内容创建/渲染

印第安纳琼斯™ 中的路径追踪优化:透明度 MicroMaps 和动态 BLAS 压缩

本系列第一篇文章是 Indiana Jones 中的路径追踪优化:Shader Execution Reordering 和 Live State Reductions ”,其中 介绍了 ray-gen shader 级别的优化,这些优化可加快“ Indiana Jones and the Great Circle™”的主要路径追踪通道 (“TraceMain”)

第二篇博文介绍了在游戏的路径追踪模式下,在 光线追踪加速结构 层面针对植被密集的场景进行的其他 GPU 优化:

  • 在 NVIDIA GeForce RTX 5080 GPU 上,使用 Opacity MicroMaps (OMMs) 将光线追踪 Alpha 测试对象 (如植被模型) 所花费的 GPU 时间从 7.90 毫秒缩短到 3.58 毫秒。
  • 压缩动态植被模型的 Bottom-Level Acceleration Structures (BLASs),将所有 BLASs 所需的 VRAM 大小从 1027 MB 减小到 606 MB。

剖析的场景 

A screenshot shows a dense forest, with a trail going down a hill and a lake in the background.
图 1。具有全 ray tracing 功能的剖面场景

本文中的所有数据均来自图 1 所示的秘鲁场景,使用 GeForce RTX 5080 GPU,并使用表 1 中的图形设置以及 Shader Execution Reordering (SER) 和 Live State Reductions 帖子中的 SER 优化功能。在本例中 (4K UHD with DLSS-RR Performance) ,路径追踪是在 1080p 下完成的。

设置 价值
输出分辨率 4K UHD ( 3840 x 2160)
DLSS 模式 DLSS 光线重建 、Performance Mode
图形预设
路径追踪模式 全景光线追踪
光线追踪光源 所有光源
植被动画质量 极致
表 1. Graphics settings for all data in this post

根据 Nsight Graphics RT Inspector 的数据,在此场景中,Ray Tracing Acceleration Structure (RTAS) 包含 2690 万个三角形。

RT 着色器中的 Alpha 测试 

为了能够在游戏中对所有经过 Alpha 测试的几何图形进行路径追踪,我们首先在路径追踪代码中实施基本的 Alpha 测试支持。由于性能原因,该游戏的非路径追踪版本一直禁用 ray-traced Alpha 测试支持。

TraceMain 通道中,光线追踪使用来自光线生成 (RayGen) 着色器的 GLSL traceRay 调用完成,并使用 Any-Hit Shaders (AHS) 实施 Alpha 测试。该 AHS 着色器从当前 Alpha 纹理中获取纹理 LOD 0。然后,如果忽略命中,它会调用 ignoreIntersectionEXT

对于阴影光线,我们使用了 rayQueryEXT 对象。我们无法使用 RayGen 着色器,因为引擎执行 Forward+ 渲染,因此必须在片段着色器中追踪其中一些光线。rayQueryProceed 循环主体使用 rayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetEXT 的偏移量获取包含 covermap-texture 索引的缓冲区。然后,仅当 alpha 测试不应拒绝命中时,它才会调用 rayQueryConfirmIntersectionEXT

GPU 初始性能 

在 GeForce RTX 5080 GPU 上,通过此初始实施,TraceMain 通道与 Nsight Graphics GPU Trace Profiler 中的图 2 类似。

The Nsight Graphics GPU Trace Profiler with the TraceMain marker selected, and the bottom panel shows that the Any Hit Shader is taking 17% of the periodic shader samples in this marker.
图 2。Nsight GPU Trace 的初始实现

图 2 显示,TraceMain 通道耗时 7.90 毫秒,并且在 AHS 中花费了 17% 的周期着色器样本。AHS 正在做的唯一一件事是进行 Alpha 测试。事实上,由于在遍历和 AHS 评估之间切换会产生开销,因此在 AHS 中进行 Alpha 测试的开销要大于执行 AHS 本身所花费的时间。有关更多信息,请参阅 NVIDIA Ada GPU 架构白皮书。

为了加快路径追踪通道中的 Alpha 测试,我们使用 VK_EXT_opacity_micromap 添加了 Opacity MicroMaps

