有人认为虚拟现实将在 2020 年达到 70 亿美元的价值。在那之前,web 肯定不会一直停留于 2d 环境。实际上,已经有一些简单的方法可以将虚拟现实带进浏览器了。而且那弄起来也非常有趣!
要开始你的虚拟 web 开发之旅,有这么三种可行的方式:
我会将每一种方式都过一遍,简要展示下它们各自是如何工作的。
当前,大多数基于浏览器的虚拟现实项目都是利用浏览器的 deviceorientation 事件。此事件告诉浏览器设备的朝向,而且允许浏览器在设备旋转或倾斜时有所动作。从虚拟现实的角度看,此功能允许你侦测到某人看向某个方向,然后你可以调整摄像头以跟随他的视线。
为了在浏览器里获得良好的 3d 场景,我们使用一个可以方便地创建 3d 形状和场景的 javascript 框架three.js。它封装了创建 3d 内容的大部分复杂性,让你可以专注于把你希望的东西放进你的场景。
我在 sitepoint 上写过两个使用设备朝向方法的示例:
如果你不熟悉 three.js 和组建场景,我推荐你看一下上面的两篇文章以更深入的理解此方法。我将只大致介绍下主要概念。
下面是要用到的关键 javascript 文件(你可以从上面的示例中获取,也可以 从three.js 例子下载):
使用设备朝向控制的代码大致如下:
在可用设备上,设备朝向事件监听器提供一组 alpha,beta 和 gamma 值。如果没有 alpha 值就不能通过设备朝向进行控制,转而替代的是轨道控制。
如果有 alpha 值,那么我们就可以使用设备朝向控制摄像头。如果用户轻击屏幕,我们还可将场景在全屏模式下呈现(我们可不想在虚拟现实下看到浏览器地址栏)。
如果 alpha 值不存在,我们也就不可以访问设备的定位事件,这替代了通过摄像头拖拽鼠标的技术。这看起来就像这样:
主要可能混乱的代码是上面的 nopan 和 nozoom。基本上,我们不需要通过鼠标移动身体的场景,我们也不希望能够放大或缩小 —— 我只是想环视。
为了使用立体效果,我们先这么定义:
然后再窗口重设尺寸时,相应更新它的尺寸:
在每次 requestanimationframe 的时候,使用效果渲染场景:
以上便是使用设备朝向方法达到虚拟现实的基本方法。这种方法对于简易的 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 可以让你通过如下方式访问虚拟现实设备:
我不会在这里讲太多细节(在之后 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 了。
要把此项目加到你自己的草稿上,你需要这些文件:
实现它仅需要稍微调整下设备朝向方法。以下是给想尝试的朋友的一份综述:
vr 控制器是很容易创建的,我们只需要通过创建一个 vrcontrols 对象给我们之前使用的 controls 变量就可以了。由于 boilerplate 目前应该注意浏览器没有 vr 功能,因此轨迹控制器和设备方式控制器不是必须的。这意味着你的动画应该依然在 google cardboard 上能够很好的运行
effect 是非常类似于实现了 stereoeffect 类的类。只不过用新的 vreffect 类替换了原来的:
然而,在这个方法里我们不会通过 effect 渲染,而是,通过我们的 vr 管理器来渲染。
vr 管理器关注我们所有进入或退出 vr 等等诸如此类的,因此这是我们的场景最终渲染的地方。我们通过下面的方式初始化管理器:
如果vr管理器在一个可兼容的浏览器里,那么它会提供一个可以让我们进入vr 模块的按钮,如果它们的浏览器不支持 vr,那么进入全屏(全屏是我们为移动端准备的)。hidebutton 参数表示我们是否想隐藏按钮或不隐藏按钮,我们定义为不隐藏!
我们像这样去调用渲染,它使用的 timestamp 变量是来自 three.js 的 update() 方法:
在所有的地方,你都应该让 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 的元素需要为两个视角分别渲染,以达到虚拟现实:
如果你知道任何使用虚拟现实和 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 上的文章等。如果你有其他不错的而我没列出的资源,也请告知我!