XR 优化

理解 VR/AR 的性能预算与单 Pass Stereo、注视点渲染等 XR 特有优化手段。

学习目标

  • 能解释 PC VR 90 FPS 与 Standalone 72 FPS 对应的毫秒级帧预算,以及双眼渲染对 GPU Fill 的放大效应
  • 能说出 Single Pass Instanced 相对 Multi-Pass 减少哪一类 CPU/GPU 成本,以及 URP Renderer 中应如何启用
  • 能回答:Standalone 头显 GPU ms 顶满但 CPU 有余量——你会先调 Render Scale、FFR 还是检查是否仍在 Multi-Pass?

原书边界:Chapter 7

Packt 第三版把本章命名为 Optimizations for Virtual and Augmented Reality。官方目录列出的核心范围如下;这些条目共同构成本章的一对一边界:

  • Overview of XR technology:纳入本章实验与验收,不拆到别章重复计数。
  • Developing XR products:纳入本章实验与验收,不拆到别章重复计数。
  • Performance enhancements in XR:纳入本章实验与验收,不拆到别章重复计数。

XR 把双眼渲染、显示刷新、姿态预测、合成与 motion-to-photon 约束叠到普通帧预算之上。OpenXR 与 XR Plug-in Management 取代旧 SDK 接入,但单/多 Pass、分辨率、注视点、重投影和设备热预算仍是核心。 因此,本章既保留 2019/2020 语境,也明确标出迁移到现代 Unity 时哪些是稳定原理、哪些只是版本相关接口。

头显里多掉一帧,人就会晕

桌面游戏掉帧只是卡顿;在 VR 里,帧率不足或帧时间抖动 会直接触发 晕动症——画面与内耳前庭不同步。Quest、Index 等设备要求 72 甚至 90 FPS 稳定提交,整帧预算只有 约 11–14 ms,比 60 FPS 桌面(16.6 ms)更紧。

更麻烦的是 双眼:同一场景往往要 画两遍(或使用 Single Pass 一次提交双眼),像素量接近 2× 分辨率 × 2 眼。Ch6 的 GPU 优化在 XR 里全部 乘上系数——这章专门讲 XR 特有的性能预算与渲染路径

像双筒望远镜:两只眼睛各要一张清晰底片

想象用 双筒望远镜 同时看 3D 场景:每只目镜都要 独立对焦、独立曝光。若摄影师(引擎)对左筒拍一张、再跑回原点给右筒拍一张(Multi-Pass),快门与布景时间翻倍;若一次按下双快门、镜头阵列同时曝光(Single Pass Instanced),场地周转快一倍

周边视觉其实 看不清细节——只在 注视中心 用高分辨率底片、外围用粗颗粒(Foveated Rendering),是 XR 里常用的 「省胶片」 手段。

XR 性能预算:90 FPS 与 72 FPS

由头显刷新率决定,不是「能跑 60 就行」。

PC VR(Link、Index 等)常见 90 FPS ≈ 11.1 ms/帧。Standalone(Quest 2/3)基线 72 FPS ≈ 13.9 ms,热节流或省电档可能更低。

高刷头显(120 FPS)预算约 8.3 ms,留给后处理与 Overdraw 的空间更小。

除渲染外,预算还要分给 姿态预测、合成、重投影(Asynchronous Spacewarp / Application SpaceWarp)。Profiler 里 GPU ms + XR 模块 接近预算线时,任何 全屏 Post、高 MSAA、未合批透明 都会先爆。

Single Pass Instanced:一次 Draw 画双眼

是 URP/HDRP XR 的 推荐立体渲染模式。Legacy Multi-Pass 对每物体 提交两次,CPU 与驱动 SetPass 接近翻倍

