原文:An A-Frame tutorial for WebVR beginners
做者:Mary
译者:大田html
A-frame是一款基于WebGL库three.js构建的WebVR框架,Web开发人员使用它能够很方便地建立虚拟现实场景。尽管three.js在建立WebGL的场景方面已经够用了,但A-frame经过引入实体-组件-系统模式的JavaScript库,比起three.js能更进一步简化VR开发。git
A-frame最大的优点在于它的扩展性很好。若是你想构建一个简单的VR场景,既能够经过HTML代码构造,也能够经过编写自定义组件和系统来构造,因此A-frame易于使用,不须要会JavaScript,只要会写HTML就行。在本教程中,咱们将学习如何构建一个冬天的场景和一个雪人,整个过程只涉及A-frame基本图形组件,不须要使用任何自定义的JavaScript代码。github
在开始以前,咱们须要先获取A-frame基础场景模板,该模板包含一个最基本的场景项目,咱们基于它构造冬天场景。如今从git上获取该模板代码,并用Node将它启动。web
$ git clone https://github.com/aframevr/aframe-boilerplate.git $ cd aframe-boilerplate && rm -rf .git && npm install $ npm start
在浏览器中访问127.0.0.1:3000,你能够看到一些形状和平面,如今咱们将基于如今这个VR场景打造冬日雪人。npm
若是你不想使用Node(若是不使用Node,将错过不少炫酷的热加载哦)开发,能够在Html中加入如下连接,引入JavaScript文件。编程
<script src="https://aframe.io/releases/0.3.0/aframe.min.js"></script>
如今index.html看起来应该是这样的:segmentfault
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Hello, World! - A-Frame</title> <meta name="description" content="Hello, World! - A-Frame"> <script src="https://aframe.io/releases/0.3.0/aframe.min.js"></script> </head> <body> <a-scene> <a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9"></a-box> <a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere> <a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder> <a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane> <a-sky color="#ECECEC"></a-sky> </a-scene> </body> </html>
制做雪人不须要使用盒子,柱面和平现,如今咱们将其移除。浏览器
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Hello, World! - A-Frame</title> <meta name="description" content="Hello, World! - A-Frame"> <script src="https://aframe.io/releases/0.3.0/aframe.min.js"></script> </head> <body> <a-scene> <a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere> <a-sky color="#ECECEC"></a-sky> </a-scene> </body> </html>
如今只有一个球漂浮在空间的中央。接下来咱们须要调整雪球的位置,大小和球面材料等属性,但首先来快速了解一下A-frame中的坐标系统。微信
要直接解释A-frame的坐标系统是什么有点难。在我看来,它是等同于Blender(一款3D动画制做软件,和3DMax相似)中的定位系统,在这个系统中有宽度,深度和高度三个概念,分别对应X轴、Y轴和Z轴。宽度对应X轴,深度对应Y轴,高度对应Z轴。框架
在A-frame中,相机的默认坐标为(0,0,0),相对于该坐标,X轴上负值就至关于画面的左边,正值就是右边;对于Z轴,负值是在画面的前面,正值是后面;对于Y轴,正值是上方,负值是下方。
例如,立方体位于(1,-1,1),即等至关于位于画面中心的右侧一个象素,水平线下方一个象素,画面日后一个象素的位置。
<a-sphere position="0 0 -15" radius="2" material="shader: standard; color: #fff; metalness: 0; roughness: 1"></a-sphere>
如今咱们从新设置了球体,将它放在咱们与中心点之间,距离中心点15象素的位置。(记住,在Z轴上,负值就是靠近咱们,正值是远离咱们。)如今的球体半径为2个象素,它将是雪人的底座,比以前的要大。
这里将color属性换成了material属性,这么作是为了给球体添加上阴影效果。shader属性定义了球体表面材质贴图的类型,它的默认值就为standard,不用设置也行,但这里为了保证代码清晰,仍旧将其写出来。
雪的颜色显然得是白色的,您能够指定color属性为white或十六进制颜色代码。metalness(金属质感)和roughness(粗糙质感)两个属性默认值为0.5,由于雪人不是金属,因此没有金属质感,这里设置metalness(金属质感)等于0;再者,雪人的表面是雪组成的,理应很粗糙,因此设置roughness(粗糙质感)等于1。
为了完成雪人的身体,咱们再复制两个球体,并调整球体位置和大小。
<a-sphere position="0 0 -15" radius="2" material="shader: standard; color: #fff; metalness: 0; roughness: 1"></a-sphere> <a-sphere position="0 2 -15" radius="1.7" material="shader: standard; color: #fff; metalness: 0; roughness: 1"></a-sphere> <a-sphere position="0 4 -15" radius="1.3" material="shader: standard; color: #fff; metalness: 0; roughness: 1"></a-sphere>
如今您的代码看起来应该是这样的(我把页面的标题和内容改为了“雪人”):
<!DOCTYPE HTML> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Snowman</title> <meta name="description" content="Snowman"> <script src="https://aframe.io/releases/0.3.0/aframe.min.js"></script> </script> </head> <body> <a-scene> <a-sphere position="0 0 -15" radius="2" material="shader: standard; color: #fff; metalness: 0; roughness: 1"></a-sphere> <a-sphere position="0 2 -15" radius="1.7" material="shader: standard; color: #fff; metalness: 0; roughness: 1"></a-sphere> <a-sphere position="0 4 -15" radius="1.3" material="shader: standard; color: #fff; metalness: 0; roughness: 1"></a-sphere> <a-sky color="#ECECEC"></a-sky> </a-scene> </body> </html>
咱们要增长两个球体来当眼睛,在雪人身体的三个球体代码后面添加如下代码。
<a-sphere position="-0.4 4.3 -13.9" radius="0.2" material="shader: standard; color: #000; metalness: 0; roughness: 1"></a-sphere> <a-sphere position="0.4 4.3 -13.9" radius="0.2" material="shader: standard; color: #000; metalness: 0; roughness: 1"></a-sphere>
球体是用来作眼睛的,这里将它的半径设置为0.2象素,设为黑色,放置在雪人的面部区域,这样眼晴就作好了。如今雪人还须要一个胡萝卜鼻子:
<a-cone position="0 4 -13.2" rotation="90 0 0" radius-bottom="0.2" radius-top="0" material="shader: standard; color: #ce6548; metalness: 0"></a-cone>
鼻子是圆锥体,可是基础形状里没有圆锥,这里咱们用一个小妙招用圆柱体来作:设置圆柱体一端半径为0.2个象素做为圆锥体的底部,另外一端半径为0象素,做为圆锥的顶端,设成橙色,放在眼睛的下方,这样鼻子就作好了。可是如今鼻子的朝向不太对,最后,咱们将它的X轴旋转90度,这样胡萝卜鼻子就能正对着咱们。
如今在你的浏览器访问127.0.0.1:3000查看VR场景,就能看到刚才完成的雪人了,只不过如今它看起来仍是漂浮在一片空白中。
天空球就是能营造出天空场景效果的球体。
接下来咱们要添加天空球,不过先别急,咱们先导入一个等距离长方圆柱投影图像资源,将其添加为背景,如今在body
标签的下方添加如下代码:
<a-assets> <img id="snowy" src="snowy.jpg"> </a-assets>
以上代码所作的是提早将资源预加载到场景中。像这样把全部的静态资源都在a-asset
标签中声明好是很好的编程习惯,虽然也能够在声明实体对象时直接加载资源,但预加载使代码组织更清晰,因此最好是预加载。
在添加新的天空球以前,先移除的旧的天空球代码:
<a-sky color="#ECECEC"></a-sky>
如今咱们来添加新的天空球,这一次再也不使用a-sky
标签,而是使用a-entity
标签,它的效果和a-sphere
标签同样。如今将如下代码添加到雪人的身体和面部下方:
<a-entity geometry="primitive: sphere; radius: 50" material="shader: flat; src: #snowy" rotation="0 40 0" position="0 0 0" scale="1 1 -1"> </a-entity>
如你所见,咱们使用的不是sphere
标签,而是a-entity
标签,因此须要设置geometry
属性。这里将a-entity
中的primitive
属性设置为sphere
,半径为50像素。
天空球的贴图材质设置为平面,这样它就不是立体图形,这样在有光照时,能避免天空中出现反射光照的效果,更天然。图像源文件设置为刚才预加载的图片资源ID(ID以#为前缀)。出于美学方面的考虑,如今设置scale
为(1,1,-1),这么作能让天空球在Y轴稍微旋转一下,这样图像的文字就能显示在天空球内部,咱们就能看到了。
设置primitive
为sky
也能够添加天空球,使用这种写能够不用设置对背景图片的缩放,比使用sphere更简单。使用这种写法时,天空球的半径默认为5000像素,若是你不须要天空球大到这种程序,注意进行适当调整。
要有光!
A-frame场景中默认就设置有光源:
<!-- Default lighting injected by A-Frame. --> <a-entity light="type: ambient; color: #BBB"></a-entity> <a-entity light="type: directional; color: #FFF; intensity: 0.6" position="-0.5 1 1"></a-entity>
这里咱们但愿阴影呈现出蓝色色调,而光应该都从背景中太阳的方向照射过来,因此我设置环境光偏蓝色调,从新调整光源的位置,增长光照的强度。
<a-entity light="type: ambient; color: #405e94"></a-entity> <a-entity light="type: directional; color: #FFF; intensity: 0.8" position="5 5 10"></a-entity>
当用VR眼镜查看画面时,雪人看起来仍是漂浮在半空中。虽然这不是最优雅的解决方案,但我用下面的配置来建立了一组平面效果做为地面,来解决这个问题:
<a-plane material="shader: flat; src: #snowy; repeat: 1 0.48" position="0 -1 0" rotation="-90 0 0" width="200" height="100"> </a-plane>
该平面使用了背景图片,可是只显示下半部分。如今雪人看来起就像是坐在地上了,虽然画面中能看出一些缝隙,不够完美,但大致上来讲仍是不错的。
最终代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Snowman</title> <meta name="description" content="Snowman"> <script src="https://aframe.io/releases/0.3.0/aframe.min.js"></script> </head> <body> <a-assets> <img id="snowy" src="snowy.jpg"> </a-assets> <a-scene> <a-sphere position="0 0 -15" radius="2" material="shader: standard; color: #fff; metalness: 0; roughness: 1"></a-sphere> <a-sphere position="0 2 -15" radius="1.7" material="shader: standard; color: #fff; metalness: 0; roughness: 1"></a-sphere> <a-sphere position="0 4 -15" radius="1.3" material="shader: standard; color: #fff; metalness: 0; roughness: 1"></a-sphere> <a-sphere position="-0.4 4.3 -13.9" radius="0.2" material="shader: standard; color: #000; metalness: 0; roughness: 1"></a-sphere> <a-sphere position="0.4 4.3 -13.9" radius="0.2" material="shader: standard; color: #000; metalness: 0; roughness: 1"></a-sphere> <a-cone position="0 4 -13.2" rotation="90 0 0" radius-bottom="0.2" radius-top="0" material="shader: standard; color: #ce6548; metalness: 0"></a-cone> <a-plane material="shader: flat; src: #snowy; repeat: 1 0.48" position="0 -1 0" rotation="-90 0 0" width="200" height="100"> </a-plane> <a-entity geometry="primitive: sphere; radius: 50" material="shader: flat; src: #snowy" rotation="0 40 0" position="0 0 0" scale="1 1 -1"> </a-entity> <a-entity light="type: ambient; color: #405e94"></a-entity> <a-entity light="type: directional; color: #FFF; intensity: 0.8" position="5 5 10"></a-entity> </a-scene> </body> </html>
在个人最终做品里还使用了一个名为aframe-particle-system-component
的自定义组件,在本教程中就不作说明了,你能够访问如下连接查看效果。
又到了插播广告的时间:)若是你喜欢个人文章,想学习更多VR知识,欢迎关注个人微信公众号:差很少一个意思(搜索微信公众号:chabuduoyigeyisi)