4. Lumen - Screen Probe

1 概述

2 宏观逻辑

3 实现

screen probe 的更新逻辑入口 RenderLumenScreenProbeGather

3.1 放置

3.2 重要性采样

重要性采样的入口函数 GenerateImportanceSamplingRays

3.2.1 PDF 估计

基于上一帧radiance的重要性采样

3.2.2 采样光线样本

具体实现在 shader ScreenProbeGenerateRaysCS

光线样本写入 RWStructuredImportanceSampledRayInfosForTracing,该buffer是按照screen probe以及probe分辨率排列的 atlas,但由于重要性采样某个球面texel的位置可能被重用给其它texel,因此buffer每个元素(uint) 记录了 PackRayInfo(SourceTexelCoord, SourceLevel)

在后续过程中,使用 screen probe index 可以得到 screen probe 在 atlas 中的位置,再加上 trace texel coord 可以定位一个光线样本位置 TraceBufferCoord,之后可以使用 StructuredImportanceSampledRayInfosForTracing[TraceBufferCoord] 得到实际的光线信息 RayInfo,包含了其实际采样位置

3.3 追踪

screen probe 的追踪是一个分阶段的过程,

  1. 屏幕空间追踪。对未找到交点的样本紧凑排列,送入下一阶段
  2. near field 追踪。CompactTrace,送入下一阶段
  3. far field 追踪。采样 radiance cache 或者 trace

3.3.1 样本排列

每个阶段对剩余样本的紧凑操作,将未得到交点的样本送入下一阶段。为了紧凑排列后还能找到样本所属probe,每个样本都会编码如下信息

1
2
3
4
uint EncodeScreenProbeTraceTexel(uint ScreenProbeIndex, uint2 TraceTexelCoord)
{
return (ScreenProbeIndex & 0xFFFFF) | ((TraceTexelCoord.x & 0x1F) << 20) | ((TraceTexelCoord.y & 0x1F) << 25);
}

具体实现在 shader ScreenProbeCompactTracesCS,每个group负责一个screen probe,每个线程负责一个光线样本:

  1. 从 buffer TraceHit 中读取是否已有交点
  2. 可以在group/subgroup内计算前缀和,将未得到交点的样本紧凑排列到 RWCompactedTraceTexelData

3.3.2 Trace Screen

具体实现在 shader ScreenProbeTraceScreenTexturesCS 中,每个group负责一个screen probe,每个线程负责一个光线样本:

  1. 根据 ScreenProbeIndex 获取屏幕空间位置 GetScreenProbeScreenPosition

    • NumUniformScreenProbes 范围内属于 uniform probe,因此可以直接变换为 uniform tile coord,再基于帧数抖动即可
    • NumUniformScreenProbes 范围外属于 adaptive probe,从 AdaptiveScreenProbeData buffer 中提取 ScreenProbeScreenPosition
  2. 构建当前线程的光线样本

    • 光线起点,ScreenProbeScreenPosition 变换为世界坐标
    • 光线方向,GetScreenProbeTexelRay。从 StructuredImportanceSampledRayInfosForTracing 得到实际的 probe texel,使用球面映射得到光线方向
  3. 执行屏幕空间追踪

    • 如果 hit,将交点投影回上一帧。计算 view_z,prev_view_z,如果二者差距大,则 hit = false。因为 ssrt 需要采样 prev_scene_color,需要剔除掉交点为去遮挡区域的情况
      1
      2
      // HistoryDeviceZ 是使用 motion vector 投影到上一帧的深度,PrevDeviceZ 是通过变换到上一帧得到的深度
      bHit = abs(HistoryDeviceZ - PrevDeviceZ) < HistoryDepthTestRelativeThickness * lerp(.5f, 2.0f, Noise);
  4. 如果 bHit

    • WriteTraceHit。结果写入 RWTraceHit,分辨率与 StructuredImportanceSampledRayInfosForTracing 一致,即 screen probe atlas。
      hit 结果编码了 HitDistance, bHit, bMoving, bReachedRadianceCache 到一个float
    • 采样上一帧 scene color,写入 RWTraceRadiance,分辨率为 screen probe atlas

3.3.3 near-field 世界空间追踪

具体实现在 shader LumenScreenProbeGatherHardwareRayTracing,遍历的是 CompactedTraceTexelData ,每个线程一个光线样本。


4. Lumen - Screen Probe
http://example.com/2025/04/27/Render Engine/UE5/Lumen/4. Screen Probe/
Author
John Doe
Posted on
April 27, 2025
Licensed under