Oculus-VR 分支游戏引擎性能提升
更新时间: 2025年6月5日
Unreal 引擎可提供大量的
性能优化功能。但是,部分功能对于 Quest 及其他 MR 设备的性能收益有限。
Unreal 引擎 5 (UE5) 采用 LightGrid,一种正向+着色技术,来处理动态本地光源。但 UE5 中当前的 LightGrid 实现在移动设备上的性能开销较高,尤其是在 Quest 上。
我们自版本 72 起,通过将所有光源数据打包到统一缓冲区对象 (UBO) 中,而非使用着色器存储缓冲对象 (SSBO),优化 LightGrid。此变动显著提升了性能。
需要注意的是,GPU 硬件中用于存放 UBO 数据的常量缓冲区的大小是有限制的。因此,GPU 常量缓冲区只能容纳有限的动态局部光源数量。默认支持 32 个光源光,这一数值由 GMaxForwardMovableLights 指定。减小该数值可节省 GPU 常量缓冲区空间以用于存放其他统一缓冲区数据,增大该数值则可能会因常量缓冲区压力上升而导致性能下降。
注意:GMaxForwardMovableLights 为硬编码常量,而非 CVar。如果该值发生改变,则必须重新编译 UE5 的源代码。
另外,如果没有动态局部光源和反射捕捉,LightGrid 通道将默认禁用,节省约 0.14 毫秒的 GPU 时间。该行为通过下方的 CVar 进行切换。
性能测试结果显示,相较于原版 UE5 的 LightGrid 实现,GPU 应用时间的改进幅度在 3% 至 22.5% 之间。
默认启用此功能。
其中引入了以下 CVars:
r.Mobile.PackLightGridLightDataToUBO.Enable(默认为 1)将 LightGrid 光源数据打包到 UBO。
r.Forward.NoLightGridIfNoLightOpt(默认值为 1)在移动设备的正向+渲染中,若没有动态本地光源或反射捕捉,则跳过 LightGrid 通道。
正如前文所述,UE5 默认的基于 LightGrid 的动态本地光源在 Quest 设备上可能会造成较大负担。即便进行了上述优化,在某些情况下,LightGrid 的着色仍然成本高昂,尤其是当整个场景中动态本地光源数量较少的情况下。
Meta UE5 集成包含用于移动渲染器的动态点和聚光灯替代实现方式。该实现方式通过统一缓冲区将光源绑定到每个点亮的绘制调用(经典正向着色),同时禁用默认的 LightGrid(正向+着色)。
我们在性能测试中测量到,相较于 Quest 3 上的 LightGrid,某些场景中存在 10% ~ 15% 的性能差值。
在特定情况下,这种变化可能会增加绘制线程工作量。每个绘制调用有八点光源的硬限制,可通过下列 CVar 进行更改。对于光源数量较少的情况,通过展开式光照循环可对着色器进行专门化定制,这种循环可由下方的 CVar 进行修改。
要启用该选项,前往系统设置 >> 渲染 >> 移动设备 >> 在移动设备正向渲染中启用统一缓冲区本地光源支持。
其中引入了以下 CVars:
r.Mobile.UniformLocalLights.Enable(默认为False)
启用统一本地光照系统
r.Mobile.UniformLocalLights.NumUnrolledLights(默认为 0)
一个循环中要展开的光源数量。该 CVar 的最大值为 4。
r.Mobile.UniformLocalLights.MaxLights(默认为 8)
一个绘制调用可绑定的最大光源数量。
注意:此值无法设置为 8 以上。超出 8 个的光源将被无序弃置。更改此设置将大幅增加着色器排列和 PSO 数量。另外,此功能不兼容 GPUScene。
这些 CVars 均为只读,任何修改都需要重新构建移动着色器。
模拟统一缓冲区最初引入 OpenGL 后端是为了在 Unreal 引擎中支持低规格移动设备。它将常量缓冲区并入单个全局统一缓冲区中,用以提高着色器优化效果。由于切换为 DXC 编译器,所以 UE5 中移除了引擎的模拟统一缓冲区。
但在某些场景中,模拟统一缓冲区提供的加速甚至高于“真正的”统一缓冲区。在性能测试中,我们在 Quest 3 的一些场景中测量到了 5% 的差值。
Meta Github 分支的 UE5 集成 v65 版本支持模拟的统一缓冲区。
要启用此项,前往系统设置 >> 渲染 >> VR >> 启用模拟统一缓冲区。
其中引入了以下 CVars:
r.Vulkan.UseEmulatedUBs(默认为 False)
启用模拟统一缓冲区
注意:EUB 不兼容 GPUScene 或 LateLatching。
我们在性能测试中测量到,相比 Quest 3 上默认的遮挡查询,某些场景中存在 5% 的性能差值。
注意:r.NeverOcclusionTestDistance 对于 Android 平台默认为 2000,表示不会将距离低于 2000 厘米的任何对象发送至 Occlusion 查询。这一点可能需要逐个案例仔细调整。
其中引入了以下 CVars:
r.Mobile.AdrenoOcclusionMode(默认为 1)
启用 Adreno 遮挡路径(须先启用遮挡剔除)。
Unreal Engine 4 (UE4) 之前搭载了
软件遮挡功能,后来在 Unreal Engine 5 (UE5) 中删除了该功能,并替换为
遮挡查询,后者是一个基于 GPU 的解决方案。但是,遮挡查询在 GPU 绑定游戏中可能表现不佳。
自 V77 版本起,在 Meta 分支中重新引入软件遮挡。此文档强调了当前实施与原始 UE4 功能之间的区别。有关软件遮挡一般行为的信息,请参阅 UE4 文档。
要启用
软件遮挡,请前往“系统设置”并启用
支持自定义遮挡剔除 (CVar:
r.Mobile.AllowCustomOcclusion)。

与 UE4 相比,此实施利用遮挡物网格素材用户数据将遮挡物网格分配给父网格(静态网格、骨架网格或实例化静态网格)。有两种设置遮挡物网格的方法,但一次只能使用一种:
- 选择静态网格作为自定义遮挡物网格。可以相对于父网格设置比例和偏移。
- 与 UE4 类似,将父网格的 LOD 级别设为遮挡物网格。

为方便测试,可以在编辑器中启用软件遮挡,方法是在“系统设置”中启用支持通过延迟管道测试自定义遮挡剔除 (CVar: r.TestDeferred.AllowCustomOcclusion)。借助 r.SO.VisualizeBuffer 1,您可以可视化软件遮挡缓冲区。请注意,此功能仅用于测试目的,除非必要,否则不要启用。
配置遮挡物网格可能很有挑战性,特别是在确定大小和偏移值时。启用软件遮挡可视化工具可有效辅助此过程。
虽然可以在骨架网格中添加遮挡物网格,但开发者必须确保将遮挡物网格应用到非动画部分,并保持在网格轮廓内。若不满足上述条件,可能导致遮挡错误或画面闪烁问题。