< >头 WebVR Part 5:设计与实现| Toptal®-欧博体育app下载作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
迈克尔·科尔的头像

迈克尔•科尔

Michael是一位专业的全栈网络工程师, 演讲者, 拥有20多年经验和计算机科学学位的顾问.

专业知识

以前在

恩斯特 & 年轻的
分享

我喜欢让项目“完成”.“我们已经到达了旅程的终点,我们的天体重力模拟在WebVR中诞生了.

在这最后一篇文章中, 我们将插入我们的高性能仿真代码(第1章),2,3)变成基于画布可视化器的WebVR可视化器(第4条).

  1. “n体问题” 简介与架构
  2. Web Workers 获取额外的浏览器线程
  3. WebAssembly和AssemblyScript 我们的O(n²)性能瓶颈代码
  4. 画布数据可视化
  5. WebVR数据可视化

这是一篇较长的文章,因此我们将跳过前面介绍的一些技术细节. 如果你想要一个方向,可以看看以前的帖子,或者继续读下去.

我们一直在探索浏览器从单线程JavaScript运行时到多线程(web worker)高性能运行时(WebAssembly)的范式转变。. 这些性能桌面计算特性在Progressive Web Apps和 SaaS分布 模型.

WebVR演示

VR将创造引人注目的无干扰的销售和营销环境来进行沟通, 说服, 测量参与度(眼动追踪和互动). 数据仍然是0和1, 但预期的执行摘要和消费者体验将是WebVR——就像我们今天为平面网络构建移动仪表板体验一样.

这些技术还支持分布式浏览器边缘计算. 例如, 我们可以创建一个基于web的应用程序,在模拟中运行我们的WebAssembly对数百万颗恒星的计算. 另一个例子是一个动画应用程序,它在您编辑自己的作品时呈现其他用户的作品.

娱乐内容引领着虚拟现实技术的发展, 就像手机上的娱乐一样. 然而, 一旦VR成为常态(就像今天的移动优先设计), 这将是预期的体验(vr优先设计). 对于设计师和开发者来说,这是一个非常激动人心的时代——VR是一个完全不同的设计范式.

如果你做不到这一点,你就不是VR设计师 控制. 这是一个大胆的声明,今天我们将深入探讨VR设计. 当你读到这篇文章时,这个领域正在被发明. 我的目的是分享我在软件和电影方面的经验,以启动“vr优先设计”的对话. 我们都互相学习.

记住那些宏伟的预言, 我想完成这个项目作为一个专业的技术演示- WebVR是一个很好的选择!

WebVR和Google 人字形

WebVR git仓库 是否是canvas版本的分支有几个原因. 它使得在Github页面上托管项目更容易, WebVR需要做一些改变,这可能会使画布版本和这些文章变得混乱.

如果你还记得 我们的第一篇关于架构的文章,我们将整个模拟委托给 nBodySimulator.

“nBodySimulator”

网络工作者职位 显示 nBodySimulator 有一个 步骤() 函数在模拟过程中每33毫秒调用一次. 步骤() 调用 calculateForces () 求出O(n²) WebAssembly仿真代码 (第3条),然后更新位置并重新绘制. 在我们的 上一篇文章创建画布可视化,我们用canvas元素实现了这一点,从这个基类开始:


/**

 *控制台的基类.Log()是模拟状态.

 */

导出类nBodyVisualizer {

  构造函数(htmlElement) {

    这.htmlElement = htmlElement

    这.调整()

    这.scaleSize = 25 //划分为主体drawSize. drawSize是log10(质量)

    //这可以重构到子类. 

    //艺术永无止境. 它必须被抛弃.

  }

  调整(){}

  油漆(身体){

    控制台.日志(JSON.Stringify (body, null, 2))

  }

}

定义集成挑战

我们进行了模拟. 现在,我们想要与WebVR集成,而无需重新构建我们的项目. 我们对模拟所做的任何调整都会在函数的主UI线程中每33毫秒发生一次 油漆(身体).

这就是我们衡量“完成”的方式.“我很兴奋,让我们开始工作吧!

如何制作虚拟现实

首先,我们需要一个设计:

  • 什么是VR 做的?
  • WebVR是如何设计的 表达了?
  • 我们怎么能 交互 用它?

虚拟现实回到了时间的开端. 每个篝火故事都是一个小小的虚拟世界,由琐碎的细节掩盖着古怪的夸张.

我们可以通过添加3D立体视觉和音频将篝火故事放大10倍. 我的电影制作预算指导老师曾经说过, “我们只付海报的钱. 我们不是在创造现实.”

如果您熟悉浏览器DOM,就会知道它创建了一个树状的层次结构.

平面网络场景图

网页设计中隐含的是浏览者从“正面”观看.“从侧面看,DOM元素会显示为线条,而从背面看,我们只会看到 标记,因为它模糊了它的子元素.

VR沉浸式体验的一部分是让用户控制自己的视角, style, 速度, 以及相互作用的顺序. 他们不需要特别注意任何事情. 如果你通过编程方式移动或旋转摄像机,它们就会这样做 随便吐 从VR病.