Multi-Pass Stereo(Legacy)场景遍历 ×2 · SetPass/State 切换翻倍场景网格Pass 1 · 左眼Pass 2 · 右眼CPU 提交 ×2SetPass ×2URP / Shader 要求• 每物体两次 cull + draw · Batches 统计接近翻倍• 透明排序/后处理需分别处理两眼 · 移动端极少使用• 迁移到 Single Pass 可显著降 CPU 与驱动开销
Multi-Pass 对同一场景渲染两遍,CPU/GPU 状态切换成本接近翻倍,仅作兼容 fallback。
Single Pass Instanced(推荐)一次 Draw Call · GPU Instancing 数组 index 区分左右眼场景网格1× Draw + SV_InstanceIDunity_StereoEyeIndex左眼 RT右眼 RTURP / Shader 要求• 启用 XR Plug-in Management + URP Renderer「Single Pass Instanced」• Shader 用 unity_StereoEyeIndex 选 MVP · 避免硬编码单眼矩阵• Post 需 XR 兼容或按眼拆分 · 自定义全屏 Pass 要测双眼
Single Pass Instanced 用 GPU 实例化在一次提交里画双眼,是 URP XR 的默认高效路径。

启用与 Shader 注意点

  • Project Settings → XR Plug-in Management:安装目标平台 Plug-in(OpenXR、Oculus 等)
  • URP Renderer Data:Stereo Rendering Mode 选 Single Pass Instanced(或 Multiview,视平台)
  • 自定义 Shader 必须用 XR 兼容宏UNITY_VERTEX_OUTPUT_STEREOunity_StereoEyeIndex),Post Processing 需验证 双眼均正确
  • Fullscreen Pass、Grab Pass、部分后处理 在 XR 下易踩坑——Frame Debugger 分别检查 Left/Right eye

Foveated Rendering:中心清晰、周边省像素

利用 人眼周边分辨率低。Standalone 常用 Fixed Foveated Rendering (FFR);带眼动追踪的设备可做 Gaze-contingent 动态注视点。

Foveated Rendering(注视点渲染)人眼周边视觉分辨率低 · GPU 在周边用更少像素/shader 采样单眼视场(俯视)← 注视方向采样密度全屏统一 · Fill rate 最高Quest / OpenXR:Fixed Foveated Rendering (FFR) · PSVR2:Gaze-contingent(需眼动)URP:XR Plug-in 或设备 SDK 暴露 FFR 等级 · 与 MSAA/动态分辨率叠加需 Profiler 验证均匀分辨率 · 周边与中心同采样密度
注视点渲染把像素预算集中在视线中心,周边降采样可显著降 Fragment 成本,边缘过激进会出现「游泳」伪影。

关闭 FFR 时 全屏均匀采样,Fill rate 最高,边缘最稳。

Foveated Rendering(注视点渲染)人眼周边视觉分辨率低 · GPU 在周边用更少像素/shader 采样单眼视场(俯视)← 注视方向采样密度Fovea 1.0×Mid 0.5×Periph 0.25×Quest / OpenXR:Fixed Foveated Rendering (FFR) · PSVR2:Gaze-contingent(需眼动)URP:XR Plug-in 或设备 SDK 暴露 FFR 等级 · 与 MSAA/动态分辨率叠加需 Profiler 验证中等注视点:中心 1× · 中环 0.5× · 外环 0.25×
注视点渲染把像素预算集中在视线中心,周边降采样可显著降 Fragment 成本,边缘过激进会出现「游泳」伪影。

中等 FFR:中心 1×、中环降采样、外环更粗——多数 Quest 项目的平衡点。

Foveated Rendering(注视点渲染)人眼周边视觉分辨率低 · GPU 在周边用更少像素/shader 采样单眼视场(俯视)← 注视方向采样密度Fovea 1.0×Mid 0.5×Periph 0.25×Far 0.125×Quest / OpenXR:Fixed Foveated Rendering (FFR) · PSVR2:Gaze-contingent(需眼动)URP:XR Plug-in 或设备 SDK 暴露 FFR 等级 · 与 MSAA/动态分辨率叠加需 Profiler 验证激进注视点:仅 fovea 全分辨率,外围大幅降采样
注视点渲染把像素预算集中在视线中心,周边降采样可显著降 Fragment 成本,边缘过激进会出现「游泳」伪影。

激进 FFR:GPU 省最多,但周边 模糊/游泳(shimmer) 明显,快速转头时更易察觉。

XR 输入开销与 URP XR 设置

