WebVR 概念
注意: WebVR API 已被 WebXR API 取代。WebVR 从未被批准为标准,在少数浏览器中默认实现和启用,并支持少量设备。
本文讨论了虚拟现实 (VR) 背后的一些概念和理论。如果您是该领域的新手,在开始深入代码之前,了解这些主题是值得的。
VR 的历史
虚拟现实并不是什么新鲜事物——这个概念比 2012 年的 Oculus Rift Kickstarter 众筹活动要早得多。人们已经进行了数十年的实验。
1939 年,View-Master 设备被创造出来,让人们能够看到 3D 图片。该设备显示存储在硬纸板盘上的图像,其中包含小型彩色照片的立体 3D 对。经过多年的发展,军方对使用这种技术产生了兴趣,1961 年,Project Headsight 诞生了——这涉及一个头盔,其中包含一个带有头部追踪系统的视频屏幕。
在接下来的几十年里,进行了各种实验,但它不再局限于科学实验室和战场。最终,流行文化接管了它,电影导演展示了他们对虚拟现实的愿景。诸如《创战纪》(1982) 和《黑客帝国》(1999) 等电影被创作出来,人们可以将自己转移到一个全新的网络世界,或者被困在一个世界中却毫不知情,将其视为真实世界。
最早的 VR 游戏尝试规模庞大且价格昂贵——1991 年,Virtuality Group 创造了一台配备护目镜的 VR 街机,并将《吃豆人》等流行游戏移植到虚拟现实中。世嘉在 1993 年的消费电子展上推出了他们的 VR 眼镜。公司正在进行实验,但市场和消费者并不买账——我们不得不等到 2012 年才看到一个成功的 VR 项目的真实案例。
近期的 VR
那么有什么新鲜事呢?虚拟现实硬件需要提供高精度、低延迟的数据以提供可接受的用户体验;运行 VR 应用程序的计算机需要足够强大才能处理所有这些信息。直到最近,这种精度和功能才以可承受的成本提供,如果能提供的话。早期的 VR 原型成本数万美元,而最近的头戴式设备,如 HTC VIVE 和 Meta Quest,仅售数百美元,并且还有更便宜的解决方案——例如基于移动设备的解决方案,如 Google Cardboard。
在软件方面,Valve 已经创建了 SteamVR 软件,该软件与 VIVE 和其他解决方案兼容,并用于提供对软件的访问,例如可用的 VR UI。
这项技术本身已经存在,更昂贵的头戴式设备只会随着时间的推移而变得更便宜,这样将来会有更多的人能够亲身体验虚拟现实。
输入设备
处理虚拟现实应用程序的输入是一个有趣的话题——这是一种全新的体验,需要为此设计专门的用户界面。目前有各种方法,从经典的键盘和鼠标,到 Leap Motion 和 VIVE 控制器等新方法。这需要反复试验,才能了解在特定情况下什么有效,以及哪种输入最适合您的游戏类型。
VR 硬件设置
有两种主要的设置类型,移动设备或计算机连接。它们的最低硬件设置如下:
- 移动设备:使用智能手机创建头戴式显示器(HMD),智能手机充当 VR 显示器,安装在 VR 支架(如 Google Cardboard)中,该支架包含所需的镜头,可提供移动屏幕上投影内容的立体视觉。

- 计算机连接:VR 设置连接到您的计算机——这包括一个头戴式显示器(HMD),其中包含一个高分辨率横向屏幕,用于显示左右眼的视觉效果,该显示器还包括每个眼睛的镜头,以促进左右眼场景的分离(立体视觉)。该设置还包括一个单独的位置传感器,用于计算头部的位置/方向/速度/加速度,并不断将该信息传递给计算机。

注意:连接电脑的系统有时不包括位置传感器,但通常会包括。
补充 VR 体验的其他硬件包括:
- 手部识别传感器:一种跟踪手部位置和运动的传感器,使其成为一个有趣的控制器,并成为 VR 游戏世界中的一个物体。迄今为止最先进的是 Leap Motion,它可与计算机(连接到 Oculus Rift)配合使用,也可以连接到移动设备(后者处于实验阶段)。
- 游戏手柄:我们可以配置 Xbox 控制器或类似的设备,使其在浏览器中充当键盘——这为与 VR 网页的交互提供了更多可能性。有些游戏手柄可与移动设备设置配合使用,但它们通过蓝牙连接,因此无法与 WebVR 配合使用。
- 眼动追踪传感器(实验性):FOVE 项目是第一款能够读取细微眼部运动的头戴式设备。
- 面部表情追踪器(实验性):南加州大学和 Facebook 的 Oculus 部门的研究人员一直在测试追踪面部表情并将其传输到虚拟角色的新方法。
- 更复杂的定位传感器系统:例如,HTC VIVE 配备了两个定位传感器,位于空间的两端对角,绘制出整个空间,并允许在最大 5 米 x 5 米的空间中享受 VR 体验。
位置和方向、速度和加速度
如上所述,位置传感器检测 HMD 的相关信息并不断输出,使您能够根据头部运动、旋转等持续更新场景。但这些信息究竟是什么?