请注意,VR病可不是开玩笑的. 我们的眼睛和内耳都能察觉到运动. 这对直立行走的动物来说非常重要. 当这些运动传感器不一致时, 我们的大脑自然会认为我们的嘴又在吃废话,然后呕吐. 我们都曾经是孩子. 关于VR中的这种生存本能已经有很多文章了. 这款名为《Epic Fun》的游戏在Steam上是免费的,过山车是我发现的最好的VR恶心演示.

虚拟现实被表示为“场景图”.“场景图具有与DOM相同的树状模式,以隐藏令人信服的3D环境的细节和复杂性. 然而, 而不是滚动和路由, 我们把观众放在他们想要的地方.

下面是来自Google的人字形 WebVR框架的Hello World场景图:






  

    

    Hello, WebVR! • 人字形

    

    

  

  

    

      

      

      

      

    

  































这个HTML文档在浏览器中创建了一个DOM. 的 标记是人字形框架的一部分,并且 是场景图的根吗. 在这里,我们看到场景中显示了四个3D原语.

平面网页浏览器中的a帧场景

首先,请注意我们是从平面网页浏览器查看场景的. 右下角的小掩模邀请用户切换到3D立体模式.

虚拟现实中的a帧场景

理论上,您应该能够:

  1. 在手机上打开这个
  2. 把手机举到脸上
  3. 享受新现实的辉煌!

如果没有VR头显的花哨镜头,我就无法做到这一点. 你可以很便宜地为Android手机买到VR头显(基于Google Cardboard的基本设备)。, 然而, 开发内容, 我建议使用独立的HMD(头戴式显示器),如Oculus Quest.

就像水肺潜水或跳伞一样,虚拟现实是一项装备运动.

VR设计师的学习“悬崖”

有重力和光的现实

注意a帧Hello World场景有一个默认的灯光和相机:

  • 立方体的面是不同的颜色-立方体是自阴影.
  • 立方体在平面上投射了一个阴影——有一个定向光.
  • 立方体和平面之间没有缝隙——这是一个有重力的世界.

这些关键的线索告诉观众, “放轻松,你脸上的东西很正常.”

还要注意,这个默认设置在上面的Hello World场景代码中是隐含的. a - frame明智地提供了一个合理的默认值, 但请注意,相机和灯光是平面网页设计师创造VR必须跨越的鸿沟.

我们认为默认的照明设置是理所当然的. 例如,按钮:

按钮

注意这种含蓄的照明在设计和摄影中是多么普遍. 即使是“平面设计”按钮也无法逃脱网页的默认灯光——它会向下方和右侧投下阴影.

设计, 沟通, 实现照明和相机设置是WebVR设计师的学习悬崖. 的 “电影语言” 文化规范的集合——表现为不同的镜头和灯光设置——是否能在情感上向观众传达故事. 在电影中设计/移动灯光和镜头的专业人士是 控制部门.

回到我们的虚拟现实

好了,我们回去工作吧. 我们的天体WebVR场景也有类似的模式:








  

  

  





  

    

    

      

    

    

    

    

    

      <一个摄像头>

        <一个游标 color="#4CC3D9" fuse="true" timeout="1">

      

    

  

































这个HTML文档加载了人字形框架和一个交互插件. 我们的场景从 .

在里面,我们从an开始 元素到背景颜色,所有我们没有在场景中定义的东西.

下一个, 我们为观众创造了一个“轨道平面”,当他们飞过我们陌生而未知的世界时,他们可以“抓住”. 我们将其创建为圆盘和(0,0,0)处的黑色小球. 没有这一点,转弯对我来说是“没有根据的”:


    

      

    

接下来,我们定义一个集合,我们可以在其中添加/移除/重新定位a - frame实体.




这是空地 nBodyVisualizers 油漆(身体) 来完成它的工作.

然后,我们创造观众和这个世界之间的关系. 作为一个技术演示, 这个世界的目的是让观众探索WebVR和支持它的浏览器技术. 一个简单的“宇航员”叙事创造了一种游戏感, 这个恒星路标是导航的另一个参考点.


   

    

这就完成了我们的场景图. 最后,我想 一些 在手机演示中,用户和这个旋转的世界之间有一种互动. 我们如何在VR中重现“扔垃圾”按钮?

按钮是所有现代设计的原始元素- VR按钮在哪里?

WebVR中的交互

虚拟现实有它自己的“上”和“下”.“观众的第一次互动是通过他们的化身或相机. 这是所有的缩放控制.

如果你是在台式机上阅读这篇文章,你可以用WASD来移动,用鼠标来旋转相机. 这种探索揭示了信息,但并没有表达你的意愿.

Real Reality有几个非常重要的功能,通常在网络上找不到:

  • 的角度来看 -当物体远离我们时,它们会明显变小.
  • 闭塞 -根据位置隐藏和显示对象.

VR模拟这些特征来创造3D效果. 它们还可以在VR中用于显示信息和界面,并在呈现交互之前设置情绪. 我发现大多数人在继续前进之前只需要一分钟的时间来享受这段经历.

