2. Lumen - Surface Cache

1 概述

直接光照只需要关注相机看到的部分,而间接光照需要处理次级光线及之后的光照信息,也就是不依赖于相机的全局信息。每帧来计算光线交点信息对于大场景是不现实的,而 surface cache 的作用就是缓存次级表面信息,供光追采样。

surface cache 可以粗略理解为定义在 texture space 上的cache,而texture space描述的是物体表面空间,不随相机而改变。整个场景的texture space是非常大,不可能全部装入显存,但实际每帧只会使用到一小部分。因此在实现上,surface cache采用的是类似于virtual texture的技术。将texture space划分为固定大小的page,使用page table维护virtual page与physical page的换入换出。光追采样surface cache发生缺页时,会生成对应的page请求。

surface cache 缓存用于间接光照计算的相关信息包括材质、表面的直接光照计算、表面的radiosity。surface cache由于定义在物体表面上,不随相机而改变,因此在多帧之间具有一致性。实际更新过程可以按照开销预算来帧间分摊

2 工作流程

Surface Cache 是 Lumen 系统的基石,Lumen 其它部分都是通过采样surface cache来获取次级弹射信息。下面这张图是surface cache整体工作流程:

  1. 构建要更新的virtual page列表。更新请求主要来自于:场景的动态更新,如物体的加载与卸载;上一帧的surface cache request。每帧的更新开销预算是固定,为此基于一定策略来评估page的重要性,在预算内,选择重要性高的page更新。
  2. PageTable 更新。在得到要更新的virtual page列表后,需要先为这些page分配physical page,这涉及到虚拟存储的管理。
  3. 历史数据重投影与填充gbuffer数据。先将上一帧的surface cache中,发生重分配的page数据重投影到当前帧page;构建光栅化page的mesh draw commands,光栅化填充page所在表面区域的gbuffer数据。
  4. 构建需要更新直接光照的 lighting page list。有了page的gbuffer数据之后,准备计算page的直接光照。此时page table中包含新出现的page以及已存在page,已存在page数据可以复用,未必需要更新。这里同样按照预算统计出需要更新直接光照的 lighting page list
  5. 光照计算。计算光照阶段将page划分为 8x8 大小的page tile。由于光源数量可能很多,按照page tile范围以及光源的衰减等构建出影响到page tile的光源列表(tile-based rendering)。为每个texel执行光照计算:
    • direct lighting: 应用光源列表的lighting function计算得到
    • final lighting: direct lighting + 上一帧的 indirect lighting。这里串起来了上一帧的间接光,这样多帧累积达到无限反弹近似。
  6. 更新 radiosity。radiosity用于间接光计算,这里的radiosity与probe类似,只是放置在了surface空间下。
    1. 按照indirect lighting预算构建放置在page的probe更新列表
    2. 为probe采样光线,执行光追,有交点则转而采样surface cache的final lighting作为光线radiance。这里如果发生缺页会生成一个page请求
    3. 为probe radiance执行spatial/temporal的filter
    4. 投影为SH,并为每个texel插值其周围的probe生成irradiance,更新到 indirect lighting
surface cache流程

3 Lumen Scene

Lumen Scene 是 Lumen 系统对世界场景的轻量化表示,其不持有场景中任何几何、材质数据,仅仅包含对 FPrimitiveSceneInfo 所引用模型的 mesh card 参数化表示。整个 Lumen Scene 也是基于 mesh card 参数化构建起来的,其代表数据结构 FLumenSceneData,主要成员有

1
2
3
4
5
class FLumenSceneData
{
TSparseSpanArray<FLumenCard> Cards; // 场景下lumen card的汇总
TSparseSpanArray<FLumenPageTableEntry> PageTable; // 虚表,记录每个virtual page信息
};

3.1 Mesh Card参数化

Card 是 Lumen 用来捕获场景模型材质属性的工具,其核心数据是一个局部轴对齐的 Bounding Box,包围盒 XY 定义了 Viewport 的大小,Z 定义了 Projection 的 Depth,所以 Card 的可视化就是一个正交投影的视锥体,如下图所示。

Card-Visualization

需要说明的是,每方向有可能会存在多个 Card,这与 Mesh 的几何结构的复杂程度有关,一般只会生成 6 个 Card,每方向各一个。因此,每个 Mesh 至少有 6 个 Card,这些 Card 的组合被称为 Mesh Cards,每个 Mesh 在导入时离线生成这些 Cards,之后会详细进行阐述。

Card 与 Mesh Cards分别对应了FLumenCardFLumenMeshCards

3.2 存储管理

3.3 采样

4 Surface Cache 更新

4.1 cache 请求

一部分来自于场景更新/相机移动带来的 new card,一部分来自于光追过程中访问surface cache的feedback。

4.1 gbuffer

4.2 lighting

4.3 radiosity

Reference

[1] https://zhuanlan.zhihu.com/p/516141543


2. Lumen - Surface Cache
http://example.com/2025/03/04/Render Engine/UE5/Lumen/2. Surface Cache/
Author
John Doe
Posted on
March 4, 2025
Licensed under