實(shí)現(xiàn)Web虛擬現(xiàn)實(shí)的最輕松方案—A-Frame框架
譯文【內(nèi)容提要】本文將向你介紹一個(gè)實(shí)現(xiàn)Web虛擬現(xiàn)實(shí)支持的最易于上手的方案—A-Frame框架。A-Frame是一款開(kāi)源的可通過(guò)定制HTML元素構(gòu)建WebVR方案的框架。有了這個(gè)框架,Web程序員無(wú)需學(xué)習(xí)一門(mén)全新的語(yǔ)言或者類似于Unity和Unreal這樣的三維引擎就可以在Web開(kāi)發(fā)中加入虛擬現(xiàn)實(shí)支持。作為一個(gè)入門(mén)教程,本文將引導(dǎo)你一步步實(shí)現(xiàn)構(gòu)建一個(gè)加入Web虛擬現(xiàn)實(shí)支持的Web頁(yè)面的全過(guò)程。
一、 何謂A-Frame
A-Frame(https://aframe.io/)是一個(gè)開(kāi)源框架,用于使用自定義的HTML元素創(chuàng)建WebVR體驗(yàn)。這些元素使用three.js(http://threejs.org/)和WebGL(https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API)在場(chǎng)景中創(chuàng)建支持虛擬現(xiàn)實(shí)的元素,而無(wú)需開(kāi)發(fā)人員僅僅為了構(gòu)建簡(jiǎn)單的體驗(yàn)而去學(xué)習(xí)例如WebGL這樣的較低級(jí)別的API。
A-Frame開(kāi)發(fā)團(tuán)隊(duì)正在努力創(chuàng)建可擴(kuò)展的虛擬現(xiàn)實(shí)Web,從而允許開(kāi)發(fā)人員構(gòu)建具有競(jìng)爭(zhēng)力的API。而且,這種思想一旦被廣泛采用和建立起來(lái),就很可能會(huì)成為某個(gè)定義的標(biāo)準(zhǔn)的一部分。這使我們今天能夠使用例如JavaScript框架和實(shí)驗(yàn)版本的瀏覽器所提供的新功能,而無(wú)需等待實(shí)現(xiàn)某種標(biāo)準(zhǔn)并等待此標(biāo)準(zhǔn)為瀏覽器所支持。
二、 設(shè)備兼容性問(wèn)題
接下來(lái),一個(gè)很重要的問(wèn)題很可能就是:A-Frame框架是否是跨瀏覽器兼容的?得到的一個(gè)出人意料的結(jié)論是:在各種平臺(tái)上,只要是WebGL兼容的瀏覽器,A-Frame體驗(yàn)效果良好;當(dāng)然在沒(méi)有VR支持的情況下3D場(chǎng)景仍然看見(jiàn)。這意味著,Chrome、 Firefox、Edge和Opera這些流行的瀏覽器都能夠顯示桌面級(jí)的交互式3D體驗(yàn)。要想進(jìn)行虛擬現(xiàn)實(shí)體驗(yàn),需要把一部例如Oculus Rift這樣的設(shè)備連接到一些支持WebVR技術(shù)的瀏覽器上,從而實(shí)現(xiàn)虛擬現(xiàn)實(shí)兼容性(請(qǐng)繼續(xù)看下文內(nèi)容)。
在智能手機(jī)方面,過(guò)去兩代的運(yùn)行iOS和安卓系統(tǒng)的現(xiàn)代智能手機(jī)是最適合的 (例如iPhone 6+、三星Galaxy S6+,還有我個(gè)人的 HTC One M9效果都很好)。這其中的大多數(shù)智能手機(jī)在插入Google Cardboard耳機(jī)時(shí)也支持虛擬現(xiàn)實(shí)。所以,相比與讓虛擬現(xiàn)實(shí)工作在您的桌面機(jī)環(huán)境而言,VR兼容性方面在智能手機(jī)上實(shí)際上更易于實(shí)現(xiàn)與管理。
三、 準(zhǔn)備工作
要按本文指導(dǎo)完成基于A-Frame的試驗(yàn),你需要作如下準(zhǔn)備工作:
l 要實(shí)現(xiàn)一個(gè)基本類型的非VR體驗(yàn):
n 你需要安裝一款如上所述的支持WebGL的瀏覽器。
l 要實(shí)現(xiàn)一個(gè)基于桌面的VR體驗(yàn):
n 你需要安裝一款支持WebGL的瀏覽器,例如最新的Chromium WebVR版本(https://drive.google.com/folderview?id=0BzudLt22BqGRbW9WTHMtOWMzNjQ)或者Firefox的Nightly版本(https://nightly.mozilla.org/)。
n 一款Oculus Rift耳機(jī)(也可能是HTC Vive,只是我還沒(méi)有進(jìn)行過(guò)實(shí)際測(cè)試)。
l 要實(shí)現(xiàn)基于移動(dòng)設(shè)備的VR體驗(yàn),則需要如下:
n 最新款式的智能設(shè)備一般都能夠至少實(shí)現(xiàn)場(chǎng)景顯示并允許你在一個(gè)半虛擬現(xiàn)實(shí)視圖中四處觀看。
n 一款谷歌的Cardboard或者Gear VR耳機(jī)。
四、 開(kāi)始工作
首先,請(qǐng)打開(kāi)A-Frame框架的入門(mén)級(jí)教程頁(yè)面(https://aframe.io/docs/guide/getting-started.html)。目前,A-Frame團(tuán)隊(duì)已經(jīng)提供了各種選項(xiàng)以方便進(jìn)行與A-Frame框架有關(guān)的各種試驗(yàn),這包括CodePen代碼片段、一個(gè)npm構(gòu)建版本、一個(gè)A-Frame框架的JS文件(可直接下載或通過(guò)CDN取得),一個(gè)HTML模板和一個(gè)本地開(kāi)發(fā)服務(wù)器。為了使事情盡可能簡(jiǎn)單,我們將下載并直接使用A-Frame樣板(https://github.com/aframevr/aframe-boilerplate/archive/master.zip)進(jìn)行工作。
把上述模板解壓到你的系統(tǒng)中你的Web項(xiàng)目所在位置。這個(gè)模板不必一定要運(yùn)行于本地Web服務(wù)器上。模板使用來(lái)自于CDN的A-Frame框架,因此我們只需主要關(guān)注index.html文件即可。配置文件package.json中提供了一個(gè)基于npm的本地Web服務(wù)器用于測(cè)試目的。在本文中,我們將使用這個(gè)服務(wù)器——然而,現(xiàn)在不必測(cè)試它。
五、 啟動(dòng)本地服務(wù)器
如上文所述,A-Frame樣板帶有它自己準(zhǔn)備使用的本地Web服務(wù)器。雖然這并不總是測(cè)試你的A-Frame框架的必要情形,但是這樣做卻是一個(gè)良好的實(shí)踐并能夠減少通過(guò)您的計(jì)算機(jī)上文件系統(tǒng)運(yùn)行網(wǎng)頁(yè)時(shí)出現(xiàn)的各種跨同源策略問(wèn)題所帶來(lái)的困惑。
為了運(yùn)行本地Web服務(wù)器,請(qǐng)從你的終端/命令提示符下切換到你的模板項(xiàng)目文件夾中,然后運(yùn)行下面的命令︰
npm install && npm start
這將安裝Web服務(wù)器必需的所有文件,然后運(yùn)行它。之后,如果你想要再次運(yùn)行服務(wù)器,只需運(yùn)行命令“npm start”。
一旦運(yùn)行本地Web服務(wù)器,它應(yīng)會(huì)自動(dòng)打開(kāi)我們的web瀏覽器并加載我們的模板網(wǎng)頁(yè)文件。模板中加入了LiveReload支持——這意味著,無(wú)論何時(shí)更改頁(yè)面其內(nèi)容都會(huì)自動(dòng)刷新。
如果你需要在不同的設(shè)備上打開(kāi)網(wǎng)頁(yè),或者在運(yùn)行本地Web服務(wù)器后網(wǎng)頁(yè)不會(huì)自動(dòng)打開(kāi),您可以通過(guò)在你的瀏覽器輸入http://localhost:3000或者http://192.168.0.1:3000。注意,這里的IP地址正對(duì)應(yīng)于你的計(jì)算機(jī)的IP地址。
你應(yīng)該會(huì)看到初始場(chǎng)景看起來(lái)像下圖所示的樣子︰
六、 構(gòu)建新場(chǎng)景
現(xiàn)在,讓我們刪除模板代碼并去掉<body>標(biāo)記內(nèi)的所有內(nèi)容,僅留下<a-scene>部分。我們所有的A-Frame元素都將放于這個(gè)<a-scene>組件內(nèi)部。目前代碼如下所示:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Our First A-Frame Experience</title>
<script src="https://aframe.io/releases/0.2.0/aframe.min.js"></script>
</head>
<body>
<a-scene>
</a-scene>
</body>
</html>
A-Frame提供了一組原型,這些原型提供給我們VR場(chǎng)景中常用的元素。
接下來(lái),讓我們添加一些元素來(lái)搭建一個(gè)定制場(chǎng)景。
七、 創(chuàng)建天空
每一個(gè)場(chǎng)景都需要一個(gè)天空部分(或者是某種類型的背景)。這或者是一個(gè)單色圖像或者是一幅全景圖像。這部分內(nèi)容的原型是<a-sky>。
使用單色圖像實(shí)現(xiàn)的天空部分的代碼如下所示:
這將為我們的目標(biāo)場(chǎng)景創(chuàng)建一個(gè)可愛(ài)的自然明亮的紫紅色天空效果,如下圖所示:
猶如輝煌的天空效果一樣,使用一幅360度全景圖像將看起來(lái)更漂亮。找到這樣的天空盒圖像的一個(gè)很好的去處是Flickr網(wǎng)站。此網(wǎng)站上提供了不少的全景圖像供大家自由重用。
我在Flickr上發(fā)現(xiàn)了Luca Biada(https://flic.kr/p/bCMJ4X)提供的如下一幅圖像:
當(dāng)我們使用如下代碼把它置于我們的場(chǎng)景中時(shí):
我們可以得到該場(chǎng)景的一個(gè)如下圖所示的360度全景圖:
八、 加入一個(gè)長(zhǎng)方體
現(xiàn)在,我們有了一個(gè)場(chǎng)景。接下來(lái),讓我們?yōu)樗砑右恍┰?。這要使用<a-box>原型,我們可以將一些長(zhǎng)方體和立方體放到我們的場(chǎng)景中。下面的代碼將把一個(gè)橙色的長(zhǎng)方體添加到我們的場(chǎng)景內(nèi)的道路上:
<a-box color="#B76705" depth="2" height="2" width="4" position="0 0 -1.25"></a-box>
代碼中的color屬性與前面我們的天空盒中的color屬性作用相同,用于指定我們的長(zhǎng)方體元素的材質(zhì)顏色。然后,通過(guò)屬性depth,height和width指定形狀。我們的長(zhǎng)方體尺寸是2 x 2 x 4,樣子像個(gè)很寬的盒子,隱隱約約看起來(lái)像個(gè)放到路上的紙車(chē)。要想把盒子放到場(chǎng)景中的不同位置,只需要修改一個(gè)它的position屬性即可。這個(gè)屬性使用了三個(gè)值,分別對(duì)應(yīng)于三個(gè)坐標(biāo)軸:x軸、y軸和z軸。
通過(guò)上述代碼創(chuàng)建的長(zhǎng)方體,在我們的場(chǎng)景中看起來(lái)有如下圖所示的效果:
九、 加入幾個(gè)圓柱體
現(xiàn)在,我們將使用<a-cylinder>原型把幾個(gè)柱子添加到場(chǎng)景的街道中:
<a-cylinder color="#1E130E" height="40" radius="0.5" position="-40 0 -8"></a-cylinder>
顏色和位置屬性以與上面我們創(chuàng)建的長(zhǎng)方體含義一致;但是,這里還添加了兩個(gè)新屬性——height和radius,這兩個(gè)屬性分別用于設(shè)置圓柱的高度與半徑。下圖給出的是我們添加了新柱子后的場(chǎng)景圖。
于是,我們可以非常容易地?cái)U(kuò)展上述想法。這只需要使用下面的代碼就可以添加一排柱子:
<a-cylinder color="#1E130E" height="40" radius="0.5" position="-40 0 -8"></a-cylinder>
<a-cylinder color="#1E130E" height="40" radius="0.5" position="-10 0 -8"></a-cylinder>
<a-cylinder color="#1E130E" height="40" radius="0.5" position="20 0 -8"></a-cylinder>
<a-cylinder color="#1E130E" height="40" radius="0.5" position="50 0 -7"></a-cylinder>
運(yùn)行結(jié)果如下圖所示:
在A-Frame框架中,圓柱體(Cylinders)還有其他許多選項(xiàng)可用,讀者可以自己查閱Cylinder參考文檔(https://aframe.io/docs/primitives/a-cylinder.html)。
十、 再加入一個(gè)球體
現(xiàn)在,我們?cè)僭?D場(chǎng)景中添加一個(gè)球體。這可以通過(guò)使用<a-sphere>原型來(lái)實(shí)現(xiàn),像下面這樣:
<a-sphere color="#000000" radius="2" position="0 15 20"></a-sphere>
這段代碼直截了當(dāng),它創(chuàng)建了一個(gè)令人有點(diǎn)毛骨悚然的黑色球體,漂浮在我們身后的天空中:
十一、 添加材質(zhì)
我們可以通過(guò)<a-assets>標(biāo)記將紋理添加到我們的長(zhǎng)方體、圓柱和球等原型上。這需要搭建一個(gè)A-Frame資源管理系統(tǒng),使我們能夠定義資源,然后把它們應(yīng)用于我們的形狀之上。這是推薦的把紋理添加到場(chǎng)景的方法。
我下載并稍微修改了網(wǎng)址http://subtlepatterns.com/dark-sharp-edges/提供的一幅圖像作為紋理使用。然后,我們可以通過(guò)如下方式將該資源添加到我們剛剛創(chuàng)建的場(chǎng)景中:
上述代碼中的Id屬性給出了引用紋理并把紋理應(yīng)用于場(chǎng)景中的對(duì)象上時(shí)的名稱。src屬性告訴A-Frame我們想使用的圖像文件名稱。為了給場(chǎng)景中的對(duì)象指定材質(zhì),我們可以把材質(zhì)通過(guò)對(duì)象的src屬性指定——在紋理的ID前面使用哈希技術(shù),請(qǐng)參考下面代碼:
<a-sphere src="#darktexture" radius="2" position="0 15 20"></a-sphere>
通過(guò)上面的代碼,將在天空中創(chuàng)建一個(gè)隨機(jī)的、陰森森的球體,從效果上看將是一個(gè)更好看的、接近于科幻效果的紋理。請(qǐng)參考下面的效果圖。
十二、 運(yùn)行效果展示
要想實(shí)際在VR中觀看上述體驗(yàn),那么你要么需要把一個(gè)Oculus Rift連接到你的PC上,或者需要一部時(shí)髦的智能手機(jī)!當(dāng)然,智能手機(jī)是最容易的選擇。如果你沒(méi)有VR耳機(jī),那么當(dāng)你走到你的智能手機(jī)上顯示的場(chǎng)景中時(shí)你仍然能夠看到上面實(shí)現(xiàn)的一切。此時(shí),你可以搖動(dòng)你的手機(jī)四處走走;請(qǐng)參考下圖。
如果你有一個(gè)與你的手機(jī)一起使用的Google Cardboard耳機(jī),你可以點(diǎn)擊右下角的VR圖標(biāo)切換到VR視圖下,請(qǐng)參考下圖。
十三、 VR體驗(yàn)
好了,如果你想在上面的A-Frame大街示例中走上一走,那么,很好。你可以從這里點(diǎn)擊A-Frame大街示例(https://www.devdiner.com/demos/aframedemo/)去體驗(yàn)一把吧。
十四、 小結(jié)
今天,當(dāng)我們提到WebVR時(shí),A-Frame無(wú)疑是一個(gè)簡(jiǎn)單而易于使用的框架。通過(guò)此框架,我們可以實(shí)現(xiàn)很多基于跨瀏覽器兼容的VR體驗(yàn)。其實(shí),我們可以使用A-Frame實(shí)現(xiàn)更多的功能。在以后的文章中我將繼續(xù)介紹這些問(wèn)題。謝謝閱讀!