在WebVR中,我们在3D空间中互动. 我们有两个基本工具:

  • 碰撞 -当两个物体共享同一空间时触发被动3D事件.
  • 投影 -一个活动的2D函数调用,列出所有与直线相交的对象.

碰撞是最“像vr”的交互

在虚拟现实, “碰撞”顾名思义就是:两个物体共享同一空间, 人字形创建事件.

为了让用户“按”下按钮,我们必须给他们一个棋子和一些东西来按下按钮.

不幸的是, WebVR还不能采用控制器——许多人会在他们的桌面或手机上看到平面网络版本, 许多人将使用谷歌Cardboard或三星Gear VR等头显来展示立体版本.

如果用户没有控制器, 他们不能伸手去“摸”东西, 因此,任何冲突都将发生在他们的“个人空间”上.”

我们可以给玩家一个宇航员形状的棋子来移动, 但是强迫用户进入旋转的行星瘴气似乎有点令人不快,并且与我们设计的空间背道而驰.

投影是在3D空间中进行的2D“类似网页”的点击

除了“碰撞”,我们还可以使用“投影”.“我们可以在我们的场景中投射一条线,看看它接触到什么. 最常见的例子是“传送射线”.”

传送射线沿着世界中的一条线显示玩家可以移动的位置. 这个“投影”寻找着陆点. 它返回投影路径中的一个或多个对象. 下面是一个传送射线的例子:

虚幻引擎默认内容中的传送射线

注意到光线实际上是一个向下的抛物线. 这意味着它自然地与“地面”相交,就像一个被抛出的物体. 这自然也会设置一个最大传送距离. 限制是VR中最重要的设计选择. 幸运的是,现实有许多自然的限制.

投影将3D世界“扁平化”为2D,这样你就可以像鼠标一样指着东西点击它. 第一人称射击游戏是一款精致的“2D点击”游戏,玩家需要点击那些令人沮丧的按钮——通常还会有一个精致的故事来解释为什么这些该死的按钮不能“点击”你.

VR中有如此多的枪支,因为枪支已经被完善为精确可靠的3D鼠标,而点击是消费者无需学习就知道如何做的事情.

投影还在与场景的关系中提供了距离的安全性. 还记得, 在VR中越接近某样东西,自然就会遮挡掉所有其他的东西,而这些东西的重要性可能还没有显现出来.

使用“凝视”的无控制器投影

在没有控制器的WebVR中创建这个交互原语, 我们可以将观看者的“凝视”投射为视线“光标”.这个光标可以通过编程方式与带有“保险丝”的对象进行交互.“这是通过一个小蓝圈传达给观众的. 现在我们点击!

如果你记得篝火故事,谎言越大,推销它所需的细节就越少. 一个明显而荒谬的“凝视”互动是凝视太阳. 我们使用这种“凝视”来触发添加新的“碎片”行星到我们的模拟中. 没有观众质疑过这个选择——VR在荒谬的时候也很迷人.

在的尖顶, 我们将摄像机(玩家的隐形棋子)和视线“光标”表达为我们的摄像机组件. 将 <一个游标><一个摄像头> 使相机的转换也应用于光标. 当玩家移动/旋转他们的兵(一个摄像头),它也会移动/旋转他们的目光(一个游标).


/ / src /索引.html

    

      <一个摄像头>

        <一个游标 color="#4CC3D9" fuse="true" timeout="1">

      

    

光标的“导火索”要等到“凝视”整整一秒后才会发出一个事件.

我使用了默认照明,所以你可能会注意到太阳的“背面”没有被照亮. 虽然我没有离开过轨道平面,但我不认为这是太阳运行的方式. 然而,它适用于我们的现实技术演示海报.

另一种选择是将灯光放在相机元素中, 所以它会随着用户移动. 这将创造一种更亲密的——可能是令人毛骨悚然的——小行星矿工体验. 这些都是有趣的设计选择.

我们有一个整合计划

这样,我们就有了a坐标系之间的积分点 以及我们的JavaScript模拟:

人字形 :

  • 尸体的命名集合:

  • 将发出投影事件的游标: <一个游标 color="#4CC3D9" fuse="true" timeout="1">

我们的JavaScript模拟:

  • nBodyVisWebVR.油漆(身体) 添加/移除/重新定位虚拟现实实体

  • addBodyArgs(name, color, x, y, z, mass, vX, vY, vZ) 添加新的碎片体到模拟中

指数.html 加载 main.js,这将初始化我们的模拟,就像canvas版本一样:


/ / src / main.js

