建筑虚拟现实应用程序从来都不容易。结合网络的力量和可达性与你WebVR。

2017-10-06 19:31


今天,我们将运行通过一个简短的教程,创造我们自己的网络应用A架反应。我们将安装过程,建立了一个基本的三维场景,并添加交互性和动画。A有一个优秀的第三方组件注册,所以我们会用一些除了写一个从无到有。最后,我们将通过部署过程surge.sh所以,你可以与全世界分享你的应用程序和测试它活在你的智能手机(谷歌或纸板的如果你有一个可用的)。供参考,最终的代码是本次回购。在本教程中,我们将建立一个这样的场景。检查了现场演示也.

A-Frame Eventide Demo

令人兴奋的,对吗?事不宜迟,让我们开始吧!

A是什么?

A-Frame Banner

A是一个网络上构建丰富的立体框架。它是建立在顶部阅读Three js,先进的三维的JavaScript库,使WebGL非常有趣的工作。最酷的部分是,A让你不写一行JavaScript构建网络应用程序(一定程度上)。你可以在几分钟的写作只是一个基本的场景几行HTML。它提供了一个极好的HTML API你脚手架的场景,同时还给予你充分的灵活性,让你访问API的权力,它丰富的阅读Three js。在我看来,一个良好的平衡的抽象框架发生这样。这个文档是一个学习更多关于它的细节的好地方。

安装程序

我们要做的第一件事是建立框架和反应。我已经提前为你做了这些,所以你可以简单地克隆本次回购cd进入它,并运行线安装把所有需要的依赖。对于这个程序,我们将会使用超前,一个快速、轻量级的替代反应,为了减少我们的束径。别担心,它仍然是相同的API,所以如果你已经与之前反应那么你不应该注意到任何差异。继续运行yarn start启动开发服务器。击中了http://localhost:3333你应该提出一个基本场景包括一个旋转的立方体和一些文字。我强烈建议你花一些时间去通过回购的自述。这有一些关于A的基本信息和反应。它也更为详细的什么和如何安装的一切。现在到有趣的东西。

A-Frame Setup

积木

火在项目的根目录,编辑和检查文件app/main.js(或看GitHub),这就是我们要建立我们的场景。让我们花一秒钟分解这。

这个Scene组件是一个框架的应用程序的根节点。这是什么创造的阶段你将3D物体,初始化摄像头,WebGL渲染和处理其他样板。它应该是最外层的元素包装一切里面。你能想到的实体如HTMLdiv。实体是一个框架的基本构建块场景。在现场的每一个对象都是一个三角支架Entity

框架是建立在实体组件系统(ECS)的体系结构,一种很常见的模式应用于3D游戏开发的最著名的推广统一,一个强大的游戏引擎。这意味着在一个框架的应用系统中,我们创建一个堆的实体,真的什么都不做,和他们的附加组件来描述他们的行为和外观。因为我们使用的反应,这意味着我们将进入我们的过往的道具Entity告诉它什么渲染。例如,通过在一箱作为道具的价值primitive我们将呈现一个盒子。同样,a-sphere,或a-cylinder。然后我们可以在属性像其他价值传递位置rotation材料height基本上,等,任何在A上市文档是公平的游戏。我希望你看到这多么强大,是真的。你抓住你的需要和重视他们的实体功能位。它为我们提供了最大的灵活性和可重用性的代码,是非常好的原因。这就是所谓的在遗传组成

Entity-component-system

但是,为什么反应?

sooooo,所有我们需要的是标记和一些脚本。不管怎样,使用反应,有什么意义呢?好吧,如果你想对这些对象的附加状态,然后手动这样做要付出很多努力。A处理几乎所有的渲染通过HTML属性的使用(或部件如上所述),并更新你的场景中的许多对象的不同属性手动可大为头痛。由于反应是优良的结合状态标记,区分它的你,并重新绘制,我们会利用这。记住,我们不会处理任何WebGL渲染调用或操纵动画循环反应。A有一个内置的动画引擎,为我们处理这个问题。我们只需要通过适当的道具,让它为我们做艰苦的工作。看到这是如何创造你的反应很像普通的应用程序,除了结果是WebGL代替原标记?好的,从技术上讲,它仍然是标记。但A转换为我们的WebGL。够了,说,让我们写一些代码。

设置场景

我们首先要做的是建立一个环境。让我们开始一片空白。删除里面的一切Scene元素为使事物的缘故,看起来很有趣吧,我们将利用第三方组件称为一个环境为我们创造好的环境。第三方组件包很多WebGL的代码在里面,但暴露的接口非常简单的标记。它已经在进口app/intialize.js文件,所以我们要做的就是将它附加到场景元素我已经配置了一些不错的默认我们要开始,但随时修改你的口味。另外,你可以按CTRL + ALT + I加载A和改变参数的实时现场监督。我发现这个超级方便在初期设计时的应用。我们的文件现在应该看起来像:

import { h, Component } from 'preact'
import { Entity, Scene } from 'aframe-react'

// Color palette to use for later
const COLORS = ['#D92B6A', '#9564F2', '#FFCF59']

class App extends Component {
  constructor() {
    super()

    // We'll use this state later on in the tutorial
    this.state = {
      colorIndex: 0,
      spherePosition: { x: 0.0, y: 4, z: -10.0 }
    }
  }

  render() {
    return (
      <Scene
        environment={{
          preset: 'starry',
          seed: 2,
          lightPosition: { x: 0.0, y: 0.03, z: -0.5 },
          fog: 0.8,
          ground: 'canyon',
          groundYScale: 6.31,
          groundTexture: 'walkernoise',
          groundColor: '#8a7f8a',
          grid: 'none'
        }}
      >
      </Scene>
    )
  }
}

A-Frame Environment

那是太容易了?这是A形元件的功率。你别担心。我们将深入到写一些自己的东西从零开始之后。我们不妨照顾相机和光标在这里。让我们定义一个Entity里面的场景标签这一次,我们会通过不同的原语(a-camera在光标

<Entity primitive="a-camera" look-controls>
  <Entity
    primitive="a-cursor"
    cursor={{ fuse: false }}
    material={{ color: 'white', shader: 'flat', opacity: 0.75 }}
    geometry={{ radiusInner: 0.005, radiusOuter: 0.007 }}
  />
</Entity>

知道这是多么的可读性和用户友好的?这是英语。你可以查看每一个单体支柱在框架文件。代替字符串属性,我通过在对象。

人口环境

现在我们有这甜蜜的场景设置,我们可以用对象来填充它。他们可以基本三维几何对象如立方体、球体、圆柱体、八面体、甚至定制的3D模型。为了简单起见,我们将使用默认提供的框架,然后编写自己的组件,并将它附加到默认对象自定义。让我们建立一个低多边形计数球因为他们看起来很酷。我们将定义一个实体,通过在我们的属性使它看起来我们想要的方式。我们将使用a-octahedron原始的本。这段代码将生活之间场景标签以及

<Entity
  primitive="a-octahedron"
  detail={2}
  radius={2}
  position={this.state.spherePosition}
  color="#FAFAF1"
/>

你可能只是看到一个黑暗的球体现在。我们需要一些照明。要有光:

<Entity
  primitive="a-light"
  type="directional"
  color="#FFF"
  intensity={1}
  position={{ x: 2.5, y: 0.0, z: 0.0 }}
/>

这增加了一个方向的光,它是一种在空间某一点发出的光。你也可以尝试使用环境或灯光,但在这种情况下,我更喜欢的方向去模仿来自太阳的方向。

A-Frame 3D Object

建立你的第一个三角支架组件

婴儿的步骤。我们现在有一个3D对象和一个我们可以走/看看周围的环境。现在让我们把它上升一个档次,从头开始建立我们自己定制的框架组件。这部分将改变我们的对象的外观,也重视互动行为,它。我们的组件将提供的形状,创造在它的上面一个稍大的线框形状相同。那就给它一个非常整洁的几何网状(即使是一个字吗?)看要做到这一点,我们将在现有的js文件定义我们的组件app/components/aframe-custom.js

首先,我们将利用全球登记的组成部分AFRAME参考,定义组件的模式,在增加我们的阅读Three js代码初始化功能。你可以把图式作为参数,或者可以通过组件的属性。我们将通过几个选项,如颜色、透明度、和其他视觉特性。这个init函数将尽快跑组件获得依附于实体。我们的框架构件的模板看起来像:

AFRAME.registerComponent('lowpoly', {
  schema: {
    // Here we define our properties, their types and default values
    color: { type: 'string', default: '#FFF' },
    nodes: { type: 'boolean', default: false },
    opacity: { type: 'number', default: 1.0 },
    wireframe: { type: 'boolean', default: false }
  },

  init: function() {
    // This block gets executed when the component gets initialized.
    // Then we can use our properties like so:
    console.log('The color of our component is ', this.data.color)
  }
}

让我们填写init功能。首先,我们改变对象的颜色不正确。然后我们将新的形状为线框。为了创建三维对象以编程方式在WebGL,我们首先需要定义一个几何、数学公式定义的顶点和对象的面孔。然后,我们需要定义一个材料,通过像素图,定义对象的外观像素(颜色、光的反射、纹理)。我们可以结合两组成一个网格。

Three.js Mesh

然后我们需要正确定位,并将它附加到现场。如果这段代码看起来有点冗长的别担心,我已经添加了一些评论引导你穿过它。

init: function() {
  // Get the ref of the object to which the component is attached
  const obj = this.el.getObject3D('mesh')

  // Grab the reference to the main WebGL scene
  const scene = document.querySelector('a-scene').object3D

  // Modify the color of the material
  obj.material = new THREE.MeshPhongMaterial({
    color: this.data.color,
    shading: THREE.FlatShading
  })

  // Define the geometry for the outer wireframe
  const frameGeom = new THREE.OctahedronGeometry(2.5, 2)

  // Define the material for it
  const frameMat = new THREE.MeshPhongMaterial({
    color: '#FFFFFF',
    opacity: this.data.opacity,
    transparent: true,
    wireframe: true
  })

  // The final mesh is a composition of the geometry and the material
  const icosFrame = new THREE.Mesh(frameGeom, frameMat)

  // Set the position of the mesh to the position of the sphere
  const { x, y, z } = obj.position
  icosFrame.position.set(0.0, 4, -10.0)

  // If the wireframe prop is set to true, then we attach the new object
  if (this.data.wireframe) {
    scene.add(icosFrame)
  }

  // If the nodes attribute is set to true
  if (this.data.nodes) {
    let spheres = new THREE.Group()
    let vertices = icosFrame.geometry.vertices

    // Traverse the vertices of the wireframe and attach small spheres
    for (var i in vertices) {
      // Create a basic sphere
      let geometry = new THREE.SphereGeometry(0.045, 16, 16)
      let material = new THREE.MeshBasicMaterial({
        color: '#FFFFFF',
        opacity: this.data.opacity,
        shading: THREE.FlatShading,
        transparent: true
      })

      let sphere = new THREE.Mesh(geometry, material)
      // Reposition them correctly
      sphere.position.set(
        vertices[i].x,
        vertices[i].y + 4,
        vertices[i].z + -10.0
      )

      spheres.add(sphere)
    }
    scene.add(spheres)
  }
}

让我们回到标记反映我们对成分的变化。我们将添加一个lowpoly支撑我们的实体和给我们定义我们模式的参数对象。现在应该看起来像:

<Entity
  lowpoly={{
    color: '#D92B6A',
    nodes: true,
    opacity: 0.15,
    wireframe: true
  }}
  primitive="a-octahedron"
  detail={2}
  radius={2}
  position={{ x: 0.0, y: 4, z: -10.0 }}
  color="#FAFAF1"
/>

A-Frame Lowpoly

添加交互性

我们有我们的场景,我们已经把我们的目标。他们看我们想要的方式。现在是什么?这仍然是很静。让我们通过改变每一次被点击球的颜色添加一些用户输入。

A是一个全功能的raycaster开箱。光线投射给我们的能力来检测一个对象时,“凝视”或“点击”与我们的光标,和执行代码,基于这些事件。虽然它的背后是迷人的数学,我们不必担心它如何实现。只知道它是什么和如何使用它。添加一个raycaster,我们提供raycaster支撑相机的对象,我们要点击类。我们现在应该像相机节点:

<Entity primitive="a-camera" look-controls>
  <Entity
    primitive="a-cursor"
    cursor={{ fuse: false }}
    material={{ color: 'white', shader: 'flat', opacity: 0.75 }}
    geometry={{ radiusInner: 0.005, radiusOuter: 0.007 }}
    event-set__1={{
      _event: 'mouseenter',
      scale: { x: 1.4, y: 1.4, z: 1.4 }
    }}
    event-set__1={{
      _event: 'mouseleave',
      scale: { x: 1, y: 1, z: 1 }
    }}
    raycaster="objects: .clickable"
  />
</Entity>

我们还增加了通过缩放光标时它进入一些反馈和叶子的raycaster目标对象。我们使用一个事件的组件让这一切发生。它让我们定义相应的事件及其影响。现在回去添加class="clickable"我们一点道具前创建3D球体实体。当你在它的附加一个事件处理程序,所以我们可以点击相应的。广告:网站建设

<Entity
  class="clickable"
  // ... all the other props we've already added before
  events={{
    click: this._handleClick.bind(this)
  }}
/>

现在让我们来定义这个_handleClick函数。外的提供调用,定义和使用setState改变颜色指数。我们只是循环0 - 2数字之间的每一次点击。

_handleClick() {
  this.setState({
    colorIndex: (this.state.colorIndex + 1) % COLORS.length
  })
}

好,现在我们改变应用程序的状态。让我们钩到框架对象。使用colorIndex变量循环通过全局定义的颜色数组。我已经对你说,你只需要改变颜色支撑球体的实体创建。像这样:

<Entity
  class="clickable"
  lowpoly={{
    color: COLORS[this.state.colorIndex],
    // The rest stays the same
/>

最后一件事,我们需要修改组件交换材料的颜色属性,因为我们通过一个新的点击时。下面的init定义一个函数,更新函数,得到的时候调用一个道具的组件被修改。里面的update功能,我们简单地交换我们的颜色一样的材料:

AFRAME.registerComponent('lowpoly', {
  schema: {
    // We've already filled this out
  },

  init: function() {
    // We've already filled this out
  }

  update: function() {
    // Get the ref of the object to which the component is attached
    const obj = this.el.getObject3D('mesh')

    // Modify the color of the material during runtime
    obj.material.color = new THREE.Color(this.data.color)
  }
}

你现在应该能够点击球和循环的颜色。

A-Frame Interactivity

动画对象

让我们添加一点点的运动场景。我们可以使用一个动画组件要做到这一点。它已经被进口让我们的低聚球体添加功能。对同一个实体,添加另一个道具命名animation__rotate。这只是一个名字,我们给它,你可以称它为任何你想要的。我们通过内部的性质是最重要的。在这种情况下,它旋转球体360度在Y轴。可以自由的玩的时间和性能参数。

<Entity
  class="clickable"
  lowpoly
  // A whole buncha props that we wrote already...
  animation__rotate={{
    property: 'rotation',
    dur: 60000,
    easing: 'linear',
    loop: true,
    to: { x: 0, y: 360, z: 0 }
  }}
/>

为使这一点更有趣,让我们添加另一个动画道具振荡球体上下微微。

animation__oscillate={{
  property: 'position',
  dur: 2000,
  dir: 'alternate',
  easing: 'linear',
  loop: true,
  from: this.state.spherePosition,
  to: {
    x: this.state.spherePosition.x,
    y: this.state.spherePosition.y + 0.25,
    z: this.state.spherePosition.z
  }
}}

抛光

我们快到了!在WebGL中处理后的效果是非常快的,可以为你的场景增添了不少人物。有许多可用的着色器使用取决于审美你去。如果你想添加后处理效果到你的场景,你可以通过阅读Three js做额外的阴影。我最喜欢的是一些绽放,模糊和噪声阴影。我们跑,很简单,这里。

处理后的效果在你的场景作为一个整体。认为这是一个位图,每一帧的渲染。这就是所谓的帧缓冲区。的影响,把这个图像,处理,输出到渲染器。这个框架效应组分已经为你方便的进口,所以我们在我们把道具Scene标签我们将使用一个混合的绽放,电影,和FXAA给我们的最后一幕一点个性:

<Scene
  effects="bloom, film, fxaa"
  bloom="radius: 0.99"
  film="sIntensity: 0.15; nIntensity: 0.15"
  fxaa
  // Everything else that was already there
/>

A-Frame Post Processing

繁荣.我们要做的。有着色数学要在幕后场景一大笔(双关语),但你不需要知道它的任何。这就是抽象的美。如果你好奇,你总是可以挖掘到的源文件,看看渲染魔法发生的后面。这是一个属于自己的世界。我们几乎在这里完成。到了最后一步…

部署

它的时间来部署。最后一步是让它活在别人的服务器上,而不是你的开发服务器。我们将使用超级棒的工具称为潮使这痛苦容易。首先,我们需要一个生产我们的应用程序的构建。运行yarn build。它将输出最终构建的公共目录通过运行安装浪涌npm install -g surge。现在运行公共/浪涌把生活的内容目录。它会提示您登录或创建一个帐户,你可以选择改变你的域名。其余的应该是很简单的,你会得到一个网址,你的网站在年底部署。够了就要这些。

Surge Prompt

我希望你喜欢这个教程,你看到A和其能力的力量。结合第三方组件和做我们自己,我们可以创造一些相对轻松,整洁的3D场景。延伸的这一切反应,我们能够有效地管理国家和动态道具疯狂。我们只是触及表面,和现在的你去探索其他的。作为2D内容未能满足身临其境的Web内容的需求不断增加,像A和阅读Three js工具已经进入了风头。WebVR的未来看起来一片光明。去发挥你的创造力,因为浏览器是一个空的三维画布和代码是你的画笔。
重庆网站建设


服务支持

我们珍惜您每一次在线询盘,有问必答,用专业的态度,贴心的服务。

让您真正感受到我们的与众不同!

合作流程
合作流程

重庆网站建设流程从提出需求到网站建设报价,再到网站建设,每一步都是规范和专业的。

常见问题
常见问题

什么是网站定制?网站报价如何?网站常见问题。

常见问题
售后保障

网站建设不难,难的是一如既往的热情服务及技术支持。我们知道:做网站就是做服务,就是做售后。