Version: 2019.2
VR 空间音响
开源代码仓库

VR 帧计时

VR 模式下的帧计时与支持 VSync 的非 VR 模式下的帧计时完全相同(请参阅事件函数执行顺序文档)。唯一的区别是 Unity 不依赖于底层 3D SDK 的 VSync,而是基于当前渲染所使用的 VR SDK。渲染速度快于显示器刷新速度没有任何好处。相反,Unity 注重于最大限度提高时间的利用效率。

在多线程渲染中,Unity 会同步模拟线程和 CPU 上的渲染线程。这会减少延迟。模拟线程主要执行脚本、声音、AI 以及运行模拟所需的其他任务。渲染线程侧重于向图形驱动程序提交绘制调用,而图形驱动程序会验证绘制调用并将它们发送到 GPU。为了实现线程之间的最大并行度,Unity 在图形命令进入时执行这些命令,并与此同时模拟下一帧。

Unity 等待 GPU 完全渲染并显示上一帧,然后提交下一帧的渲染命令。

尽可能最低的延迟

在 Unity 提交依赖于视图变换矩阵的第一个渲染命令之前,必须首先从 VR SDK 获取该视图矩阵。为了尽可能降低延迟,VR SDK 会在每帧预测两次头部变换:

  • 一个预测用于渲染当前帧。此预测对应于当帧到达屏幕时您的头部在实际空间中的实际位置。

  • 一个预测用于模拟下一帧。

Unity 将当前帧的渲染预测应用于摄像机、控制器以及需要相关信息以进行场景渲染的任何组件。如果无法渲染下一帧,Unity 将对下一帧使用模拟预测。

如需了解硬件如何处理渲染的更多信息,请参阅制造商的头戴式显示器文档。

Unity 丢帧时会发生什么情况?

如果 Unity 未及时提交完全渲染的帧以使其为下一次显示刷新做好准备,则可能会发生一些情况,具体情况取决于当前使用的是哪个 VR SDK。VR SDK 可能:

  • 显示先前提交的帧。这种情况下看起来像是抖动,并会大大降低体验品质。

  • 根据当前头部姿势以旋转的方式重新投影先前提交的帧。这是一种粗略的近似,很适合作为静态内容的后备,但任何具有动画或位置移动的内容则会看起来不正确。

  • 应用某种形式的位置重投影。这可能是暂时的,用于填补遗漏的细节。

有关重投影(有时称为时间规整)的更多信息,请参阅 XinReality 上有关 Timewarp 的 Wiki 条目。

这一切都是自动发生的。此时对 Unity 而言通常已经太迟了,无法成功完成本应该已经在渲染的下一帧。相反,VR SDK 接受其收到的上一帧并将其重投影到最新的预测姿势,而 Unity 将等待下一次渲染一个完整帧的机会以重回正轨。如果您的应用程序持续丢帧,Unity 将每隔一帧进行渲染。

如需了解硬件如何处理渲染的更多信息,请参阅制造商的头戴式显示器文档。

VR 中的 GPU 密集型与 CPU 密集型

每个显示器都具有 Unity 绑定的特定刷新率。可以在运行时使用 VRDevice.refreshRate 获取此刷新率。1 除以 refreshRate 得到的值将是分配给单个帧的时间。

例如,在刷新率为 90 赫兹的情况下,此时间可能为 11.1 毫秒。

  • 如果您的应用程序是 GPU 密集型,Unity Profiler 会显示超过一帧时间(以毫秒为单位)的 XR.WaitForGPU

  • 如果您的应用程序是 CPU 密集型,则一帧占用的时间比指定的帧时间长,但 Unity Profiler 会显示短于一帧的 XR.WaitForGPU

VR 空间音响
开源代码仓库