导入{nBodyVisualizer, nBodyVisWebVR .“/ nBodyVisualizer”

导入{Body, nBodySimulator .“/ nBodySimulator”

窗口.Onload = function() {

  //创建模拟

  const sim卡 = new nBodySimulator()

  

  //这个Visualizer管理UI

  sim卡.addVisualization(新nBodyVisWebVR(文档.getElementById(“a-的身体”),sim卡)) 

  

  //创造稳定的宇宙是困难的

  //名称颜色x y z m vz vy vz

  sim卡.addBody(new Body("star", "yellow", 0,0,1,1e9)) 

  sim卡.addBody(new Body) ("hot-jupiter", "red", - 1,1,1,1e4,  .24,  -0.05,  0))

  sim卡.addBody(new Body) ("cold-jupiter", "purple", 4,4,  .5,   1e4, -.07,   0.04,  0))

  //启动模拟  

  sim卡.start ()

  

  //添加另一个

  sim卡.addBody(new Body) ("saturn", "blue", -8, -8,  .1,   1e3,   .07,   -.035,  0))

}

你会注意到这里我们设置了 htmlElement 可视化器的 a-的身体 收集尸体.

从JavaScript编程地管理人字形对象

已经宣布了我们的场景 指数.html,我们现在准备编写可视化工具.

首先,我们设置 nBodyVisualizernBodySimulation 列表中创建/更新/删除人字形对象 集合.


/ / src / nBodyVisualizer.js

/**

 *这是WebVR可视化工具. 

 *它负责绘制和设置整个场景.

 */

