WebVR和WebGL應用程序接口使得咱們已經能夠在瀏覽器上建立虛擬現實(VR)體驗,但從工程化的角度而言,開發社區還須要更多方便強大的開發庫來簡化編程,Mozilla的 A-Frame 框架就是這樣一個工具,提供了一個Web開發者所熟悉的標記語言來快速構建3D VR場景動畫原型,而不須要編寫過多的JavaScript和GLSL語句。本文將介紹如何使用A-Frame構建一個簡單的在線可運行實例。你能夠先看下在線演示效果。javascript
當前A-Frame版本是0.5.0,因爲WebVR標準乃至WebGL標準都還在快速發展演進中,所以A-Frame仍然處於高度技術實驗的狀態,遠未達成商業成熟。可是對於開啓了相應設置的最新瀏覽器而言,A-Frame是能夠正常工做的。它能夠在桌面、移動設備(iOS和Android)、Oculus Rift, Gear VR 和 HTC Vive上運行。html
A-Frame 構建在WebGL接口之上(事實上其內置了Three.js開發框架),併爲應用程序提供了一些預裝基礎組件如 - 模型、視頻播放器、天空環境、幾何模型、控制器、動畫和鼠標等。A-Frame 基於遊戲領域經常使用的實體組件系統(entity component system),但定位於Web開發,使用標記語言以及使用javascript語言來進行操做,最終達到在網頁中得到3D虛擬現實體驗的設計目標。java
咱們首先須要搭建A-Frame的開發環境,這裏和以往同樣咱們藉助踏得網在線開發平臺:android
1. 首先要有一個現代瀏覽器,支持WebGL和WebVR,好比最新版本的Firefox(Firefox Nightly)或Chrome(v54+)。ios
2.(可選)設置一個VR設備如Oculus Rift、HTC Vive或者 Google Cardboard。git
3. 在踏得網在線開發平臺上新建做品(從菜單中選擇新建或按快捷鍵Ctrl+M)。github
4. 在左側「第三方庫」標籤欄中選擇A-Frame 0.5.0,web
這將在做品中自動引入A-Frame的最新js腳本庫。編程
若是你選擇使用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
>
|
場景(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座標位置)是無單位的,也能夠是任何適用於你的場景的單位 - 毫米,米,英尺或英里 - 由你本身來定。
一個天空盒(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)。
咱們固然能夠經過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秒內toru對象將在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應用。