有人认为虚拟现实将在 2020 年达到 70 亿美元的价值。在那之前,web 肯定不会一直停留于 2D 环境。实际上,已经有一些简单的方法可以将虚拟现实带进浏览器了。而且那弄起来也非常有趣!
要开始你的虚拟 Web 开发之旅,有这么三种可行的方式:
JavaScript,Three.js 和监视设备朝向
JavaScript,Three.js 和 WebVR(我最近比较喜欢的方式)
CSS 和 WebVR(时日尚早)
我会将每一种方式都过一遍,简要展示下它们各自是如何工作的。
当前,大多数基于浏览器的虚拟现实项目都是利用浏览器的 deviceorientation 事件。此事件告诉浏览器设备的朝向,而且允许浏览器在设备旋转或倾斜时有所动作。从虚拟现实的角度看,此功能允许你侦测到某人看向某个方向,然后你可以调整摄像头以跟随他的视线。
为了在浏览器里获得良好的 3D 场景,我们使用一个可以方便地创建 3D 形状和场景的 JavaScript 框架 three.js 。它封装了创建 3D 内容的大部分复杂性,让你可以专注于把你希望的东西放进你的场景。
我在 SitePoint 上写过两个使用设备朝向方法的示例:
Bringing VR to the Web with Google Cardboard and Three.js (使用谷歌 Cardboard 和Three.js实现基于Web的虚拟现实)
Visualizing a Twitter Stream in VR with Three.js and Node (使用 Three.js 和 Node 可视化Twitter 流)
如果你不熟悉 three.js 和组建场景,我推荐你看一下上面的两篇文章以更深入的理解此方法。我将只大致介绍下主要概念。
下面是要用到的关键 JavaScript 文件(你可以从上面的示例中获取,也可以 从 three.js 例子 下载):
three.min.js– three.js 框架
DeviceOrientationControls.js– 这是一个 three.js 插件,它帮助我们完成之前提到过的监视设备朝向,可以另摄像头根据设备的移动进行调整。
OrbitControls.js– 这是一个备用的控制器,它可以在没有设备朝向事件的时候用鼠标调整摄像头。
StereoEffect.js– 这是一个 three.js 的效果插件,可以针对每只眼睛对画面进行细微的角度调整,就像虚拟现实该有的立体效果。这使得我们不用做任何复杂的工作,就可以创造实打实的虚拟现实分屏效果。
使用设备朝向控制的代码大致如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | |
在可用设备上,设备朝向事件监听器提供一组 alpha,beta 和 gamma 值。如果没有 alpha 值就不能通过设备朝向进行控制,转而替代的是轨道控制。
如果有 alpha 值,那么我们就可以使用设备朝向控制摄像头。如果用户轻击屏幕,我们还可将场景在全屏模式下呈现(我们可不想在虚拟现实下看到浏览器地址栏)。
如果 alpha 值不存在,我们也就不可以访问设备的定位事件,这替代了通过摄像头拖拽鼠标的技术。这看起来就像这样:
1 2 3 4 5 6 7 8 | |
主要可能混乱的代码是上面的 noPan 和 noZoom。基本上,我们不需要通过鼠标移动身体的场景,我们也不希望能够放大或缩小 —— 我只是想环视。
为了使用立体效果,我们先这么定义:
1 | |
然后再窗口重设尺寸时,相应更新它的尺寸:
1 | |
在每次 requestAnimationFrame 的时候,使用效果渲染场景:
1 | |
以上便是使用设备朝向方法达到虚拟现实的基本方法。这种方法对于简易的 Google Cardboard 实现效率还可以,但在 Oculus Rift 上就不是太高效了。下面要介绍的方法在 Rift 上表现得要好得多。
对像是 Oculus Rift 这样的头戴式虚拟设备的朝向感兴趣?WebVR 是当前可行的方法。 WebVR 是一种先锋的实验性质的 JavaScript 的 API,它提供访问 Oculus Rift 和 Google Cardboard 等虚拟设备的能力。当前,它在 Firefox Nightly 和一些 experimental builds of Mobile Chrome and Chromium 上可用。需要记住的一点是,WebVR 的细节依然在草稿阶段且随时可能会改变,所以可以拿它做一些实验,而且过些时候你可能需要做一些调整。
总之,WebVR API 可以让你通过如下方式访问虚拟现实设备:
1 | |
我不会在这里讲太多细节(在之后 SitePoint 上的文章中我会讲更多细节的东西),如果你对细节感兴趣的话可以看看 the WebVR editor’s draft 。我不讲细节的原因是有更简单的方法实现 API。
上面说的更简单的实现 WebVR API 的方法是使用 WebVR Boilerplate from Boris Smus 。在不同的设备上,它可以保证基本的 WebVR 功能,同时考虑到用户体验上的优雅降级。它是我至今经过的最好的 web 虚拟现实实现。如果你在找寻基于 web 的虚拟现实实现方案,这便是当前最好的选择。
要开始使用此方法,先下载 WebVR Boilerplate on Github 。
你可以使用其中的文件,专心编辑 index.html,或者你也可以从草稿开始实现特定的插件。如果你想比较两者的区别,我已经把上面提过的 Visualizing a Twitter Stream in VR with Three.js and Node 迁移到 WebVR powered Twitter Stream in VR 了。
要把此项目加到你自己的草稿上,你需要这些文件:
three.min.js – 当然是我们的 three.js 框架
VRControls.js – 一个 three.js 插件,用于通过 WebVR 进行虚拟现实的控制 (可以从样板项目找到 bower_components/threejs/examples/js/controls/VRControls.js)
VREffect.js – 一个 three.js 插件,用于在 Oculus Rift 上显示虚拟现实效果的画面(可以从样板项目找到 bower_components/threejs/examples/js/effects/VREffect.js)
webvr-polyfill.js – 这是一个用于对 WebVR 支持不完善的浏览器的填充工具(可以从 GitHub 上找到,或者从样板项目找到 bower_components/webvr-polyfill/build/webvr-polyfill.js)
webvr-manager.js – 这是样板代码的一部分,它管理所有的东西,包括提供进入和离开虚拟现实模式的方法(可以从 build/webvr-manager.js 找到)
实现它仅需要稍微调整下设备朝向方法。以下是给想尝试的朋友的一份综述:
VR 控制器是很容易创建的,我们只需要通过创建一个 VRControls 对象给我们之前使用的 controls 变量就可以了。由于 Boilerplate 目前应该注意浏览器没有 VR 功能,因此轨迹控制器和设备方式控制器不是必须的。这意味着你的动画应该依然在 Google Cardboard 上能够很好的运行
1 | |
Effect 是非常类似于实现了 StereoEffect 类的类。只不过用新的 VREffect 类替换了原来的:
1 2 | |
然而,在这个方法里我们不会通过 Effect 渲染,而是,通过我们的 VR 管理器来渲染。
VR 管理器关注我们所有进入或退出 VR 等等诸如此类的,因此这是我们的场景最终渲染的地方。我们通过下面的方式初始化管理器:
1 | |
如果VR管理器在一个可兼容的浏览器里,那么它会提供一个可以让我们进入VR 模块的按钮,如果它们的浏览器不支持 VR,那么进入全屏(全屏是我们为移动端准备的)。hideButton 参数表示我们是否想隐藏按钮或不隐藏按钮,我们定义为不隐藏!
我们像这样去调用渲染,它使用的 timestamp 变量是来自 three.js 的 update() 方法:
1 2 3 4 | |
在所有的地方,你都应该让 VR 根据设备的不同而转化它本身的实现。
Isrenderer.getSize() 返回一个错误?这让我抓狂了几个小时,但是要想修改这个错误——更新 three.js!
这是我在 Twitter 上的例子的视图在支持 VR 的浏览器上的样子:
这是在 Oculus Rift 视图里当你点击 VR 图标时的样子:
这是在手机上的样子,设备方向仍然允许我们旋转场景,但是我没有截屏。一个很好的满足响应试的视图:
如果我们在手机上点击VR图标,我们就能得到为 Google Cardboard 样式设备提供的全屏视图:
Mozilla 计划将虚拟现实呈现能力也加到旗下的 Firefox 浏览器 Nightly 版本中,当然当前还处于非常早起的阶段!我运气不是太好,没能在我的 Mac 和 Oculus 设备上让其工作。来自 Firefox 的 Vladimir Vukićević 承诺将 CSS 3D 变换整合进虚拟现实全屏模式。
Vladimir 的博客中有个示例,指出标记了 transform-style: preserve-3d 的元素需要为两个视角分别渲染,以达到虚拟现实:
1 2 3 4 5 6 7 8 9 | |
如果你知道任何使用虚拟现实和 CSS 的示例,请告知我!我还没发现任何相关的。将 web 中的 HTML 和 CSS 用到虚拟现实,这个主意无疑是个有趣的概念。真是不可思议,web 就要进入虚拟现实的国度,我们慢慢开始接触虚拟现实设备!
在接下来几年里,技术世界将缓慢但切实地拥抱虚拟现实,前提是我们的技术跟得上我们的野心!促进虚拟现实的普及与价值的内容。我们得为用户准备好可以享用的虚拟现实内容!有比 web 更好更简单的方式吗?
如果你感兴趣并且用这些代码构建了一个虚拟现实示例,请在评论中分享或者在Twitter( @thatpatrickguy )上联系我。我很乐意把它放到我的 Oculus Rift 或 Google Cardborad 上瞧一瞧!
我收集了一堆关于通过 JavaScript 实现虚拟现实和增强现实的链接,权当大家一个参考。到 Dev Diner 看看我的 Dev Diner VR and AR with JavaScript Developer Guide ,它囊括了这篇文章中提及的链接,以及其它 SitePoint 上的文章等。如果你有其他不错的而我没列出的资源,也请告知我!