本节摘要:XR 项目所有性能问题的根是"11.1ms 的帧时间预算"。本节给出一张完整的性能预算表(CPU/GPU/内存/带宽/温度/电池),拆开 5 个最常见的优化方向(减面、减 draw call、降低分辨率、关特效、注视点渲染),并演示用 Unity 的 Frame Timing Manager + RenderDoc 抓帧来定位瓶颈。
阅读完本节,你应当能够:
XR 项目的性能优化目标不是"画面好看"——而是"在严苛预算下保持 90Hz 稳定不掉帧"。90Hz = 11.1ms / 帧,120Hz = 8.3ms / 帧。这两个数字决定了 XR 项目的"性能天花板"。
直觉:减渲染 > 提 GPU。把场景面数砍 30% 比买更好的 GPU 更有效——因为 GPU 升级意味着换设备。
| 资源 | 预算 | 典型占用 | 优化目标 |
|---|---|---|---|
| 帧时间 | 11.1ms | 8-10ms | 留 1-2ms 余量 |
| CPU | 4-5ms | 3-4ms | 单核负载 |
| GPU | 4-5ms | 4-5ms | 顶点/像素负载 |
| 内存 | <4GB | 2-3GB | Quest 3 限制 |
| 显存带宽 | <25 GB/s | 15-20 GB/s | 抗 aliasing |
| 温度 | <42°C | 35-40°C | 持续 30min |
| 电池 | 2-3h | 1.5-2h | 整机功耗 < 5W |
把"帧时间"作为唯一目标,其他资源都围绕它做权衡。
| 资源 | Quest 3 | Vision Pro |
|---|---|---|
| SoC | Snapdragon XR2 Gen 2 | M2 + R1 |
| 算力 | 4 TFLOPS GPU + 12 TOPS NPU | 10 TFLOPS GPU + 15 TOPS NPU |
| 内存 | 8GB | 16GB |
| 显示 | 2064×2208 × 2 | 3660×3200 × 2 |
| 续航 | 2-3h | 2h |
| 目标帧率 | 90/120Hz | 90/100Hz |
| 帧时间预算 | 11.1/8.3ms | 11.1/10ms |
Quest 3 的算力比 Vision Pro 弱 2.5 倍,但分辨率也低——单像素算力相当。Vision Pro 的 R1 协处理器分担追踪/感知计算,让 M2 专心做渲染——这是它帧率更稳的关键。
按"对帧时间影响"从大到小排序:
3D 模型的面数从 100k 砍到 30k,渲染时间直接降 50%。在 XR 里 LOD(Level of Detail)是必须的:
// Unity LOD:远处用低模 public class XR_LOD : MonoBehaviour { public LODGroup lodGroup; void Start() { // 距离 < 5m: 100k 面 // 距离 5-15m: 30k 面 // 距离 > 15m: 5k 面 } }
每个 Draw Call 是 CPU→GPU 的一次"开火"。1000 个物体 = 1000 个 Draw Call = CPU 满载。用 GPU Instancing 合并:
// Unity GPU Instancing public Material instancedMaterial; void Start() { var renderer = GetComponent<Renderer>(); renderer.material.enableInstancing = true; }
XR 头显默认渲染分辨率 1.0x。降到 0.7x → GPU 负载降 50%。在 Quest 3 上:
// Quest 3 降低渲染分辨率 OVRManager.eyeTextureSizeScale = 0.8f; // 80% 分辨率
代价是画面略糊,但配合注视点渲染后肉眼几乎看不出。
后处理(Bloom、DOF、AA)在 VR 里吃 30%+ GPU。砍到 1-2 个最关键的:
// 关掉所有后处理 UnityEngine.Rendering.Universal.UniversalAdditionalCameraData urp = camera.GetUniversalAdditionalCameraData(); urp.renderPostProcessing = false;
上一章渲染管线讲过——对注视点附近 20% 区域全分辨率,剩下 80% 降采样。GPU 负载降 30-50%。
// Unity Frame Timing Manager using UnityEngine.Rendering; public class FrameTimingCapture : MonoBehaviour { void Update() { FrameTimingManager.CaptureFrameTimings(); var timings = new FrameTiming[1]; uint count = FrameTimingManager.GetLatestTimings(1, timings); if (count > 0) { var t = timings[0]; Debug.Log($"CPU: {t.cpuFrameTime:F2}ms GPU: {t.gpuFrameTime:F2}ms 帧时间: {t.cpuFrameTime + t.gpuFrameTime:F2}ms"); } } }
跑起来后 Console 输出每帧的 CPU/GPU 拆分:
CPU: 3.45ms GPU: 4.12ms 帧时间: 7.57ms CPU: 3.21ms GPU: 4.01ms 帧时间: 7.22ms
如果 GPU 时间 > CPU 时间 → 减少 draw call / 减面。如果 CPU 时间 > GPU 时间 → 减少脚本工作量。
⚠️ 常见坑:很多团队一开始就用 RenderDoc 抓帧分析——但 RenderDoc 本身会让帧时间变成 30ms,调试结果不可信。Frame Timing Manager 是更轻量的"运行时"分析工具。
XR 头显的续航不是由电池容量决定的,而是由"芯片功耗+散热"决定的:
优化的目标是"保持 5W 以下"。每降 1W,续航延长 30 分钟、芯片温度降 3°C。
工程上:
把 5 大优化方向按"对帧时间影响"画成柱状图——能直观看到哪个方向投入产出比最高。

下一章我们从工程层进入"内容创作"——3D 资产、沉浸叙事、空间音频、UI/防眩晕。