使用 Opacity MicroMap 

Opacity MicroMaps 可让 GPU 通过预先计算微三角形的不透明度状态来减少 AHS 调用的数量,并将其分类为以下状态之一:

  • 不透明
  • 未知不透明
  • 透明未知
  • 透明

如果状态是两种未知状态之一,则微三角形的不透明度状态通常由 AHS 或 RayQuery 对象确定。对于阴影光线,我们使用了完全保守的四态 OMM。

对于间接照明光线,我们使用 gl_RayFlagsForceOpacityMicromap2StateEXT 标志,这使得 RTCore 单元使用 OMM 的双状态近似版本进行追踪。这种近似值对于间接照明来说已经足够好了,让我们完全避免在着色器中评估带有 OMM 的 BLAS 的 Alpha 测试。

在图 1 的场景中,对大多数 alpha 测试模型启用 OMM 后,路径追踪器的 SharcUpdateTraceMain 通道的 GPU 时间减少了 55%,其中 SharcUpdate 最多可执行四次反弹以更新 SHARC 辐射缓存,而 TraceMain 最多可执行两次反弹并重复使用 SHARC 缓存结果。在 SunTracing 通道上花费的 GPU 时间也加快了 14%。

GPU 时间 OMM 关闭 OMM 已开启 三角洲
SharcUpdate 1.99 毫秒 0.89 毫秒 -55%
TraceMain 7.90 毫秒 3.58 毫秒 -55%
SunTracing 0.83 毫秒 0.71 毫秒 -14%
表 2。OMM 开 关每次通过的 GPU 次数

通过观察 DispatchRays 通道的 Nsight Graphics GPU Trace Profiler,可以发现 AHS 中使用的周期样本数量已经减少,并且增量与 GPU 时间增量处于相同的范围内。

样本 OMM 关闭 OMM 已开启 三角洲
SharcUpdate 4.37 K ( 12%) 1.79 K ( 3%) -59%
TraceMain 37.5 K ( 17%) 12.2 K ( 3%) -67%
表 3。OMM 开 关的 AHS 定期样本

我们使用 VK_BUILD_MICROMAP_PREFER_FAST_TRACE 标志构建了所有 OMM,这使得 TraceMain 通道的 GPU 时间减少了 5%,而 BLAS 更新的速度稍慢。

烘焙 OMM 

我们集成了 OMM SDK ,并在 CPU 上为游戏中具有 covermaps 或 alpha textures 的大多数静态模型烘焙了所有 OMM。这包括所有 vegetation,但也包括所有其他经过 alpha 测试的静态模型,例如 fences、cloth、containers、tents 等。

最初,OMM 烘焙是在开发者工作站上完成的,但速度很慢,我们将所有烹饪过程都转移到离线 cooker 中进行。该 cooker 在艺术家提交 mesh 或 covermap 更改后运行。通常,OMM 会与其他 cooked 数据一起推送到 Perforce 中。

以下是我们用于烘焙 OMM 的参数。我们使用四态格式制作了所有 OMM,并调整了细分参数,以便在 VRAM 大小和效率之间实现良好的权衡:

  • ommFormat_OC1_4_State
  • ommUnknownStatePromotion_ForceOpaque
  • maxSubdivisionLevel: 6
  • dynamicSubdivisionScale: 2.0

在烘焙游戏中的所有 OMM 时,我们遇到了一个意想不到的问题:少数 OMM 的烘焙时间超过 30 分钟,有时需要数小时。在这些情况下,对 OMM baker 的输入 (UV 和 alpha 贴图) 没有任何错误。只是因为 UV 三角形或 alpha 贴图的复杂性使得烘焙过程比平常更长。

如果使用 OMM SDK 的 GPU 烘焙路径,则这一时间将大大减少,但这不可能实现,因为烹饪机没有 GPU,并且在添加 OMM 时无法更改。为了解决这个问题,我们使用以下 OMM SDK 参数让 OMM 烘焙师跳过 OMM,而这些 OMM 在 CPU 上烘焙会花费太长时间:

  • bakeFlags: ommCpuBakeFlags_EnableWorkloadValidation
  • maxWorkloadSize: 1ull << 32