导出类nBodyVisWebVR扩展nBodyVisualizer {

  constructor(htmlElement, sim卡) {

    // HTML元素是一个集合.

    超级(htmlElement)

    //我们将这些添加到全局命名空间中,因为 

    //这不是我们要解决的核心问题.

    窗口.Sim = Sim

    这.nextId = 0

  }

  调整(){}

在构造函数中, 我们保存了我们的人字形系列, 为我们的凝视事件设置一个全局变量来查找模拟, 并初始化一个id计数器,我们将使用它来匹配我们的模拟和人字形场景之间的身体.


  油漆(身体){

    让我

    //创建查找表:lookup[body ..aframeId] = body

    Const lookup = body.reduce( (total, body) => {

      //如果是新的body,给它一个aframeId

      if (!body.aframeId)身体.aframeId = ' a-sim卡-body-${body.名称}- $ {.nextId + +} '

      总(身体.aframeId] = body

      返回总

    }, {})

    //循环遍历现有的a-sim卡- body并删除任何不在其中的

    //查找-这是我们丢弃的碎片

    const aSimBodies =文档.querySelectorAll (.“a-sim卡-body”)

    for (i = 0; i  {

      //找到这个框架id的html元素

      body = document.getElementById(身体.aframeId)

      //如果没有找到html元素,创建一个.

      if (!一体的){

        这.htmlElement.innerHTML += '



`

        body = document.getElementById(身体.aframeId)

      }

      / /复位

      一体的.object3D.位置.集(身体.x,身体.y,身体.z)

    })

}

第一个, 我们循环遍历模拟体以标记和/或创建查找表,以便将a - frame实体与模拟体相匹配.

下一个, 我们循环遍历现有的人字形体,并删除任何因出界而被模拟修剪过的物体. 这将提高体验的感知性能.

最后,我们循环模拟主体来创建一个新的 寻找失踪的尸体并重新定位其他尸体 一体的.object3D.位置.集(身体.x,身体.y,身体.z)

我们可以使用标准DOM函数以编程方式改变人字形场景中的元素. 为了在场景中添加一个元素,我们向容器的innerHTML添加一个字符串. 这段代码对我来说味道很奇怪,但它有效,我没有找到更好的.

您将注意到,当我们创建要追加的字符串时, 我们在“星号”附近有一个三元运算符来设置属性.




`

如果主体是“星型”,我们添加一些描述其事件的额外属性. 下面是我们的星形在DOM中加载时的样子:




三个属性, debris-listener, event-set__enterevent-set__leave,建立我们的互动,是我们融合的最后一圈.

定义人字形事件和交互

我们使用 NPM package " frame-event-set-component " 在实体的属性中改变查看者“看着”太阳时太阳的颜色.

这种“凝视”是从观看者的位置和旋转中投射出来的, 这种互动提供了必要的反馈,表明他们的目光在做一些事情.

我们的星球现在有两个由插件启用的简短事件, event-set__enterevent-set__leave:




接下来,我们用一个装饰我们的星球 debris-listener 我们将实现为一个自定义的a - frame组件.




人字形组件是在全局级别定义的:


/ / src / nBodyVisualizer.js

//组件,当用户盯着太阳时添加新的物体. 看到HTML

AFRAME.registerComponent (debris-listener, {

  Init: function () {

    //辅助函数

    函数随机(缩放){返回(数学.随机()-.5) *刻度}

    //添加10个新主体

    这.el.addEventListener('click', function (evt) {

      for (let x=0; x<10; x++) {

        // name, color, x, y, z, mass, vx, vy, vz

        窗口.sim卡.addBodyArgs(“碎片”,“白色”,随机(10),随机(10),随机(10),1,随机(.1)、金兰(.1)、金兰(.1))

      }

    })

  }

})

这个a - frame组件就像一个“点击”监听器,可以由凝视光标触发,为我们的场景添加10个新的随机物体.

总结:

  1. 我们在标准HTML中声明带有人字形的WebVR场景.
  2. 我们可以通过JavaScript在场景中添加/删除/更新人字形实体.
  3. 我们可以通过人字形插件和组件在JavaScript中创建与事件处理程序的交互.

Veni, Vidi, Vici

我希望你从这次技术演示中得到和我一样多的收获. 我们将这些特性(web workers和WebAssembly)应用到WebVR的哪些地方, 它们也可以应用于浏览器边缘计算.

一股巨大的技术浪潮已经到来——虚拟现实(VR). 你第一次拿着智能手机的感觉, 第一次体验虚拟现实可以在计算的各个方面提供10倍的情感体验. 从第一代iPhone到现在才过去了12年.

VR的历史要长得多, 但将VR带给普通用户所需的技术是通过移动革命和Facebook的Oculus Quest来实现的,而不是PC革命.

互联网和开源是人类最伟大的奇迹之一. 对于所有创造扁平化互联网的人们,我要为你们的勇气和冒险精神干杯.

宣言! 我们将建造世界,因为我们有创造的能力.

WebVR演示

了解基本知识

  • 什么是基于Web的VR?

    当一个人把屏幕绑在脸上时,VR就发生了, 创造一种身临其境的体验,让他们“假装”自己真的在那里.

  • VR是如何工作的?

    基于网络的虚拟现实利用网络上的奇异现实,将虚拟现实更贴近人类的心灵, 但在僵化的“信息是书中的一页”范式之外. WebVR是虚拟现实公域.

  • 什么是边缘计算?

    边缘计算的概念是在租用新设备之前使用运行应用程序的所有边缘设备的计算能力.

聘请Toptal这方面的专家.
现在雇佣
迈克尔·科尔的头像
迈克尔•科尔

位于 达拉斯,美国

成员自 2014年9月10日

作者简介

Michael是一位专业的全栈网络工程师, 演讲者, 拥有20多年经验和计算机科学学位的顾问.

Toptal作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.

专业知识

以前在

恩斯特 & 年轻的

世界级的文章,每周发一次.

订阅意味着同意我们的 隐私政策

世界级的文章,每周发一次.

订阅意味着同意我们的 隐私政策

Toptal开发者

加入总冠军® 社区.

\n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n \n\n\n\n\n\n

这个HTML文档在浏览器中创建了一个DOM. 的 标记是人字形框架的一部分,并且 是场景图的根吗. 在这里,我们看到场景中显示了四个3D原语.

\n\n

\"平面网页浏览器中的a帧场景\"
平面网页浏览器中的a帧场景.\n

\n\n

首先,请注意我们是从平面网页浏览器查看场景的. 右下角的小掩模邀请用户切换到3D立体模式.

\n\n

\"虚拟现实中的a帧场景\"
虚拟现实中的a帧场景 - one image for each eye.\n

\n\n

理论上,您应该能够:

\n\n
    \n
  1. 在手机上打开这个
  2. \n
  3. 把手机举到脸上
  4. \n
  5. 享受新现实的辉煌!
  6. \n
\n\n

如果没有VR头显的花哨镜头,我就无法做到这一点. 你可以很便宜地为Android手机买到VR头显(基于Google Cardboard的基本设备)。, 然而, 开发内容, 我建议使用独立的HMD(头戴式显示器),如Oculus Quest.

\n\n

就像水肺潜水或跳伞一样,虚拟现实是一项装备运动.

\n\n

VR设计师的学习“悬崖”

\n\n

\"有重力和光的现实\"
Welcome to 这 comfortable reality with gravity 和 light.\n

\n\n

注意a帧Hello World场景有一个默认的灯光和相机:

\n\n\n\n

这些关键的线索告诉观众, “放轻松,你脸上的东西很正常.”

\n\n

还要注意,这个默认设置在上面的Hello World场景代码中是隐含的. a - frame明智地提供了一个合理的默认值, 但请注意,相机和灯光是平面网页设计师创造VR必须跨越的鸿沟.

\n\n

我们认为默认的照明设置是理所当然的. 例如,按钮:

\n\n

\"按钮\"

\n\n

注意这种含蓄的照明在设计和摄影中是多么普遍. 即使是“平面设计”按钮也无法逃脱网页的默认灯光——它会向下方和右侧投下阴影.

\n\n

设计, 沟通, 实现照明和相机设置是WebVR设计师的学习悬崖. 的 “电影语言” 文化规范的集合——表现为不同的镜头和灯光设置——是否能在情感上向观众传达故事. 在电影中设计/移动灯光和镜头的专业人士是 控制部门.

\n\n

回到我们的虚拟现实

\n\n

好了,我们回去工作吧. 我们的天体WebVR场景也有类似的模式:

\n\n
\n\n\n\n\n\n\n  \n\n  \n\n  \n\n\n\n\n\n  \n\n    \n\n    \n\n      \n\n    \n\n    \n\n    \n\n    \n\n    \n\n      <一个摄像头>\n\n        <一个游标 color=\"#4CC3D9\" fuse=\"true\" timeout=\"1\">\n\n      \n\n    \n\n  \n\n



























\n\n\n\n
\n\n

这个HTML文档加载了人字形框架和一个交互插件. 我们的场景从 .

\n\n

在里面,我们从an开始 元素到背景颜色,所有我们没有在场景中定义的东西.

\n\n

下一个, 我们为观众创造了一个“轨道平面”,当他们飞过我们陌生而未知的世界时,他们可以“抓住”. 我们将其创建为圆盘和(0,0,0)处的黑色小球. 没有这一点,转弯对我来说是“没有根据的”:

\n\n
\n    \n\n      \n\n    \n
\n\n

接下来,我们定义一个集合,我们可以在其中添加/移除/重新定位a - frame实体.

\n\n
\n\n\n
\n\n

这是空地 nBodyVisualizers 油漆(身体) 来完成它的工作.

\n\n

然后,我们创造观众和这个世界之间的关系. 作为一个技术演示, 这个世界的目的是让观众探索WebVR和支持它的浏览器技术. 一个简单的“宇航员”叙事创造了一种游戏感, 这个恒星路标是导航的另一个参考点.

\n\n
\n   \n\n    \n\n
\n\n

这就完成了我们的场景图. 最后,我想 一些 在手机演示中,用户和这个旋转的世界之间有一种互动. 我们如何在VR中重现“扔垃圾”按钮?

\n\n

按钮是所有现代设计的原始元素- VR按钮在哪里?

\n\n

WebVR中的交互

\n\n

虚拟现实有它自己的“上”和“下”.“观众的第一次互动是通过他们的化身或相机. 这是所有的缩放控制.

\n\n

如果你是在台式机上阅读这篇文章,你可以用WASD来移动,用鼠标来旋转相机. 这种探索揭示了信息,但并没有表达你的意愿.

\n\n

Real Reality有几个非常重要的功能,通常在网络上找不到:

\n\n\n\n

VR模拟这些特征来创造3D效果. 它们还可以在VR中用于显示信息和界面,并在呈现交互之前设置情绪. 我发现大多数人在继续前进之前只需要一分钟的时间来享受这段经历.

\n\n

在WebVR中,我们在3D空间中互动. 我们有两个基本工具:

\n\n\n\n

碰撞是最“像vr”的交互

\n\n

在虚拟现实, “碰撞”顾名思义就是:两个物体共享同一空间, 人字形创建事件.

\n\n

为了让用户“按”下按钮,我们必须给他们一个棋子和一些东西来按下按钮.

\n\n

不幸的是, WebVR还不能采用控制器——许多人会在他们的桌面或手机上看到平面网络版本, 许多人将使用谷歌Cardboard或三星Gear VR等头显来展示立体版本.

\n\n

如果用户没有控制器, 他们不能伸手去“摸”东西, 因此,任何冲突都将发生在他们的“个人空间”上.”

\n\n

我们可以给玩家一个宇航员形状的棋子来移动, 但是强迫用户进入旋转的行星瘴气似乎有点令人不快,并且与我们设计的空间背道而驰.

\n\n

投影是在3D空间中进行的2D“类似网页”的点击

\n\n

除了“碰撞”,我们还可以使用“投影”.“我们可以在我们的场景中投射一条线,看看它接触到什么. 最常见的例子是“传送射线”.”

\n\n

传送射线沿着世界中的一条线显示玩家可以移动的位置. 这个“投影”寻找着陆点. 它返回投影路径中的一个或多个对象. 下面是一个传送射线的例子:

\n\n

\"虚幻引擎默认内容中的传送射线\"
虚幻引擎默认内容中的传送射线.\n

\n\n

注意到光线实际上是一个向下的抛物线. 这意味着它自然地与“地面”相交,就像一个被抛出的物体. 这自然也会设置一个最大传送距离. 限制是VR中最重要的设计选择. 幸运的是,现实有许多自然的限制.

\n\n

投影将3D世界“扁平化”为2D,这样你就可以像鼠标一样指着东西点击它. 第一人称射击游戏是一款精致的“2D点击”游戏,玩家需要点击那些令人沮丧的按钮——通常还会有一个精致的故事来解释为什么这些该死的按钮不能“点击”你.

\n\n

VR中有如此多的枪支,因为枪支已经被完善为精确可靠的3D鼠标,而点击是消费者无需学习就知道如何做的事情.

\n\n

投影还在与场景的关系中提供了距离的安全性. 还记得, 在VR中越接近某样东西,自然就会遮挡掉所有其他的东西,而这些东西的重要性可能还没有显现出来.

\n\n

使用“凝视”的无控制器投影

\n\n

在没有控制器的WebVR中创建这个交互原语, 我们可以将观看者的“凝视”投射为视线“光标”.这个光标可以通过编程方式与带有“保险丝”的对象进行交互.“这是通过一个小蓝圈传达给观众的. 现在我们点击!

\n\n

如果你记得篝火故事,谎言越大,推销它所需的细节就越少. 一个明显而荒谬的“凝视”互动是凝视太阳. 我们使用这种“凝视”来触发添加新的“碎片”行星到我们的模拟中. 没有观众质疑过这个选择——VR在荒谬的时候也很迷人.

\n\n

在的尖顶, 我们将摄像机(玩家的隐形棋子)和视线“光标”表达为我们的摄像机组件. 将 <一个游标><一个摄像头> 使相机的转换也应用于光标. 当玩家移动/旋转他们的兵(一个摄像头),它也会移动/旋转他们的目光(一个游标).

\n\n
\n/ / src /索引.html\n\n    \n\n      <一个摄像头>\n\n        <一个游标 color=\"#4CC3D9\" fuse=\"true\" timeout=\"1\">\n\n      \n\n    \n\n
\n\n

光标的“导火索”要等到“凝视”整整一秒后才会发出一个事件.

\n\n

我使用了默认照明,所以你可能会注意到太阳的“背面”没有被照亮. 虽然我没有离开过轨道平面,但我不认为这是太阳运行的方式. 然而,它适用于我们的现实技术演示海报.

\n\n

另一种选择是将灯光放在相机元素中, 所以它会随着用户移动. 这将创造一种更亲密的——可能是令人毛骨悚然的——小行星矿工体验. 这些都是有趣的设计选择.

\n\n

我们有一个整合计划

\n\n

这样,我们就有了a坐标系之间的积分点 以及我们的JavaScript模拟:

\n\n

人字形 :

\n\n\n\n

我们的JavaScript模拟:

\n\n\n\n

指数.html 加载 main.js,这将初始化我们的模拟,就像canvas版本一样:

\n\n
\n/ / src / main.js\n\n导入{nBodyVisualizer, nBodyVisWebVR .\"/nBodyVisualizer\"\n\n导入{Body, nBodySimulator .\"/nBodySimulator\"\n\n窗口.Onload = function() {\n\n  //创建模拟\n\n  const sim卡 = new nBodySimulator()\n\n  \n\n  //这个Visualizer管理UI\n\n  sim卡.addVisualization(新nBodyVisWebVR(文档.getElementById(\"a-的身体\"), sim卡)) \n\n  \n\n  //创造稳定的宇宙是困难的\n\n  //名称颜色x y z m vz vy vz\n\n  sim卡.addBody(new Body(\"star\",         \"yellow\", 0,   0,   1,   1e9)) \n\n  sim卡.addBody(new Body(\"hot-jupiter\",  \"red\",   -1,  -1,   1,   1e4,  .24,  -0.05,  0))\n\n  sim卡.addBody(new Body(\"cold-jupiter\", \"purple\", 4,   4,  .5,   1e4, -.07,   0.04,  0))\n\n  //启动模拟  \n\n  sim卡.start ()\n\n  \n\n  //添加另一个\n\n  sim卡.addBody(new Body(\"saturn\",       \"blue\",  -8,  -8,  .1,   1e3,   .07,   -.035,  0))\n\n}\n\n
\n\n

你会注意到这里我们设置了 htmlElement 可视化器的 a-的身体 收集尸体.

\n\n

从JavaScript编程地管理人字形对象

\n\n

已经宣布了我们的场景 指数.html,我们现在准备编写可视化工具.

\n\n

首先,我们设置 nBodyVisualizernBodySimulation 列表中创建/更新/删除人字形对象 集合.

\n\n
\n/ / src / nBodyVisualizer.js\n\n/**\n\n *这是WebVR可视化工具. \n\n *它负责绘制和设置整个场景.\n\n */\n\n导出类nBodyVisWebVR扩展nBodyVisualizer {\n\n  constructor(htmlElement, sim卡) {\n\n    // HTML元素是一个集合.\n\n    超级(htmlElement)\n\n    //我们将这些添加到全局命名空间中,因为 \n\n    //这不是我们要解决的核心问题.\n\n    窗口.Sim = Sim\n\n    这.nextId = 0\n\n  }\n\n  调整(){}\n\n
\n\n

在构造函数中, 我们保存了我们的人字形系列, 为我们的凝视事件设置一个全局变量来查找模拟, 并初始化一个id计数器,我们将使用它来匹配我们的模拟和人字形场景之间的身体.

\n\n
\n  油漆(身体){\n\n    让我\n\n    //创建查找表:lookup[body ..aframeId] = body\n\n    Const lookup = body.reduce( (total, body) => {\n\n      //如果是新的body,给它一个aframeId\n\n      if (!body.aframeId)身体.aframeId = ' a-sim卡-body-${body.名称}- $ {.nextId + +} '\n\n      总(身体.aframeId] = body\n\n      返回总\n\n    }, {})\n\n    //循环遍历现有的a-sim卡- body并删除任何不在其中的\n\n    //查找-这是我们丢弃的碎片\n\n    const aSimBodies =文档.querySelectorAll (.\"a-sim卡-body\")\n\n    for (i = 0; i  {\n\n      //找到这个框架id的html元素\n\n      body = document.getElementById(身体.aframeId)\n\n      //如果没有找到html元素,创建一个.\n\n      if (!一体的){\n\n        这.htmlElement.innerHTML += '\n\n\n\n`\n\n        body = document.getElementById(身体.aframeId)\n\n      }\n\n      / /复位\n\n      一体的.object3D.位置.集(身体.x,身体.y,身体.z)\n\n    })\n\n}\n\n
\n\n

第一个, 我们循环遍历模拟体以标记和/或创建查找表,以便将a - frame实体与模拟体相匹配.

\n\n

下一个, 我们循环遍历现有的人字形体,并删除任何因出界而被模拟修剪过的物体. 这将提高体验的感知性能.

\n\n

最后,我们循环模拟主体来创建一个新的 寻找失踪的尸体并重新定位其他尸体 一体的.object3D.位置.集(身体.x,身体.y,身体.z)

\n\n

我们可以使用标准DOM函数以编程方式改变人字形场景中的元素. 为了在场景中添加一个元素,我们向容器的innerHTML添加一个字符串. 这段代码对我来说味道很奇怪,但它有效,我没有找到更好的.

\n\n

您将注意到,当我们创建要追加的字符串时, 我们在“星号”附近有一个三元运算符来设置属性.

\n\n
\n\n\n`\n\n
\n\n

如果主体是“星型”,我们添加一些描述其事件的额外属性. 下面是我们的星形在DOM中加载时的样子:

\n\n
\n\n\n
\n\n

三个属性, debris-listener, event-set__enterevent-set__leave,建立我们的互动,是我们融合的最后一圈.

\n\n

定义人字形事件和交互

\n\n

我们使用 NPM package " frame-event-set-component " 在实体的属性中改变查看者“看着”太阳时太阳的颜色.

\n\n

这种“凝视”是从观看者的位置和旋转中投射出来的, 这种互动提供了必要的反馈,表明他们的目光在做一些事情.

\n\n

我们的星球现在有两个由插件启用的简短事件, event-set__enterevent-set__leave:

\n\n
\n\n\n
\n\n

接下来,我们用一个装饰我们的星球 debris-listener 我们将实现为一个自定义的a - frame组件.

\n\n
\n\n\n
\n\n

人字形组件是在全局级别定义的:

\n\n
\n/ / src / nBodyVisualizer.js\n\n//组件,当用户盯着太阳时添加新的物体. 看到HTML\n\nAFRAME.registerComponent (debris-listener, {\n\n  Init: function () {\n\n    //辅助函数\n\n    函数随机(缩放){返回(数学.随机()-.5) *刻度}\n\n    //添加10个新主体\n\n    这.el.addEventListener('click', function (evt) {\n\n      for (let x=0; x<10; x++) {\n\n        // name, color, x, y, z, mass, vx, vy, vz\n\n        窗口.sim卡.addBodyArgs(\"debris\", \"white\", r和o(10), r和o(10), r和o(10), 1, r和o(.1)、金兰(.1)、金兰(.1))\n\n      }\n\n    })\n\n  }\n\n})\n\n
\n\n

这个a - frame组件就像一个“点击”监听器,可以由凝视光标触发,为我们的场景添加10个新的随机物体.

\n\n

总结:

\n\n
    \n
  1. 我们在标准HTML中声明带有人字形的WebVR场景.
  2. \n
  3. 我们可以通过JavaScript在场景中添加/删除/更新人字形实体.
  4. \n
  5. 我们可以通过人字形插件和组件在JavaScript中创建与事件处理程序的交互.
  6. \n
\n\n

Veni, Vidi, Vici

\n\n

我希望你从这次技术演示中得到和我一样多的收获. 我们将这些特性(web workers和WebAssembly)应用到WebVR的哪些地方, 它们也可以应用于浏览器边缘计算.

\n\n

一股巨大的技术浪潮已经到来——虚拟现实(VR). 你第一次拿着智能手机的感觉, 第一次体验虚拟现实可以在计算的各个方面提供10倍的情感体验. 从第一代iPhone到现在才过去了12年.

\n\n

VR的历史要长得多, 但将VR带给普通用户所需的技术是通过移动革命和Facebook的Oculus Quest来实现的,而不是PC革命.

\n\n

互联网和开源是人类最伟大的奇迹之一. 对于所有创造扁平化互联网的人们,我要为你们的勇气和冒险精神干杯.

\n\n

宣言! 我们将建造世界,因为我们有创造的能力.

\n\n

\"WebVR演示\"
Canvas demo, WebVR demo, Example Code\n

\n","as":"div","isContentFit":true,"sharingWidget":{"url":"http://d4w2lrix.ubuildnow.com/virtual-reality/webvr-design-and-implementation","title":"WebVR第5部分:设计和实现","text":null,"providers":["linkedin","推特","脸谱网"],"gaCategory":null,"domain":{"name":"developers","title":"工程","vertical":{"name":"developers","title":"开发人员","publicUrl":"http://d4w2lrix.ubuildnow.com/developers"},"publicUrl":"http://d4w2lrix.ubuildnow.com/developers/blog"},"hashtags":"WebVR,WebAssembly,AssemblyScript"}}