WebVR和WebGL應用程序接口使得我們已經可以在瀏覽器上創建虛擬現實(VR)體驗,但從工程化的角度而言,開發社區還需要更多方便強大的開發庫來簡化編程,Mozilla的 A-Frame 框架就是這樣一個工具,提供了一個Web開發者所熟悉的標記語言來快速構建3D VR場景動畫原型,而不需要編寫過多的JavaScript和GLSL語句。本文將介紹如何使用A-Frame構建一個簡單的在線可運行實例。你可以先看下在線演示效果。
參考文檔:A-Frame中文文檔開發指南在線教程
概覽
當前A-Frame版本是0.5.0,由於WebVR標準乃至WebGL標準都還在快速發展演進中,因此A-Frame仍然處於高度技術實驗的狀態,遠未達成商業成熟。但是對於開啓了相應設置的最新瀏覽器而言,A-Frame是可以正常工作的。它可以在桌面、移動設備(iOS和Android)、Oculus Rift, Gear VR 和 HTC Vive上運行。
A-Frame 構建在WebGL接口之上(事實上其內置了Three.js開發框架),併爲應用程序提供了一些預裝基礎組件如 - 模型、視頻播放器、天空環境、幾何模型、控制器、動畫和鼠標等。A-Frame 基於遊戲領域常用的實體組件系統(entity component system),但定位於Web開發,使用標記語言以及使用JavaScript語言來進行操作,最終達到在網頁中獲得3D虛擬現實體驗的設計目標。
搭建開發環境
我們首先需要搭建A-Frame的開發環境,這裏和以往一樣我們藉助踏得網在線開發平臺:
1. 首先要有一個現代瀏覽器,支持WebGL和WebVR,比如最新版本的Firefox(Firefox Nightly)或Chrome(v54+)。
2.(可選)設置一個VR設備如Oculus Rift、HTC Vive或者 Google Cardboard。
3. 在踏得網在線開發平臺上新建作品(從菜單中選擇新建或按快捷鍵Ctrl+M)。
4. 在左側“第三方庫”標籤欄中選擇A-Frame 0.5.0,
這將在作品中自動引入A-Frame的最新JS腳本庫。
HTML代碼結構
如果你選擇使用Sublime Text等本地編輯器來開發,那麼你首先需要創建一個空HTML文檔並引入aframe腳本庫,代碼如下:
1 2 3 4 5 6 7 8 9 10 11 | <!doctype html> < html > < head > < meta charset = "utf-8" > < title >A-Frame demo</ title > < script src = "//wow.techbrood.com/libs/aframe/aframe-v0.5.0.min.js" ></ script > </ head > < body > <!-- HTML goes here --> </ body > </ html > |
如果你使用踏得網在線開發平臺,這一步略過。
(踏得網將爲您自動生成這些重複性的模板代碼但並不顯示,您可以通過下載功能獲取到完整HTML文檔代碼)。
初始化場景
場景(scene)是所有VR內容的容器,當創建新的對象後,我們只有把這些對象加到場景中,才能真正在屏幕上被看到。在 A-Frame 中,場景通過一個 場景實體(Scene entity)元素來表達。
注意:一個實體(Entity)可以是任意元素 - 可以是盒子、圓柱、圓錐對象,也可以是一個相機(camera)、光源(light)或者聲源(sound)。
我們通過在 <body>
元素中添加一個 <a-scene>
元素來添加場景對象,即在踏得網在線開發平臺的html面板中添加如下代碼:
1 2 | < a-scene > </ a-scene > |
添加幾何模型
接着我們在 <a-scene> 元素中添加一個 <a-box> 元素,這等於是在場景中添加一個立方體:
1 | < a-box position = "-1 0.5 -3" rotation = "0 45 0" color = "#4CC3D9" ></ a-box > |
上述代碼中,該立方體對象包含一些已定義屬性:顏色(color), 位置(position)和角度(rotation)。
注意:這裏的距離數值(比如立方體的y座標位置)是無單位的,也可以是任何適用於你的場景的單位 - 毫米,米,英尺或英里 - 由你自己來定。
添加一個背景:天空盒(Sky box)
一個天空盒(skybox)是三維世界的背景,通過一個 <a-sky>
元素來表示。在這裏,我們使用一個簡單的顏色背景,但它也可以是一個圖像(image)等。環顧四周的時候可以營造一種在天空中或者木質車庫或者任何你喜歡的環境中的感覺。添加如下的標記代碼在 <a-cube>
元素之前:
1 | < a-sky color = "#DDDDDD" ></ a-sky > |
到這裏,如果你點擊菜單中的“運行”按鈕(或者按CTRL+R快捷鍵),我們將看到一個帶背景的立方體,並且可以通過鼠標(如果是通過電腦屏幕查閱該作品)操控它:
我們很容易就完成了一個VR小應用,這是因爲 A-Frame 幫我們做了很多事情:
該應用程序包含了一個缺省的光源和相機,所以我們能看到場景中的模型。
有現成可用的操作控制器:可以360°瀏覽,可以通過鍵盤上的WASD按鍵來行走。
屏幕右下角還有一個"Enter VR mode"按鈕(眼鏡形狀的圖標),可以切換到全屏模式,如果你設置好了VR設備,那麼將可以進入虛擬現實模式。
指定一個相機
相機通過 <a-camera>
元素來添加到場景中。我們可以顯式設置相機的位置,把相機放在場景中心稍退後一點的位置上,這樣我們能看清模型形狀,我們把該元素添加在場景元素的關閉標籤 </a-scene>
之前:
1 2 3 4 5 6 7 | < a-camera position = "0 1 4" cursor-visible = "true" cursor-scale = "2" cursor-color = "#0095DD" cursor-opacity = "0.5" > </ a-camera > |
上述代碼中,我們還通過 cursor-*
屬性給相機定義了遊標(cursor,缺省情況下不可見)- 我們設置了遊標的縮放因子(scale),這樣就更容易被看見,透明度設置爲0.5,這樣不會完全擋住遊標後面的物體。
添加光源
A-Frame中的基礎光源類型是平行光(directional light)和環境光(ambient light)。平行光被放在場景某處而環境光是來自該平行光的反射,這樣光線看起來比較自然。光源元素的標籤爲 <a-light>,
把下面的代碼添加到前述相機元素之後:
1 2 3 4 5 6 7 8 9 10 | < a-light type = "directional" color = "#FFF" intensity = "0.5" position = "-1 1 2" > </ a-light > < a-light type = "ambient" color = "#FFF" > </ a-light > |
這樣我們添加了一個白色平行光,光強爲0.5,位置在 (-1, 1, 2) 。環境光也是白色。
添加高級模型
前面我們通過 <a-box> 添加過立方體,但是A-Frame並不侷限於只能添加固定模型,還可以添加自定義的複雜形狀模型,這通過使用 <a-entity> 標籤來實現:
1 2 3 4 5 6 7 8 9 | < a-entity geometry=" primitive: torus; radius: 1; radiusTubular: 0.1; segmentsTubular: 12;" rotation = "10 0 0" position = "-3 1 0" > </ a-entity > |
這裏的實體其幾何模型基於一個麻花原型(torus primitive),其他的一些參數用來定製該模型的外形:torus的外邊界半徑、管道半徑和管道分段數,位置和角度的設置和前述的立方體類似。
定義材料
現在我們已經在場景中可以看到 torus 模型,但顏色看起來不太好,因爲該模型還缺少定義其表面屬性的材質(material ),我們需要創建一個材料來定義實體表面的外觀,修改上述代碼爲如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 | < a-entity geometry=" primitive: torus; radius: 1; radiusTubular: 0.1; segmentsTubular: 12;" material=" color: #EAEFF2; roughness: 0.1; metalness: 0.5;" rotation = "10 0 0" position = "-3 1 0" > </ a-entity > |
上述代碼中,我們給 entity 添加了一個新的 material 屬性,並給定了該 material 的顏色(color)、粗糙度(roughness,越粗糙的物體散射越均勻)和金屬性(metalness)。
通過JS來動態創建模型對象
我們當然可以通過JavaScript來添加物體,下面的代碼將動態創建一個圓柱體對象並加入場景中,當然JS代碼需要被放在一個<script>標籤內部:
1 2 3 4 5 6 7 | var scene = document.querySelector( 'a-scene' ); var cylinder = document.createElement( 'a-cylinder' ); cylinder.setAttribute( 'color' , '#FF9500' ); cylinder.setAttribute( 'height' , '2' ); cylinder.setAttribute( 'radius' , '0.75' ); cylinder.setAttribute( 'position' , '3 1 0' ); scene.appendChild(cylinder); |
我們首先獲取到場景對象的句柄,然後我們創建一個圓柱(a-cylinder)元素爲 A-Frame 實體。接着設置其對象屬性:顏色(color), 高度(height),半徑( radius )和 位置(position)。最後一行把新創建的圓柱添加到場景中。就這樣,現在我們已經創建了3個物體了,看起來像下面這樣:
短短几行HTML和JS代碼就完成了這樣一個三維場景,的確令人印象深刻。
動畫
我們可以通過 rotation 、position 和 scale 屬性改變對象,這樣就可以創造出動畫的視覺效果。
旋轉
我們可以通過 <a-animation>
實體來幫助我們實現元素的動畫。在 <a-box> 元素中添加 <a-animation>
子元素,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | < a-box color = "#0095DD" rotation = "20 40 0" position = "0 1 0" > < a-animation attribute = "rotation" from = "20 0 0" to = "20 360 0" direction = "alternate" dur = "4000" repeat = "indefinite" easing = "ease" > </ a-animation > </ a-box > |
與其他實體一樣,你可以定義動畫的關鍵屬性。上述代碼中我們通過改變 rotation 屬性,將讓該立方體產生旋轉動畫,從 20 0 0
到 20 360 0
, 也就是在沿着Y軸完成一個360°的旋轉。動畫方向(direction)被設置爲 alternate ,因此動畫將被正向播放然後返回。動畫持續時間(dur)爲4秒,並無限循環(repeat 爲 indefinite )。該動畫使用 ease
實現緩動效果,這通過內置的 tween.js 來實現。
縮放
我們也可以給自定義模型如 torus 來添加動畫,方法基本上類似:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | < a-entity geometry=" primitive: torus; radius: 1; radiusTubular: 0.1; segmentsTubular: 12;" material=" color: #EAEFF2; roughness: 0.1; metalness: 0.5;" rotation = "10 0 0" position = "-3 1 0" > < a-animation attribute = "scale" to = "1 0.5 1" direction = "alternate" dur = "2000" repeat = "indefinite" easing = "linear" > </ a-animation > </ a-entity > |
這裏,我們通過改變比例(scale)屬性來給torus添加縮放動畫。缺省情況下(未設置from),scale 是 1 1 1
, 我們將使其變換爲 1 0.5 1
, 也就是沿着Y軸壓縮一半。這裏的緩動效果我們使用了線性(linear)。因爲方向(direction)爲 alternate,所以在2秒內torus對象將在Y軸方向上縮小一半,然後恢復成初始狀態。同樣的,該動畫將被無限反覆。
平移
我們還可以通過 <a-animation>
來改變對象的位置,當然我們也可以通過JavaScript來實現這一點,在 <script>
標籤中添加如下代碼:
1 2 3 4 5 6 7 | var t = 0; function render() { t += 0.01; requestAnimationFrame(render); cylinder.setAttribute( 'position' , '3 ' +(Math.sin(t*2)+1)+ ' 0' ); } render(); |
這裏我們在渲染函數(render
)中更新圓柱體的位置,requestAnimationFrame函數將使得該渲染函數每幀刷新的時候被調用,這樣就形成一個圓柱體平移的視覺動畫。
到此,我們就完成了第一個A-Frame WebVR應用。
參考文檔:A-Frame入門教程