3.1 渲染管线与立体视觉


3.1 渲染管线与立体视觉

本节摘要:XR 渲染管线和传统 3D 渲染最大的差异是"立体"——同一帧要渲染两次(左眼+右眼),还要在显示前对每只眼做反畸变。整条管线在 11.1ms(90Hz)内完成。本节拆开 XR 渲染管线的 8 个阶段,给出每个阶段的预算;再用一个 Shader 演示"注视点渲染"——把注视点附近 20% 区域做全分辨率,剩下 80% 降采样。

学习要点

阅读完本节,你应当能够:

  1. 说出 XR 渲染管线的 8 个阶段及每个阶段的毫秒预算。
  2. 解释反畸变(Barrel Distortion Compensation)的工作原理。
  3. 在 Unity 里启用注视点渲染,并测量它对 GPU 帧时间的影响。
  4. 解释 TimeWarp 和 SpaceWarp 的工作原理。

一、问题与直觉

XR 渲染看起来"只是把 3D 画面投到屏幕上",但要解决 4 个非平凡问题:

  1. 立体视觉:左右眼看到的画面要差一个视差(IPD,瞳距约 63mm)。
  2. 畸变校正:透镜让画面边缘出现"桶形畸变",必须在显示前反向校正。
  3. 跟头转动:头转时画面必须跟得上,否则大脑"出戏"——这就是 TimeWarp。
  4. 性能预算:90Hz 意味着 11.1ms 留给你所有 GPU 工作。

这 4 个问题任何一个没解决,体验都会瞬间崩塌。

二、XR 渲染管线的 8 个阶段

阶段 工作内容 典型耗时
1. 姿态采样 从 IMU/SLAM 读出头/眼 6DoF <0.1ms
2. 视锥裁剪 根据姿态裁剪掉画面外物体 0.2ms
3. 立体渲染 同帧渲染左眼+右眼 4-6ms
4. 反畸变 把渲染好的图像做反向桶形畸变 0.5ms
5. 注视点渲染 对中心 20% 做全分辨率,边缘降采样 已包含在 3
6. 合成 把虚拟画面 + 摄像头透视合成 0.3-0.5ms
7. TimeWarp 用最新姿态重新投影画面 0.3-0.5ms
8. 显示 送面板显示 由硬件决定

加起来 5-7ms 是理想情况。剩下的 4-6ms 留给 CPU(物理、AI、脚本)和系统调度。

⚠️ 常见坑:把"渲染"和"显示"分开看。如果渲染完成时已经过了 11ms,下一帧 TimeWarp 也救不回来——画面会出现"卡顿+拖影"。

三、立体视觉:IPD 和视差

人的左右眼相距约 63mm。看同一物体时,左右眼图像有一个微小偏移——视差(Disparity)。大脑根据视差反推出物体的深度。XR 渲染就是模拟这个过程:

// Unity 立体渲染:每只眼一个 view matrix Matrix4x4 viewLeft = cameraLeft.worldToCameraMatrix; Matrix4x4 viewRight = cameraRight.worldToCameraMatrix;

两个 view matrix 的差异就是 IPD(约 0.064m)。IPD 是 XR 头显必须支持的可调参数——每个人的瞳距不同,固定 IPD 会让一部分用户疲劳。

四、反畸变:Barrel Distortion Compensation

透镜让边缘画面"拉宽",叫桶形畸变(Barrel Distortion)。XR 渲染要在送显示前对图像做反向桶形畸变:

// 反畸变 Shader half4 frag (Varyings input) : SV_Target { float2 uv = input.uv * 2.0 - 1.0; // 转到 [-1, 1] float2 distortedUV = uv * (1.0 + k * dot(uv, uv)); // 反向桶形 distortedUV = distortedUV * 0.5 + 0.5; return SAMPLE_TEXTURE(_MainTex, distortedUV); }

其中 k 是畸变系数,Quest 3 约 0.18,Vision Pro 约 0.12。没有这一步,画面边缘会糊+色散。

五、TimeWarp 和 SpaceWarp

TimeWarp(时间扭曲):当 GPU 渲染完成时,用户头已经又转了一点。TimeWarp 用"渲染后到显示前"这 1-2ms 时间,用最新的头部姿态重新投影整个画面。

SpaceWarp(空间扭曲):当帧率掉到 60Hz 时,SpaceWarp 在 TimeWarp 基础上再补一帧——用前后两帧的深度信息"猜"出中间那一帧。Meta Quest 3 的 90Hz 实际跑 45Hz 渲染 + SpaceWarp 补帧,可以省 50% GPU 负载。

Quest 3 / Vision Pro 都默认开启这两项。开发者只要保证渲染 45-60Hz 即可。

六、注视点渲染:Foveated Rendering

人眼中央凹的分辨率远高于周边——但全画面高分辨率是浪费。注视点渲染只对注视点附近 20% 区域做全分辨率,剩下 80% 降采样:

// 注视点渲染 API var foveationParams = new XrFoveationProfile() { FoveationLevel = XrFoveationLevel.High, VerticalOffset = 0.0f }; xrSession.SetFoveation(foveationParams);

这项技术让 Vision Pro 跑 4K×2 Micro-OLED 时实际 GPU 负载只增加 30%,而不是 100%。

💡 关键直觉:注视点渲染不是"硬件升级",是"算法降本"——它用算法把硬件压力从 100% 砍到 30%。这是 XR 行业的核心工程智慧。

七、动手演示:在 Unity 里启用注视点渲染

// 启用注视点渲染(Unity 2022 LTS+) using UnityEngine.XR.OpenXR; var settings = OpenXRSettings.Instance; settings.eyeTracking = true; settings.foveatedRendering = FoveatedRenderingLevel.High;

跑起来后用 RenderDoc 抓帧,会看到:中心 20% 区域是 4K 分辨率,边缘是 1K 分辨率——但肉眼看不出差异。GPU 帧时间从 8ms 降到 5ms,省下的 3ms 可以用来做更多 AI/物理。

本节要点回顾

  • XR 渲染管线分 8 个阶段,总预算 11.1ms(90Hz)。
  • 立体视觉的本质是 IPD 视差,反畸变是桶形畸变的反向补偿。
  • TimeWarp 用最新头部姿态重投影,SpaceWarp 补帧。
  • 注视点渲染是"用算法降本"的核心——能省 30-50% GPU 负载。
  • 工程目标不是 90Hz 渲染,而是 45-60Hz 渲染 + SpaceWarp 补到 90Hz。

图 3-1:XR 渲染管线 8 阶段

把 XR 渲染管线的 8 个阶段画成流水线——每个阶段的输入/输出和典型耗时一目了然。

图 3-1:XR 渲染管线 8 阶段

下一节我们看第二个支柱:跟踪与 SLAM。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U