烘焙时间与微三角形覆盖的 texels 数量成正比。这就是工作负载大小。这反过来又是三角形数量、纹理分辨率、细分比例和 UV 坐标的函数。当工作负载验证标志启用时,OMM baker 会发出警告消息,这有助于调整 maxWorkloadSize 阈值。

以下是复杂植被模型的此类警告示例:

[Perf Warning] - The workload consists of 869,002,294 work items (number of texels to classify), which corresponds to roughly 828 1024x1024 textures.

在图 3 和图 4 中,X 轴是 OMM index。

A histogram of OMM array-data sizes in kB, where 95% of the values are under 200 kB.
Figure 3. CPU times (in seconds)
A histogram of CPU times in seconds, where 95% of the values are below 1 sec.
图 4。OMM 数组数据大小 (in kB)

图 3 和图 4 中的直方图显示,在秘鲁地图和启用 OMM 工作负载验证标志的情况下,95% 的 OMM 只需不到 1 秒即可生成,每个 OMM 占用的空间不到 200 kB。在这项研究中,OMM 在本地重新烘焙,并在引擎中禁用多线程资源生成。

A screenshot from a tool showing statistics about a given OMM, and slides and controls to change the parameters of the baker and rebake a new OMM. The right panel shows the micro-triangles of the OMM and the underlying covermap.
图 5。OMM Viewer Tool,用于配备 arrayDataSize 43 MB 的 OMM

后来,我们发现还有一个问题:一些 OMM 占用了大量 VRAM。例如,其中一家单独占用了 43 MB 的 VRAM (图 5) 。同样,OMM baker 输入没有任何问题,只是 UV 封装的复杂性和覆盖图的复杂性导致生成的 OMM 非常庞大。

当存在 UV 三角形重用时,例如树上的叶子被实例化多次时,OMMs 的内存效率更高。在这种情况下,baker 几乎没有发现任何重叠或可能的重复使用,导致 OMM 数据阵列中出现超过 55K 个唯一条目。作为最后一分钟的变通方法,我们实施了一个额外步骤,跳过了所有 OMM,而这些 OMM 会占用超过 0.5 MB 的 VRAM。大多数 OMM 都低于该值。最后,游戏中每个地图的所有 OMM 都符合 128-MB VRAM 预算。Release 1.7.0 的 OMM SDK 添加了替代解决方案,将 OMM 输出大小保持在每个 OMM 的特定 VRAM 预算下。以下代码显示了 OMM CPU baker 的此新参数:

// Max allowed size in bytes of ommCpuBakeResultDesc::arrayData
// The baker will choose to downsample the most appropriate omm blocks (based on area, reuse, coverage and other factors) until this limit is met
uint32_t                 maxArrayDataSize;

验证 OMM 是否存在 

我们实施了 path-tracing 调试模式,可将 ray-tracing 主光线的结果可视化,并根据 RayQuery 循环是否必须执行多次迭代,使用不同的调试颜色。循环仅迭代一次的主光线可以在 RTCore 硬件单元中进行全景光线遍历,并以绿色显示。其他光线以紫色显示。一些像素还以蓝色显示,在此上下文中可以忽略。

为了验证所有原本配备 OMM 的 BLAS 是否确实配备了 OMM,我们发现将此调试模式与强制设置 gl_RayFlagsForceOpacityMicromap2StateEXT 光线标志并检查游戏各区域中所有具有紫色像素的模型相结合非常有用。我们甚至请求通过此模式的 QA 环节,要求报告此模式中包含紫色像素的游戏区域。

An image shows a version of the profiled scene where the majority of the image is shown in green pixels for the primary rays that haven't had to evaluate any alpha testing on the shader side. There are scattered blue and purple pixels in several areas.
图 6。Debug 模式:紫色像素缺少 OMMs

图 6 在与图 1 相同的场景中使用此调试视图与强制 2 状态 OMM。有几棵树没有 OMM,很可能是由于每个 OMM 按上述最大大小删除了已 cooked OMM,但大多数树确实有 OMM。

