Lightmass分析(四) 光子追踪

Intro

Lightmass分析 系列文章前言及目录

Lightmass 借用 Photon Mapping 算法生成保存全局光照信息的光照贴图. 本文将着重介绍 Lightmass 的光子追踪部分.

光子追踪的主要工作是: 发射直接光子, 发射间接光子, 缓存物体表面各处的光照结果. 在 Lightmass 中计算光子的 Irradiance 之前还会对光子进行标记和缓存操作. 这些预先的操作目的是根据空间关系先对光子进行一次筛选, 减少无用的光子计算, 提高运行效率, 并为后面的流程做数据准备.

发射直接光子

直接光子的生成过程比较简单. 从光源发射一定数量的光线并与场景求交, 所得的交点就是直接光子的位置并可以根据场景光源计算出光子所对应的 power.

另外在得到直接光子之后, Lightmass 还会根据光子所在表面的 BRDF 属性产生一组被称为 IndirectPath 的射线, 这组射线会决定是否需要产生间接光子以及产生间接光子时采样光线的方向.

Lightmass分析(四) 光子追踪_第1张图片

发射间接光子

间接光子的生成过程与直接光子的类似, 只不过间接光子会开始考虑光子接触表面后的反弹等行为. 需要注意的是为了更好的间接光照效果, 间接光子并没有在上一步产生的直接光子基础上继续生成. 而是以更大的密度重新产生了一遍直接光子, 并在此基础上生成间接光子. 另外因为第一次反弹和后续反弹在计算辐照度时的贡献权重不同, 这里会将间接光子分成两个光子图分别保存.
Lightmass分析(四) 光子追踪_第2张图片

标记 IrradiancePhoton

这里标记的是 IrradiancePhoton 是否存在存在直接光照的贡献, 这可以通过判断当前光子一定范围内是否存在Direct Photon来确定 (这也体现出我们将光子图一分为三的意义). 这个指标会影响当前 IrradiancePhoton 的搜索范围, 存在直接光照贡献的 IrradiancePhoton 搜索范围会更小, 也就是在空间中某点处查找其周围的光子时更不容易被找到. 或者说有直接光照贡献的 IrradiancePhoton 影响范围要小一些.

将 IrradiancePhoton 缓存到对应的 TextureMapping 中

这里我们需要遍历 TextureMapping 中记录的物体表面上的每一个点, 为此我们需要对其进行光栅化操作. 获取到当前顶点之后查找其一定范围内与其距离最近的 IrradiancePhoton, 如果存在则将此光子记录在 TextureMapping->CachedIrradiancePhotons 中并将此光子标记为已使用. 在后面计算光子的辐照度时, 如果光子没有被标记为已使用, 则直接跳过计算. 这其中的逻辑在于: 没有被标记为已使用的光子意味着在空间上他没有影响任何一个表面, 所以不需要计算.

另外需要注意的是我们遍历每一个位置查询与其距离最近的光子, 由于光子本身是离散的, 这就形成了一定范围内的模型表面都受到同一个光子的影响.

计算 IrradiancePhoton 的 Irradiance

这里我们会遍历之前所有的 IrradiancePhotons, 跳过未使用的光子, 然后计算光子的 Irradiance. 光子的 Irradiance 涉及直接光照贡献, 第一次反弹贡献和第二次及后续反弹贡献三部分.

其中直接光照部分在默认设置下在这里不起作用. Lightmass 通过 CalculatePhotonIrradiance 方法计算光子的 Irradiance. 他首先寻找目标光子一定范围内的所有光子, 然后对这些光子使用 ConeFilter 计算出当前光子的 Irradiance 并更新当前光子.

需要注意的是我们上一步缓存的是 IrradiancePhoton 的指针, 这里的修改也就自动同步到了 TextureMapping->CachedIrradiancePhotons 中.
Lightmass分析(四) 光子追踪_第3张图片PS: 从图中可以看出现在缓存的光照明显呈现色块效果

缓存物体表面各处的光照结果

我们之前已经缓存了模型表面受到的间接光照值, 接下来我们再将直接光照的结果也应用到缓存中就可以得到完整的光照缓存.

为此我们需要先遍历物体表面上的每一个点(和之前一样通过光栅化来实现这个空间上的遍历). 这时我们之前缓存的 CachedIrradiancePhotons 开始发挥作用. 由于 CachedIrradiancePhotons 和光栅化之后的 TexelToVertexMap 是一一对应的, 那么我们在遍历 TexelToVertexMap 时就可以直接通过下标判断对应空间位置上是否存在光子并获取光子的 Irradiance.

这一步会将光子的 Irradiance 数据, 直接光照阴影信息和模型表面材质整合到一起并保存到 TextureMapping->SurfaceCacheLighting 中. 不过这时的光子还没有对其周围的环境产生影响, 光子对环境的作用还需要通过最后的 Final Gather 确定.
Lightmass分析(四) 光子追踪_第4张图片

参考文献

Jiff:Lightmass分析之 经典Photon Mapping算法介绍
Jiff:LightMass源码分析之光子追踪实现
Jiff:LightMass源码分析之光照评估

你可能感兴趣的:(Unreal,Lightmass)