输出信息分为四类:
-
位置 — HMD 在 3D 坐标空间中沿三个轴的位置。x 表示左右,y 表示上下,z 表示朝向和远离位置传感器。在 WebVR 中,x、y 和 z 坐标由
VRPose.position中包含的数组表示。 -
方向 — HMD 在 3D 坐标空间中绕三个轴的旋转。俯仰角是绕 x 轴的旋转,偏航角是绕 y 轴的旋转,滚转角是绕 z 轴的旋转。在 WebVR 中,俯仰角、偏航角和滚转角由
VRPose.orientation中包含的数组的前三个元素表示。 -
速度 — 在 VR 中需要考虑两种类型的速度:
- 线性 — HMD 沿任何一个轴移动的速度。此信息可以使用
VRPose.linearVelocity访问。 - 角速度 — HMD 绕任何一个轴旋转的速度。此信息可以使用
VRPose.angularVelocity访问。
- 线性 — HMD 沿任何一个轴移动的速度。此信息可以使用
-
加速度 — 在 VR 中需要考虑两种类型的加速度:
- 线性 — HMD 沿任何一个轴移动的加速度。此信息可以使用
VRPose.linearAcceleration访问。 - 角加速度 — HMD 绕任何一个轴旋转的加速度。此信息可以使用
VRPose.angularAcceleration访问。
- 线性 — HMD 沿任何一个轴移动的加速度。此信息可以使用
视野
视野 (FOV) 是用户每只眼睛可以合理期望看到的区域。它大致呈金字塔形,侧卧,顶点在用户头部内部,金字塔的其余部分从用户眼睛发出。每只眼睛都有自己的 FOV,一个略微重叠另一个。

FOV 由以下值定义:
VRFieldOfView.upDegrees:视野向上延伸的度数。VRFieldOfView.rightDegrees:视野向右延伸的度数。VRFieldOfView.downDegrees:视野向下延伸的度数。VRFieldOfView.leftDegrees:视野向左延伸的度数。- zNear,由
VRDisplay.depthNear定义:从用户头部中心到可见 FOV 起始点的距离。 - zFar,由
VRDisplay.depthFar定义:从用户头部中心到可见 FOV 结束点的距离。
这些属性的默认值会因 VR 硬件而略有不同,但它们通常都在上下约 53°,左右约 47° 左右,zNear 和 zFar 分别约为 0.1 米和 10000 米。
注意:用户有可能看到周围的一切,这对于应用程序和游戏来说是一个全新的概念。尝试给人们一个环顾四周并查看他们身后事物的理由——让他们伸出手去寻找一开始不可见的事物。描述他们身后有什么。
VR 应用程序的概念
本节讨论了在开发 VR 应用程序时需要注意的概念,这些概念在开发常规移动或桌面应用程序时可能从未考虑过。
立体视觉
立体视觉是人类和(大多数)动物正常的视觉——将两个略有不同的图像(每只眼睛一个)感知为单个图像。这会产生深度感知,帮助我们以绚丽的 3D 方式看世界。要在 VR 应用程序中重现这一点,您需要并排渲染两个非常略有不同的视图,当用户使用 HMD 时,左右眼将接收这些视图。

