【webVR翻译】使用A-frame零基础一小时制做冬日雪人特效

原文:An A-Frame tutorial for WebVR beginners
做者:Mary
译者:大田html

什么是A-frame?

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基础模板

在开始以前,咱们须要先获取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轴稍微旋转一下,这样图像的文字就能显示在天空球内部,咱们就能看到了。

设置primitivesky也能够添加天空球,使用这种写能够不用设置对背景图片的缩放,比使用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教程:【WebVR教程翻译】一步一步教你如何制做A-frame动画效果


又到了插播广告的时间:)若是你喜欢个人文章,想学习更多VR知识,欢迎关注个人微信公众号:差很少一个意思(搜索微信公众号:chabuduoyigeyisi)

相关文章
相关标签/搜索