12 KiB
title, date, excerpt, tags, rating
title | date | excerpt | tags | rating |
---|---|---|---|---|
Lumen学习笔记(2)——代码分析 | 2023-02-12 10:50:24 | Lumen | ⭐ |
前言
本文的内容为丛越的知乎文章的知识点浓缩。
- SIGGRAPH2022 Lumen:https://advances.realtimerendering.com/s2022/SIGGRAPH2022-Advances-Lumen-Wright%20et%20al.pdf
- UE5.1 Lumen Indirect Diffuse Lighting技术分析 - GOOD REAL的文章 - 知乎:https://zhuanlan.zhihu.com/p/696232022
Lumen相关可视化命令
- r.Lumen.Visualize.CardPlacement 1:开启Lumen Card的显示。
- r.Lumen.RadianceCache.Visualize 1:开启World Space Probe。
- r.Lumen.ScreenProbeGather.VisualizeTraces 1:开启屏幕空间探针追踪可视化。
Software Lumen的加速结构(距离场)
使用SDF(Signed Distance Field)作为存软件方案的加速结构。分为Mesh DF与Global DF。
Surface Cache
Surface Cache 是一系列运行时生成的图集(Atlas),以很低的分辨率存储了整个场景物体表面的材质属性。 Lumen 采用 Cube Map 理念仅生成6 个轴对齐方向(上、下、左、右、前、后)的 Material Attribute,在 Tracing 时将 Hit Point 简单的投影到这 6 个方向,对 Surface Cache 执行采样,就可以以极高的性能获取 Material Attribute 进行 Lighting。
Radiance Cache
对于 Surface Cache 上的每个 Texel 来说,Direct Lighting 的结果就是该点的 Radiance,如果把 Surface 上的所有 Texel 的 Radiance 保存下来,这样就包含了整个场景的光照信息,这就是 Radiance Cache。有了 Radiance Cache,就可以在 Tracing 时直接进行采样作为 Tracing 方向对应的 Radiance,将这些 Radiance 收集起来积分计算出 Irradiance,从而得到最终的光照值。还可以基于此生成 Indirect Lighting 并与历史帧累积起来,这样就实现了 Lumen 所宣称的无限反弹(Infinite Bounces)的全局光照能力。
从左到右分别为 Albedo、Normal、Depth、Radiance(Direct Lighting) 以及最终的渲染画面。
Lumen Scene
可以在ViewMode-Lumen-LumenScene
中查看。
Lumen Scene 包含了 DF 描述的场景几何表达以及 Surface Cache 描述的场景材质表达,是一个完整的系统。
Screen Space Probe(针对MF Tracing)
Lumen 是一个基于 Probe 的 RTGI 系统,通过 Probe 执行 Ray Tracing。
Screen Space Probe 仅用于DF Tracing,在1.8 米范围内进行Mesh DF Tracing,那么对于更远的距离会使用Global DF Tracing(以及屏幕空间外的区域)。但是却无法同 Mesh DF 一样从 Surface Cache 上获取 Material Attribute,原因正如上所述,Global DF 是由 Mesh DF 合并而来,全局只有一份,缺少了 Mesh DF 信息,而 Surface Cache 又与 Mesh 相关,因此无法通过 Global DF 获取 Mesh 对应的 Surface Cache 数据。
Lumen作者解释时还说了下图中的东西。我个人理解为:
首先进行屏幕空间的追踪,即直接获取到SurfaceCache的材质与照度数据,如果失败则依次追踪Mesh DF与Global DF。
那么 Lumen 又是如何对 Global DF 进行 Lighting 的呢?这就要引入 #Voxel Lighting。
Screen Space Probe放置方法
首先每隔 16 个像素均匀的放置,然后进行自适应放置,检查 Probe 网格中的像素是否可被插值,即 4 个 Corner Probe 是否被当前像素遮挡,如果是则在当前像素位置上增加一个 Probe,如此迭代,每次迭代增加一倍分辨率,直到插值差值失败的像素很少或达到指定的分辨率阈值。如下图所示,橘红色为差值失败的像素:
Voxel Lighting
Lumen的Voxel Lighting存储的是较粗颗粒度的空间光照信息(应该6轴向的光照信息)。从采样Radiance Cache获得。为了精确,采用了和Surface Cache一样的世界坐标6轴向对齐方案。最后通过采样3轴向的光照数据,再根据Ray方向进行权重插值取得结果。
为了进一步优化性能减少内存,Lumen 还为 Voxel Lighting 生成了 Clipmap,用于覆盖不同范围,这样可以根据采样点所在的 Clipmap 获取光照。通过 Clipmap,Voxel Lighting 可以覆盖从最小 50 米到最大 6.4 公里的范围,默认最大覆盖 400 米。
Voxel Lighting的另一个用途是用于生成 Indirect Lighting,这就是Radiosity Indirect Lighting。
Radiosity Indirect Lighting
实际上严格来说 Lumen 并不是 Ray Tracing,而是 Ray Casting,因为光线在与 SDF 相交后并没有再次 Bounce,因此最多只能产生一次 Bounce 的 Indirect Lighting,为了弥补这一点,Lumen 使用 Radiosity 来生成 Indirect Lighting。
传统的 Radiosity 方法需要将场景划分为 Patch,而 Lumen 已经拥有了粗粒度的 Global DF 以及粗粒度的 Voxel Lighting,因此可以直接从Surface Cache 上射出光线,与 Global DF 进行 Ray Tracing 求交,交点采样上一帧的 Voxel Lighting 后转换为二阶球谐,最后再根据 Normal 计算Diffuse Transfer 球谐系数,计算出最终的 Indirect Radiance。
这个Indirect Radiance也保存在Radiance Cache中,称为Indirect Lighting,并与Direct Lighting 合并计算得到最终的 Final Lighting,而下一祯的 Voxel Lighting 又来自于这一祯的 Radiance Cache,因此后续所有的 Lumen 光照流程自然具有了间接光照。
World Space Probe(当Global DF求交失败时进行采样)
尽管 Voxel Lighting 可以Trace到更远距离的光照,但对于远光(Distant Lighting)会更容易出现噪点,因为小而亮的特征产生的噪声会随着该特征的距离增加而增加,另外还存在着长距离 Tracing 的性能问题,并且距离的长短不均匀变化也会导致 Tracing 性能的不稳定。
Lumen 使用了单独的采样方案来解决这个问题,这就是Word Space Probe。通过在世界空间中布置 Probe,向各个方向上对 Global DF Tracing,对 Voxel Lighting 进行采样并缓存下来,这样就得到了 Word Space Probe 的 Radiance Cache。
乍看起来这与传统的 Irradiance Field 很相似,但不同之处在于 Word Space Probe 在Screen Probe 周围分布 8 个 Probe,因此是稀疏的放置的,另外由于 World Space Probe 与视角相关,为了优化性能也使用了 Clipmap,每个 Clipmap 的 World Probe 数量相同,但范围不同,默认 4 级最大可设置为 6 级。下图为 World Space Probe 的可视化视图,可以明显看到 Probe 在 Clipmap 中的稀疏分布:
当 Global DF Tracing 失败时,可以快速查找 Screen Space Probe 周围的 8 个 Word Space Probe,在 Ray 方向上对 Word Space Probe Radiance Cache 采样,三线性插值混合这些 Radiance,从而得到最终的 Distant Lighting,这种方式使光照更加稳定,大大缓解了噪声。此外,还可以与采样的 Voxel Lighting 进行插值混合,使光照过渡更加平滑。下图是 Radiance Cache 对比图,左图关闭,右图开启:
Importance Sampling
Lumen 引入了业界降噪常用的方法:重要性采样(Importance Sampling),通过使用上一帧的 Radiance Cache 作为生成当前帧的光线方向的引导,使光线尽可能朝向光源方向追踪,这样就可以在不增加光线预算的情况下实现了降噪,如下所示:
Shadow
阴影的本质就是光照的可见性。Lumen 为 Surface Cache 标记 Shadow Mask,这样在 Lighting 时直接乘以这个 Mask 即可。Shadow Mask 可以直接使用之前已经生成的Virtual Shadow Map。
但是这并不够完整,原因在于 (Virtual)Shadow Map 的生成是 Camera Visibility相关的,而 Surface Cache 与 Camera Visibility 无关,这会 Surface Cache 的 Shadow Mask 缺失,因此需要对那些没有 Mask 的 Surface 再执行一次 Ray Tracing 来判断光源的可见性。因为 Lumen Scene 已经具有 SDF 表达,因此可直接使用 Mesh Global DF Ray Tracing,其实本质上就是在Surface Cache 上进行 DF Shadowing。
降噪
同目前主流的 RTGI 一样,Lumen 也采用了基于 Temporal Spatial Filter 来降噪,Lumen 的 Temporal Filter 发生在整个 Lumen Pipeline 的最后阶段,而 Spatial Filter 则在各个流程之中已经进行。例如 Screen Space Radiance Cache,访问时在 Probe 空间执行 3x3 的滤波,由于 Radiance Caceh 是 1/16 屏幕大小的,因此 3x3 的 Kernel 相当于屏幕空间 48x48 的 Kernel 大小,这样就以很低的成本实现大 Kernel 的 Filtering。下面是仅使用 Spatial Filter 的对比图,降噪效果明显:
Reflections
为了优化性能 Lumen 实现两种 Reflections 机制,当 Roughness 大于 0.4 时重用Screen Space Radiance Cache的结果,因为这时高光的 GGX Lobe 已经汇聚到 Diffuse 上,而且会自动利用已经做完的 Sample 和 Filtering 结果。当Roughness < 0.4 的反射使用额外的光线进行 Tracing,过程与Indirect Diffuse 类似,也包含了三种 Trace:
- Screen Ray Marching,采样上一帧的 Scene Color。
- Mesh DF Tracing ,采样 Screen Space Radiance Cache。
- Global DF Tracing ,采样 Voxel Lighting 和 World Space Radiance Cache。
最后使用双边滤波器进行降噪输出 。
Translucency Volume GI
Lumen 还为半透明材质及体积雾的 Light Scattering 提供了低分辨率的 GI。
Lumen 将 Frustum 体素化为 Froxel,对可见的 Froxel 执行 Global DF Ray Tracing,采样当前帧的 Voxel Lighting 和 World Space Radiance Cache 获取 Radiance,使用 3D Texture 存储每个 Froxel 的 Radiance,然后使用一定次数的 Spatial Filtering 降噪,最后进行积分转换为二阶球谐系数,用于半透明材质及体积雾来计算 Lighting。
丛越整理的的流程
- Lumen Scene Update
- 根据Mesh Cards生成Surface Cache。
- Lumen Scene Lighting
- Surface Cache Direct Lighting
- Radiosity Indirect Lighting
- Direct Lighting + Indirect Lighting 合并生成Screen Space Probe Radiance Cache。
- 体素化相机范围内场景并根据Surface Cache Lighting生成Voxel Lighting
- 根据 Voxel Lighting 生成 Translucency Volume Lighting。
- Final Gather
- 根据G-Buffer放置Screen Space Probe
- 在每个Screen Space Probe周围放置 World Space Probe 并根据 Voxel Lighting 生成 World Space Probe Radiance Cache
- Screen Tracing,采样前一帧的 Scene Color。
- 在近距离范围内对每个Screen Probe执行 Mesh DF Ray Tracing,采样Screen Space Probe Radiance Cache。
- 在中远距离范围内对每个Screen Probe 执行Global DF Ray Tracing,采样三个方向的 Voxel Lighting,并同时采样 8 个 World Space Probe Radiance Cache 与Voxel Lighting 混合。
- 插值、积分和时序过滤,最终得到 Scene Indirect Diffuse。