Chapter 7 AR/VR 优化
虚拟现实(VR)和增强现实(AR)是两种新兴的娱乐媒介。VR 通过头戴显示器(HMD)把用户带入虚拟空间;AR 则把虚拟元素叠加到现实世界的画面上。为了简洁,这两者常被合称为 扩展现实(XR)。此外还有混合现实(MR/HR),把真实与虚拟世界混合在一起。
Unity 很早就支持了主流 XR 平台,如 Google Cardboard、HTC VIVE、Oculus Rift、Microsoft HoloLens、Samsung Gear VR,以及较新的 Apple ARKit、Google ARCore、Windows Mixed Reality、Vuforia、PlayStation VR 等。
XR 技术概览
XR 为开发者和创作者开辟了全新的领域,包括游戏、360 度视频、3D 建模工具、工作流可视化等。由于规则尚未定型,创新空间巨大。但新技术通常遵循 Gartner 技术成熟度曲线:先被过度炒作,随后进入幻灭低谷,再逐步成熟。XR 近年来正逐步走向成熟,但普及速度低于最初的预期。
开发 XR 产品有一定风险:平台和技术变化快,SDK 更新、API 变更、兼容性问题、性能问题、渲染瑕疵、平台间功能不一致等都很常见。但反过来看,大家都在面对同样的问题,Unity 和各平台开发者也在不断改进工具链。
XR 产品对性能尤为敏感,原因有三:
- 用户投入成本高:VR 头显、传感器或 AR 设备价格不菲,用户对质量期望更高。
- 身体不适风险:VR 中帧率不足会导致用户眩晕、恶心、眼疲劳、头痛,甚至摔倒受伤。
- 沉浸感易被打破:掉帧、闪烁或应用崩溃会迅速破坏沉浸体验。
因此,XR 项目必须尽早进行性能分析,确保不会超出运行预算。
开发 XR 产品
在 Unity 中开发 XR 产品需要导入对应的 SDK,并在运行时调用专门的 API。Unity 从 2017.2 起把 UnityEngine.VR 重命名为 UnityEngine.XR,以支持更多 AR SDK。目前 Unity XR 系统正在从旧版模型向基于 Package Manager 的新模型过渡。许多 SDK(如 ARKit、HoloLens)需要通过 **Window | Package Manager** 安装。 |
用户舒适度
VR 应用必须把用户舒适度作为优化指标。常见的不适包括:
- 晕动症(Motion sickness):眼睛感知到的运动与内耳平衡感不一致。
- 眼疲劳(Eye strain):屏幕离眼睛很近,长时间使用容易导致头痛。
- 定向障碍(Disorientation):在狭小空间内站立时,若游戏存在加速运动,用户会本能地调整平衡,可能摔倒。
注意:加速度是矢量,包含大小和方向。任何方向的加速(前后、左右、旋转、跳跃、下落)都可能引发不适。
另一个风险是诱发癫痫。VR 近距离闪烁画面可能触发易感人群癫痫发作,需要尽早测试和修复。
帧率目标
VR 应用最重要的性能指标是高帧率,最好达到 90 FPS 或更高。高帧率能让头部运动与世界运动之间的延迟非常小,减少不适。任何持续掉帧都会带来问题。
同时要小心控制视角:
- 不要自行改变 HMD 的视野方向,让用户自己决定朝向。
- 避免长时间加速运动。
- 避免不受控制的世界旋转和地平线移动。
- 绝对不要在最终产品中对 HMD 的位置追踪施加增益、倍率或加速效果。用户头部移动两英寸,应用中也应移动相同的相对距离,并在头部停止时立即停止。
如果玩家角色需要加速,应尽量短促快速,然后回到恒定速度或瞬移(teleportation)。赛车游戏中的倾斜弯道通常更舒适,因为用户会自然倾斜头部匹配转弯。
360 视频
360 视频同样适用上述规则。可惜的是,市场上很多 360 视频没有充分考虑舒适度:画面抖动、缺乏稳定、手动旋转视角等都会引发恶心。应通过引导用户注意力(如让画面角落有物体移动,吸引用户转头)来替代强制旋转。
360 视频本身的帧率(如 24 FPS 或 29.97 FPS)对舒适度的影响相对较小,但渲染帧率必须保持很高,以确保头部追踪流畅。
AR 舒适度
AR 的不适感通常不如 VR 明显,但也不能忽视。AR 应用资源消耗大,低帧率会让背景相机画面与叠加虚拟对象之间产生帧率脱节,应尽量同步这两者的帧率。
XR 性能增强
XR 应用本质上与普通 Unity 游戏使用相同的引擎、子系统、资源、工具,因此本书中提到的几乎所有通用性能优化技术都能帮助 XR 应用。但 XR 有一些特殊考量:
- VR 最大的威胁是 GPU Fill Rate,因为场景需要为两只眼睛各渲染一次,目标帧缓冲更大。
- AR 通常同时消耗大量 CPU 和 GPU:GPU 并行处理空间定位、图像识别等任务,同时需要大量 draw call。
- 某些技术在 XR 中效果有限:VR 中用户可能从各种角度观察物体,遮挡剔除设置较复杂;AR 中物体通常在可触及距离,LOD 收益不大。
因此,在投入 XR 专属优化之前,应先应用通用优化技术。
Single Pass 与 Multi Pass 立体渲染
VR 中 Unity 提供三种立体渲染模式:
- Multi Pass:为每只眼分别渲染一次,是默认方式。
- Single Pass:把左右眼图像合并到一张双倍宽度的渲染纹理中,每只眼只看到对应的一半。这样可以显著减少主线程 CPU 工作和 GPU 纹理交换,但每只眼仍需从各自视角渲染物体。
- Single Pass Instanced:实验性模式,利用 GPU Instancing 技术,只需一次 draw call 就让 GPU 把同个网格绘制到两个不同位置,CPU 收益更大。但自定义 shader 必须支持 GPU Instancing。
Single Pass 对传统屏幕空间后处理效果有影响:shader 不能再假设屏幕空间坐标对应整个屏幕,而是对应整张双倍宽纹理。后处理 shader 必须正确渲染到输出纹理的左半或右半部分,否则会出现画面拉伸。
配置路径:
- 旧版:
Edit | Project Settings | Player | XR Settings | Stereo Rendering Method - 新版 XR Plugin Management:
Edit | Project Settings | XR Plugin Management
抗锯齿
抗锯齿对 XR 项目几乎是必需的。它能显著减少锯齿、提高沉浸感,但会消耗大量 Fill Rate。应尽早开启,并把性能目标建立在开启抗锯齿的前提下,只在万不得已时关闭。
使用前向渲染
延迟渲染适合多光源场景,但如果同时开启抗锯齿,抗锯齿必须作为屏幕空间后处理实现,这会消耗大量性能。相比之下,前向渲染可以把抗锯齿作为多重采样效果应用,可能反而更高效。
VR 中的图像效果
法线贴图在 VR 中容易“穿帮”:当用户通过位置追踪靠近物体、以很斜的角度观察表面时,法线贴图看起来就像画在表面上,没有深度感。法线贴图对高多边形模型有提升,但对低多边形模型帮助有限。需要测试视觉改善是否值得内存带宽开销。
更好的选择是 置换贴图(Displacement Map)、曲面细分 或 视差贴图(Parallax Mapping),但这些技术更昂贵。
景深、模糊、镜头光晕等后处理效果在普通 3D 游戏中效果不错,但在 VR 中通常显得不自然(至少在眼动追踪普及之前),应尽量避免。
背面剔除
VR/AR 中玩家可能从任何方向观察靠近相机的物体。如果物体不是完全闭合的形状,玩家可能看到不应该看到的内容,破坏沉浸感。因此靠近相机的资源应尽量做成封闭形状。对于远处物体,若用户可能通过瞬移到达附近,也要谨慎使用背面剔除,并测试场景边界体积,防止用户穿出地图。
空间音频
空间音频(Spatialized Audio)能提升 VR 体验,但它需要在运行时根据相机朝向(尤其是垂直方向)实时合成音频谐波,持续消耗 CPU,有时还会使用 GPU 加速。如果使用空间音频后出现性能问题,应同时检查 CPU 和 GPU。
避免相机物理碰撞
在 VR/AR 中,用户可能把头伸进物体内部。虽然给物体加碰撞体阻止相机穿过它们很诱人,但这会造成不适,因为相机不会随用户真实移动而移动,还会破坏 AR 的位置追踪校准。更好的做法是允许用户看穿物体,或在物体与相机之间保留安全缓冲区。也可以限制瞬移落点,避免玩家离墙太近。
避免使用欧拉角
任何方向计算都应使用四元数(Quaternion),避免欧拉角。欧拉角在多次旋转后会产生累积误差,而 VR/AR 中用户视角每秒都会发生大量微小变化。更严重的是,欧拉角可能出现 万向节锁(Gimbal Lock):当某个轴旋转 90 度时,两个轴会重叠,导致后续旋转同时影响两个轴。四元数通过引入第四个值避免了这一问题。
克制与取舍
VR 应用的性能目标很难达到。当场景质量超出当前 XR 设备和典型用户硬件所能承受的范围时,必须果断削减对象。对 XR 项目来说,性能差的代价往往远大于画质提升的收益。应持续关注 Unity 官方文档、博客和教程,了解最新的 XR 设计与优化建议。
小结
XR 应用与普通 Unity 应用共享底层平台,因此有大量通用优化手段可用。但也需要针对 XR 的特殊性做出调整:高帧率、舒适度、立体渲染模式、抗锯齿、渲染路径选择、相机控制、空间音频等。在硬件成熟之前,开发者需要在画质和性能之间保持克制,并愿意为实现流畅体验而削减场景内容。