基于Primrose和WebVR搭建虛擬現(xiàn)實(shí)方案
譯文【51CTO.com快譯】2016年一開始,虛擬現(xiàn)實(shí)應(yīng)用就進(jìn)展得熱火朝天,到處都在銷售VR耳機(jī)這一事實(shí)就足夠證明這一點(diǎn)。如今,虛擬現(xiàn)實(shí)技術(shù)發(fā)展已引起平臺(tái)開發(fā)商們?cè)絹?lái)越多的關(guān)注,因?yàn)檫@些技術(shù)正迎合這些狂熱的開發(fā)商們的口味。其中,Unity和Unreal引擎帶給人們最激動(dòng)人心的功能之一便是支持開發(fā)人員在虛擬現(xiàn)實(shí)中即時(shí)地編輯虛擬現(xiàn)實(shí)場(chǎng)景。令WebVR和JavaScript程序員興奮的是,如今已經(jīng)出現(xiàn)了一款支持WebVR原型化開發(fā)及有關(guān)實(shí)驗(yàn)的新框架——Primrose。
一、 何謂Primrose
何謂Primrose?其官方網(wǎng)站(http://www.primrosevr.com/)描述如下:
Primrose是一個(gè)跨瀏覽器、支持多種設(shè)備并且支持在WebVR應(yīng)用程序中開發(fā)生產(chǎn)工具類應(yīng)用的軟件開發(fā)框架。
Primrose為開發(fā)人員提供了一種很好的框架,使其可以在他們的瀏覽器中打開應(yīng)用程序、試驗(yàn)新的想法和探索在VR場(chǎng)景中的外觀模樣。它是一個(gè)開源框架,目前還很新穎,但在迅速發(fā)展中。
二、 準(zhǔn)備工作
如果你想使用Primrose進(jìn)行WebVR相關(guān)的試驗(yàn),那么你需要作如下準(zhǔn)備工作:
l 一個(gè)支持WebGL的瀏覽器,***是支持WebVR功能,例如***的Chromium WebVR版本或者Firefox Nightly。
l 一部Oculus Rift耳機(jī)(也可以是HTC Vive)或者Google Cardboard;然而,你也可以在沒(méi)有耳機(jī)的情況下在瀏覽器中進(jìn)行試驗(yàn)!
l 某種Web服務(wù)器——一個(gè)本地服務(wù)器即可,例如WAMP、MAMP、靜態(tài)Node服務(wù)器、靜態(tài)Python服務(wù)器,等等,都能勝任。
l 能夠觸摸式輸入——在虛擬現(xiàn)實(shí)環(huán)境中你不必看到你的鍵盤。
三、 開始工作
你可以在Primrose的官方網(wǎng)站(http://www.primrosevr.com/examples/editor3d/index.html)嘗試一個(gè)完全可工作版本的實(shí)時(shí)編碼操作(前提是:一定要使用一個(gè)支持WebGL功能的瀏覽器打開這個(gè)站點(diǎn)。例如,使用就像上文提到的那些瀏覽器即可;否則,你只會(huì)看到一個(gè)靜態(tài)的屏幕截圖)。
當(dāng)然,如果你想自己在本地運(yùn)行程序的副本,你可以從Primrose GitHub倉(cāng)庫(kù)(https://github.com/capnmidnight/Primrose/archive/master.zip)中下載/克隆其實(shí)例的***版本。
四、 基于GitHub網(wǎng)站的簡(jiǎn)化版本
在本文中,我提供了一個(gè)簡(jiǎn)化版本的現(xiàn)場(chǎng)編碼的展示實(shí)例。此實(shí)例中使用了與Primrose示例一樣的代碼,只是為了易于說(shuō)明起見(jiàn)減少了一些功能。為了與本文論述觀點(diǎn)保持一致,你可以打開網(wǎng)址https://github.com/sitepoint-editors/Primrose-Simplified-Editor找到GitHub上的那個(gè)版本。
五、 運(yùn)行本地服務(wù)器
要運(yùn)行我們的簡(jiǎn)化版本的現(xiàn)場(chǎng)編碼實(shí)例,你只需把它復(fù)制到你的本地服務(wù)器上,然后在你的支持WebGL的瀏覽器中打開該位置。(例如http://localhost/primrose甚至只有http://localhost,如果你把它放到你的服務(wù)器的根目錄下的話)
注意:這將不會(huì)從你的文件系統(tǒng)運(yùn)行!如果你想從一個(gè)例如file:///Users/yourname/primrose/index.html這樣的位置運(yùn)行它,程序?qū)⒈罎ⅲ灰驗(yàn)闉g覽器不會(huì)給予JavaScript權(quán)限去訪問(wèn)有關(guān)紋理文件。
上述程序啟動(dòng)后,你將能夠看到如下圖所示的樣子:
如果你在這個(gè)場(chǎng)景中環(huán)顧一下四周,你將看到一個(gè)立即可用的代碼編輯器。你可以把你的光標(biāo)指向代碼行,在代碼處點(diǎn)擊一下光標(biāo),然后就像你使用常規(guī)文本編輯器鍵入內(nèi)容一樣輸入內(nèi)容。例如,如果我們正好在for循環(huán)語(yǔ)句(for (var i = 0; i < 10; i++))中的10后點(diǎn)擊一下,然后把語(yǔ)句修改為for (var i = 0; i < 100; i++),像下圖中箭頭所指的樣子:
那么,你會(huì)注意到我們的場(chǎng)景也會(huì)實(shí)時(shí)地改變——由這個(gè)for循環(huán)創(chuàng)建的100個(gè)長(zhǎng)方體塊在場(chǎng)景中隨機(jī)移動(dòng)!
如果你想從不同的角度更好地看看它,你可以看看地板并點(diǎn)擊你想要移動(dòng)到哪里:
你還可以使用鍵盤上的箭頭鍵在上述場(chǎng)景中來(lái)回走動(dòng)。
六、 工作原理
大多數(shù)情況下,你不需要重新編譯構(gòu)建Primrose官方提供的現(xiàn)場(chǎng)編輯器實(shí)例,而只需要簡(jiǎn)單地從GitHub網(wǎng)站上把這些代碼復(fù)制到你自己的場(chǎng)景中即可。但是,在本文中,我想我已經(jīng)提供給您探索Primrose框架應(yīng)用有關(guān)概念的一些簡(jiǎn)化版本實(shí)例。
接下來(lái),請(qǐng)看一下我們的Primrose應(yīng)用程序的開頭部分,如下面代碼所示:
上面代碼定義了三個(gè)紋理文件,然后實(shí)例化我們的Primrose程序,并把其實(shí)例賦值給變量app。其中的Primrose.BrowserEnvironment()方法負(fù)責(zé)使用給定的天空盒與場(chǎng)地紋理搭建起我們的場(chǎng)景。
另外,我們還要使用一個(gè)變量editorFrame,它負(fù)責(zé)為我們的編輯器構(gòu)建2048 X 2048大小的場(chǎng)景:
另外,所有Primrose程序的都會(huì)有的一些功能包括:使用語(yǔ)句addEventListener("ready", function() {});初始化我們的元素,等等。例如,我們添加如下內(nèi)容:
l subScene:可以在我們的現(xiàn)場(chǎng)編輯器中添加或者更改元素。
l editor:我們場(chǎng)景中的現(xiàn)場(chǎng)編輯器(稍后我們會(huì)更詳細(xì)地討論)。
l getSourceCode():在此初始化代碼。在我們的簡(jiǎn)化版本程序中,它負(fù)責(zé)檢索Primrose編輯器中提供的代碼片斷并把這些代碼顯示于我們自己的VR文本編輯器中。當(dāng)然,在更復(fù)雜的編輯器中,可以借助于本地存儲(chǔ)實(shí)現(xiàn)更多的功能。
Primrose最近又發(fā)行了一個(gè)新的版本。在該版本中,通過(guò)在Primrose.Text中引入一些新的框架對(duì)象進(jìn)一步改造了編輯器。具體包括如下一些方面:
l Primrose.Text.Controls.TextBox:負(fù)責(zé)構(gòu)建一個(gè)文本區(qū)域并提供一些默認(rèn)功能。
l Primrose.Text.Rectangle:它允許我們?yōu)槲谋緟^(qū)域定義一個(gè)顯示內(nèi)容的長(zhǎng)方形邊界。在前面代碼中我們定義editorFrame時(shí)你可能已經(jīng)注意到。
l Primrose.Text.Grammars.JavaScript:用于記號(hào)鍵內(nèi)設(shè)置JavaScript代碼高亮顯示功能。你可以通過(guò)調(diào)用Primrose.Text.Grammars.PlainText實(shí)現(xiàn)純文本的高亮顯示。
在編寫Primrose應(yīng)用程序時(shí),除了已有的“ready”事件外,還有幾個(gè)事件需要引起你的關(guān)注,包括:
l "update"事件:這是我們的示例編輯器代碼中唯一使用的另一個(gè)事件。它負(fù)責(zé)運(yùn)行每一幀。你可以在Primrose程序中使用它來(lái)運(yùn)行動(dòng)畫并檢查場(chǎng)景內(nèi)的有關(guān)更新操作。
l "keydown","keyup"和"keypress"事件:當(dāng)按下鍵、松開鍵時(shí)使用這些事件。
l "mousedown"和"mouseup"事件:同上,只是與鼠標(biāo)有關(guān)。
l "mousemove"事件:檢測(cè)鼠標(biāo)移動(dòng)。
l "wheel"事件:檢測(cè)用戶移動(dòng)鼠標(biāo)滾輪時(shí)使用。
l "touchstart","touchend"和"touchmove"事件:當(dāng)手指通過(guò)觸屏按下場(chǎng)景中的某一個(gè)元素時(shí)、抬起手指時(shí)和在屏幕上滑動(dòng)時(shí)檢測(cè)這些事件。
l "unload"事件:當(dāng)程序即將關(guān)閉時(shí)觸發(fā)此事件。但是,我提供的簡(jiǎn)化版本的編輯器中并沒(méi)有實(shí)現(xiàn)此功能;而完整版本的Primrose編輯器使用這一事件實(shí)現(xiàn)把編輯器中內(nèi)容保存到本地存儲(chǔ)中。
l "load"事件:當(dāng)程序再次加載時(shí)啟用此事件。
l "pointerstart","pointerend"和"pointermove"事件:相應(yīng)于場(chǎng)景中對(duì)象的點(diǎn)擊和觸摸操作。
l "gazestart"事件:當(dāng)用戶觀看場(chǎng)景中某對(duì)象的瞬間觸發(fā)此事件。
l "gazecomplete"事件:當(dāng)用戶觀看場(chǎng)景中某對(duì)象有默認(rèn)的一秒鐘時(shí)觸發(fā)此事件。
l "gazecancel"事件:當(dāng)用戶觀看場(chǎng)景中某對(duì)象不足默認(rèn)的一秒鐘時(shí)觸發(fā)此事件。當(dāng)然,你可以通過(guò)修改gazeLength屬性值來(lái)修改默認(rèn)的一秒鐘時(shí)間,只是這已經(jīng)不在本文討論范圍之內(nèi)。
各位請(qǐng)注意:篇幅所限,在本文中我不會(huì)展示更多的代碼,有興趣的朋友可以自行參考前面提供的GitHub倉(cāng)庫(kù)地址處。但是,我們還是要簡(jiǎn)要了解一下上面的某些事件的響應(yīng)及實(shí)現(xiàn)的功能,等等。
在我提供的簡(jiǎn)化版本程序中的update事件中,它負(fù)責(zé)檢查編輯器中的任何代碼更改,并且在每一個(gè)scriptUpdateTimeout調(diào)用(每隔半秒觸發(fā)一次)時(shí)更新它們,并負(fù)責(zé)運(yùn)行它所知道的任何動(dòng)畫。
在keydown事件中,它負(fù)責(zé)清除scriptUpdateTimeout調(diào)用,當(dāng)程序試圖更新內(nèi)容時(shí)它會(huì)延遲一些時(shí)間。
每一次scriptUpdateTimeout執(zhí)行結(jié)束時(shí)都會(huì)運(yùn)行UpdateScript()函數(shù)。當(dāng)我們編輯器中的腳本更改并且替換正在運(yùn)行的腳本時(shí),而且剛好此時(shí)它發(fā)覺(jué)到有一次更新時(shí)它就做這樣的檢查工作。它會(huì)清除我們上面的subScene調(diào)用,并根據(jù)我們的VR編輯器中的代碼立即更改有關(guān)元素。
七、 創(chuàng)建按鈕功能
為了能正確、身臨其境地體驗(yàn)實(shí)時(shí)編碼(或其他任何你所創(chuàng)建的具備Primrose支持功能的應(yīng)用程序),我們希望在全屏幕下展示。這是必不可少的VR要求,因?yàn)樵谌魏纹渌绞较滤疾粫?huì)工作!為此,我們要添加按鈕來(lái)觸發(fā)這些模式。Primrose已提供了這其中的大部分直接支持。我們只需添加一個(gè)id為goVR的按鈕和另一個(gè)id為goRegular的按鈕,然后調(diào)用app.setFullScreenButton函數(shù)——把ID名稱作***個(gè)參數(shù)傳遞進(jìn)去,還有一個(gè)click事件參數(shù),***一個(gè)參數(shù)要么為true要么為false(用于指定VR常用的全屏模式)。請(qǐng)參考如下代碼:
八、 使用Primrose
目前,我們已經(jīng)作了一定的準(zhǔn)備工作,并了解了如何通過(guò)調(diào)整代碼實(shí)時(shí)地改變場(chǎng)景中的內(nèi)容。但是,在Primrose程序中,我們能夠構(gòu)建哪些內(nèi)容呢?接下來(lái),將介紹一些你經(jīng)常加入的元素;你可以在app.js程序中通過(guò)testDemo()函數(shù)添加,或者在你的實(shí)時(shí)VR場(chǎng)景中添加。
(一) 使用軸(Axis)
軸的作用是提供紅、綠、藍(lán)共三個(gè)條塊,分別用于負(fù)責(zé)指示x軸、y軸和z軸三個(gè)方向。其調(diào)用方式是axis(length, width),請(qǐng)參考如下代碼:
這段代碼調(diào)用將生成如下圖所示的效果:
(二) 使用點(diǎn)云(Point Cloud)
可以通過(guò)調(diào)用函數(shù)cloud(verts, color, size)來(lái)通過(guò)使用許多小方點(diǎn)生成點(diǎn)云。注意,其中的變量verts是一個(gè)頂點(diǎn)數(shù)組。使用點(diǎn)云的一個(gè)例子如下所示:
在上面的代碼中,MIDX,MIDY和MIDZ是在我們的示例代碼中已經(jīng)定義好的變量。這段代碼指定了我們場(chǎng)景中的一個(gè)焦點(diǎn)。你可以把任意值賦給這些變量。
上面的代碼將在我們的場(chǎng)景中生成如下圖所示的效果:
(三) 使用Hub
在我上面提供的示例中你需要注意的一點(diǎn)是我們添加了一個(gè)叫start的東西。實(shí)際上,這是一個(gè)hub()函數(shù)——在我們的場(chǎng)景中是一個(gè)特別的入口點(diǎn)——我們可以在其中把其他對(duì)象分組。我們的hub()函數(shù)使用如下代碼定義:
(四) 添加燈光效果
可以通過(guò)調(diào)用函數(shù)light(color, [intensity, [distance, [decay]]])來(lái)創(chuàng)建燈光效果。我們的場(chǎng)景中的默認(rèn)的燈光是白光的,如下面代碼所示:
(五) 添加一個(gè)長(zhǎng)方體
本小節(jié)中將要添加的長(zhǎng)方體以及接下來(lái)將添加的其他對(duì)象在我們的場(chǎng)景中呈現(xiàn)前都要求使用紋理。這些內(nèi)容包含在一個(gè)叫textured()的函數(shù)內(nèi);此函數(shù)中通過(guò)指定圖像文件名來(lái)指定紋理數(shù)據(jù)。創(chuàng)建長(zhǎng)方體的函數(shù)調(diào)用格式類似于:box(width, height, length)。請(qǐng)參考如下代碼:
通過(guò)上面的函數(shù)調(diào)用將會(huì)在我們的場(chǎng)景中創(chuàng)建一個(gè)Three.js中的BoxGeometry對(duì)象(http://threejs.org/docs/#Reference/Extras.Geometries/BoxGeometry)。
(六) 添加圓柱體
我們可以通過(guò)如下調(diào)用在場(chǎng)景中添加圓柱體:
通過(guò)上面的函數(shù)調(diào)用將會(huì)創(chuàng)建一個(gè)Three.js中的CylinderGeometry對(duì)象(http://threejs.org/docs/#Reference/Extras.Geometries/CylinderGeometry)。例如,下面創(chuàng)建的圓柱體,其頂部與底部的半徑均為1,高度為5,半徑/高度片斷數(shù)(segments)為40:
上面創(chuàng)建的圓柱體在場(chǎng)景中看起來(lái)將有如下圖所示的效果:
(七) 其他
其實(shí),在Primrose文檔的“Scripting Functions”這一部分中你會(huì)發(fā)現(xiàn)大量的其他內(nèi)容,包括quad()函數(shù)、shell()函數(shù)和sphere()函數(shù),等等。請(qǐng)各位盡情地探討和試驗(yàn)吧!
九、 小結(jié)
Primrose是一個(gè)功能非常強(qiáng)大的WebVR框架,不久后肯定會(huì)在構(gòu)建Web虛擬現(xiàn)實(shí)應(yīng)用方面發(fā)揮巨大作用。盡管WebVR技術(shù)及Primrose框架尚處于發(fā)展的早期,但是虛擬現(xiàn)實(shí)技術(shù)在Web領(lǐng)域的應(yīng)用乃大勢(shì)所趨;因此,無(wú)論是Primrose還是WebVR一段時(shí)間后必將強(qiáng)大與成熟起來(lái)。
【51CTO譯稿,合作站點(diǎn)轉(zhuǎn)載請(qǐng)注明原文譯者和出處為51CTO.com】