与渲染 共享同一帧 CPU 预算。大量 Physics.Raycast、XR Interaction Toolkit hover/select、Hand 骨骼 会在 PlayerLoop 早期 抬 CPU ms。

决定 GPU 路径是否正确、是否启用 Single Pass、MSAA 样本数 等。

常见配置清单:

  • Edit → Project Settings → XR Plug-in Management:勾选目标 Loader;Android 与 Standalone 分开配置
  • URP Asset:MSAA 与 Render Scale(如 0.9–1.1);过高 MSAA 在 XR ×2 眼 极贵
  • Quality Level:Standalone 单独一档,关 多余 Post、阴影距离、像素灯数量
  • Input System:用 XR Input Actions 替代每帧 Input.GetButton 散落调用;交互集中在一个 Input Reader 里更新

动手:Standalone VR 性能排查

下面五步针对 Quest 类 Standalone GPU/CPU 双紧场景。每步示意图对应当前检查点——建议 Link 或实机 + Meta XR Profiler 同步。

猜一猜:把 FFR 从 Off 调到 High,GPU ms 下降但边缘发糊,该优先降 FFR 还是降 Render Scale?

分步1 / 5

① 基线:确认目标 FPS 与帧预算

确认 Quality 目标 72/90 FPS。Profiler 记录 CPU ms、GPU ms、XR Wait/Get Pose。超 13.9 ms(72 FPS)即需优化;记录是 GPU bound 还是 CPU bound。

容易踩的坑

小结

  • XR 预算由刷新率决定:90 FPS ≈ 11.1 ms,72 FPS ≈ 13.9 ms,需留合成余量
  • 双眼放大像素与 Draw;Single Pass Instanced 是 URP 默认高效立体路径
  • Foveated Rendering 用周边降采样换 GPU;等级与 Render Scale 需实机权衡伪影
  • XR 输入每帧 Poll + 射线交互占 CPU;与 URP XR 设置(MSAA、Render Scale、Post)同帧竞争
  • 排查顺序:预算 → Single Pass → FFR/Scale → URP 画质档 → 输入 CPU

练习

问题 1(改 Demo 型) 在 Standalone 或 Link 场景打开 Profiler,记录默认 GPU msCPU ms。只改一项:URP Render Scale 0.9FFR 提一档,同场景复测——哪一项降 ms 更多?边缘画质能否接受?

问题 2(问答型) Single Pass Instanced 与 Multi-Pass Stereo 各适合什么场景?为何移动端几乎不用 Multi-Pass?

问题 3(选型型) GPU ms 顶满、CPU 有余量;已 Single Pass、LOD 正常。下一步优先 FFR、降 MSAA 还是降 Shadow Distance?

名词解释

本章出现的专业名词,用大白话再讲一遍。

XR 性能预算

头显刷新率对应的帧时间上限。详见 XrPerformanceBudgetDiagram target 90/72。

Single Pass Instanced

一次 Draw 通过实例索引输出双眼。详见 SinglePassStereoDiagram mode single。

Multi-Pass Stereo

左右眼各渲染一遍的 Legacy 路径。详见 SinglePassStereoDiagram mode multi。

Foveated Rendering(注视点渲染)

注视区高分辨率、周边降采样。详见 FoveatedRenderingDiagram。

Fixed Foveated Rendering (FFR)

固定视场中心的注视点渲染,Quest 等平台常用,无需眼动硬件。

Render Scale

URP 渲染分辨率相对 eye buffer 的比例;XR 下直接缩放 Fill rate。

XR 输入开销

HMD/控制器/手部每帧 Poll 与交互射线 CPU 成本。详见 UrpXrSettingsDiagram highlight input。

URP XR 设置

XR Plug-in + URP Renderer 立体模式、MSAA、Quality 等成组配置。详见 UrpXrSettingsDiagram。

资料与写作方式声明

本章以Packt《Unity Game Optimization》第3版权威目录界定学习范围,并结合正文列出的技术资料独立重写;不宣称复现原书正文,也不沿用原作表述。

原作版权归作者与出版社所有;本站原创教学结构与表述仅供学习交流。

讨论

评论区加载中…