头部追踪
由于 HMD 中包含的陀螺仪、加速度计和磁力计(指南针),使您感觉身临其境的 360 度场景中的主要技术。它具有主要相关性,因为它使我们的眼睛相信我们正对着一个球形屏幕,从而使用户在应用程序画布内获得逼真的沉浸感。
眼疲劳
一个在 VR 中常用的术语,因为它使用 HMD 的一个主要障碍——我们不断地用我们在应用程序画布中显示的内容欺骗眼睛,这导致眼睛比平时做更多的工作,因此长时间使用 VR 应用程序会导致眼疲劳。
为了尽量减少这种不良影响,我们需要:
- 避免聚焦于不同深度(例如,避免使用大量具有不同深度的粒子)。
- 避免眼睛会聚(例如,如果有一个物体向相机移动,您的眼睛会跟随并会聚到它身上)。
- 尽可能使用较暗背景和较柔和的颜色;明亮的屏幕会使眼睛更容易疲劳。
- 避免亮度快速变化。
- 避免向用户呈现大量文本阅读。您还应该注意眼睛/相机与要阅读的文本之间的距离。0.5 米不舒服,而超过 2 米立体效果开始减弱,因此建议介于两者之间。
- 通常要注意物体与相机之间的距离。Oculus 建议最小聚焦距离为 0.75 米。
- 如果用户需要与场景中的物体进行交互,请使用指针——这将帮助他们以较少的精力正确指向物体。
一般来说,最省力的视觉路径将为用户带来更轻松的体验。
晕动病
如果开发者不格外小心,VR 应用程序实际上可能会导致用户感到恶心。这种效应发生在眼睛接收到的刺激与身体预期接收的刺激不符时。
为了避免让我们的用户产生晕动症(或至少最大限度地减少影响),我们需要:
- 始终保持头部追踪(这是最重要的,尤其是在体验过程中发生)。
- 使用恒定速度;避免加速或减速相机运动(使用线性加速度,如果可以的话避免缓动)。
- 保持帧率(低于 30fps 会不舒服)。
- 避免急剧和/或意外的相机旋转。
- 为固定物体添加固定的参照点(否则用户会认为它们正在移动)。
- 不要使用景深或运动模糊后期处理,因为您不知道眼睛将聚焦在哪里。
- 避免亮度变化(使用低频纹理或雾效果来创建平滑的照明过渡)。
总的来说,您的眼睛不应向大脑发送导致身体其他部位产生反射动作的信号。
延迟
延迟是指物理头部运动与 HMD 屏幕更新后视觉显示到达用户眼睛之间的时间。这是提供逼真体验最重要的因素之一。人类可以检测到非常小的延迟——如果它们要不被人察觉,我们需要将延迟保持在 20 毫秒以下(例如,60Hz 显示器有 16 毫秒的响应时间)。
Oculus Rift 头戴式设备的延迟为 20 毫秒或更短,但基于移动设备的设置将严重依赖智能手机 CPU 功率和其他功能。
帧率 (每秒帧数 / FPS)
根据维基百科的定义,帧率是成像设备产生独特连续图像(称为帧)的频率。60fps 的帧率是平滑用户体验的可接受帧率,但根据运行应用程序的机器性能或您要显示的内容的复杂性,它可能会急剧下降。低于 30fps 通常被认为是卡顿的,并会给用户带来烦恼。
最困难的任务之一是保持恒定且高的帧率值,因此我们必须优化代码,使其尽可能高效。最好有一个不会持续或突然变化的体面帧率;为此,您需要尽可能少地让必要的对象进入场景,并(在 WebGL 的情况下)尝试减少绘制调用。
瞳距 (IPD)
根据维基百科的定义,瞳距是两只眼睛瞳孔中心之间的距离。瞳距对于双目观察系统的设计至关重要,其中两只眼睛的瞳孔都需要定位在观察系统的出瞳孔内。
在 WebVR 中,瞳距 (IPD) 可以使用 VREyeParameters.offset 计算,它等于 IPD 的一半。
此值由 HMD 返回,其值可能在 60 到 70 毫米之间;对于某些 HMD(如 Oculus Rift),您可以设置自己的 IPD。通常我们不更改此值,但您可以调整它以更改整个场景的比例。例如,如果您的 IPD 设置为 6000 毫米,用户将像巨人俯瞰小人国一样观看场景。
自由度 (DoF)
DoF 指刚体在空间中的运动。为此术语创建缩写没有统一性——我们可以在仅检测旋转头部跟踪的传感器上下文中找到 3DoF 的引用,当输入允许我们同时控制位置和方向时,可以找到 6DoF。我们甚至有时会发现 9DoF 的引用,当硬件包含陀螺仪、加速度计和磁力计等三个传感器时,但 3 x 3DoF 值的结果实际上将返回 6 自由度跟踪。
DoF 与用户头部运动的跟踪直接相关。
聚焦锥体
尽管我们的视野要大得多(大约 180 度),但我们需要注意,只有在该视野的一小部分中才能感知符号(中心 60 度)或阅读文本(中心 10 度)。如果您没有眼动追踪传感器,我们假设屏幕中心是用户眼睛聚焦的地方。
在决定将视觉效果放置在应用程序画布上的位置时,此限制很重要——如果离聚焦锥体的边缘太远,可能会更快导致眼睛疲劳。
3D 定位音频
3D 定位音频是指一组操作音频以模拟其在三维空间中听起来的效果。
这与 Web 音频 API 直接相关,该 API 允许我们将在画布中的对象上放置声音,或根据用户正在前往或正在查看的场景部分启动音频。