压缩动态 BLAS 

通常,BLAS Compaction 仅用于一次性构建、压缩且从未重建或更新的 BLAS。但是,BLAS Compaction 也适用于 BLAS,这些 BLAS 经过构建、压缩,然后进行更新或改装。

BLAS 与 BLAS 规整兼容的唯一限制是,此 BLAS 在规整后不应重建。其原因是,在重建后,BLAS 的压缩大小可能会有所不同。

事实证明,游戏中动态植被模型的 BLAS 无需重建,因此它们与 BLAS Compaction 兼容,我们也将其用于这些模型。通常情况下,最好定期为动态几何图形重建 BLAS,但动态植被在风中波动,在角色的脚下变形,并且总是在某个点返回到其初始位置。因此,为了保持 BLAS 的高质量,无需针对动态植被定期重建 BLAS。

游戏中为所有动态植被模型启用了 Dynamic-BLAS 规整。在图 1 的场景中,这样一来,在 NVIDIA RTX 5080 GPU 上,分配给所有 BLAS 的 VRAM 从 1027 MB 减少到 606 MB,节省了 41%。

A histogram of per-BLAS compacted sizes shows that the min value for this percentage was at about 30% and most BLASs had between 40% and 60%.
图 7。适用于动态植被的 Per-BLAS 紧凑尺寸

图 7 显示了基于 NVIDIA RTX 5080 GPU 的基于 BLAS 的动态 BLAS 规整所节省的 BLAS VRAM。X 轴是 BLAS 索引,Y 轴是压缩后的 VRAM 大小 (占原始 BLAS 大小的百分比) 。通常,压缩后的 BLAS 的大小是原始 BLAS 的 50%。

据记录,所有采用动态 BLAS 规整的 BLAS 都具有以下 BLAS 构建标志:PREFER_FAST_BUILD | ALLOW_UPDATE | ALLOW_COMPACTION

总结 

Opacity MicroMaps (OMMs) 是在使用 alpha 测试材质的场景中加速 traceRay 调用或 rayQuery 对象的有效方式。OMMs 让硬件避免在 RTCore 单元级别调用 Any Hit Shaders 或 rayQuery 循环中的等效着色器代码。OMMs 在 GeForce RTX 40 和 50 系列的 RTCore 单元中进行硬件加速。在 DX12 应用中,它们通过 DXR 1.2 NVAPI 公开。只要 BLAS 经过更新或改装,并且在初始构建后从未重建,BLAS 规整就与动态几何的 BLAS 兼容。压缩动态植被模型的所有 BLAS 对于让 Indiana Jones and Great Circle 在 12-GB GPUs 上以无损的路径追踪质量进行游戏至关重要,从而将秘鲁丛林场景中 BLAS 所需的显存总量从 1027 MB 减少到 606 MB。

这两种优化在游戏初始版本中均支持 Path Tracing。

第一篇博文 Shader Execution Reordering 和 Live State Reductions 介绍了光线生成着色器级别的优化,在“ Indiana Jones and the Great Circle ”的简介场景中,这些优化使 GPU 上的主要路径追踪通道 (TraceMain) 成本降低了 25%。

致谢 

在此,我们要感谢来自 NVIDIA 和 MachineGames 的所有人,他们于 2024 年 12 月 9 日推出了带有路径追踪功能的“ Indiana Jones and the Great Circle™”。

MachineGames:Sergei Kulikov、Andreas Larsson、Marcus Buretorp、Joel de Vahl、Nikita Druzhinin、Patrik Willbo、Markus Ålind、Magnus Auvinen、Jim Kjellin、Truls Bengtsson、Jorge Luna (MPG)。

NVIDIA:Ivan Povarov、Juho Marttila、Jussi Rasanen、Jiho Choi、Oleg Arutiunian、Dmitrii Zhdan、Evgeny Makarov、Johannes Deligiannis、Fedor Gatov、Vladimir Mulabaev、Dajuan Mcdaniel、Dean Bent、Jon Story、Eric Reichley、Magnus Andersson、Pierre Moreau、Rasmus Barringer、Michael Haidl 和 Martin Stich。

 

标签