路径追踪与重要性采样

重要性采样和多重重要性采样在路径追踪中的应用 - 知乎

本文是作者对路径追踪中的重要性采样原理和实践的笔记。

重要性采样

设积分

\[ L_o(\boldsymbol x, \boldsymbol \omega_o) =\int_{\Omega} L_i(\boldsymbol x, \boldsymbol \omega_i) f_r(\boldsymbol x, \boldsymbol \omega_o, \boldsymbol \omega_i) (\boldsymbol \omega_i \cdot \boldsymbol n)_{+} \, \mathrm d \boldsymbol \omega_i. \]

我们有蒙特卡洛方法计算和分(离散蒙特卡洛积分)的一般公式

\[ \int_I f(x) \, \mathrm dx \approx \frac{1}{N} \sum_{i=1}^N \frac{f(X_i)}{p(X_i)}, \]

其中 \(X_i \sim p(x)\)

那么,我们令

\[ f = L_i(\boldsymbol x, \boldsymbol \omega_i) f_r(\boldsymbol x, \boldsymbol \omega_o, \boldsymbol \omega_i) (\boldsymbol \omega_i \cdot \boldsymbol n)_{+} \]

然后找到一个 PDF \(p(x)\),即可对给定的反射点 \(\boldsymbol x\) 和出射光线 \(\boldsymbol \omega_o\),在变量 \(\boldsymbol \omega_i\) 上进行蒙特卡洛积分

\[ L_o(\boldsymbol x, \boldsymbol \omega_o) \approx \frac{1}{N} \sum_{i=1}^N \frac{L_i(\boldsymbol x, \boldsymbol \omega_i) f_r(\boldsymbol x, \boldsymbol \omega_o, \boldsymbol \omega_i) (\boldsymbol \omega_i \cdot \boldsymbol n)_{+}}{p(\boldsymbol \omega_i)}. \]

在 MCPT 中,一般 \(N = 1\),即在一个像素采样过程中,对当前表面仅发射一个光线。通过在同一像素点发射多根光线的方式进行平均,可以达到 \(N\) 较大时类似的效果,且也能解决锯齿问题。对分布式光线追踪,\(N\) 可能不为 1。

均匀半球采样

由于半球的面积为 \(2 \pi\),而采样相当于在这个面积中均匀取一个点,故均匀采样的 PDF 为

\[ p(\boldsymbol \omega_i) = \frac{1}{2 \pi}. \]

光源的重要性采样

我们可以直接采样光源,以避免无头苍蝇般地均匀采样,获取显著的效率提升。

设当前反射点为 \(\boldsymbol x\),面光源的采样点为 \(\boldsymbol x'\),根据单位立体角的定义,有

\[ \mathrm d \boldsymbol \omega = \frac{\mathrm dA}{||\boldsymbol x - \boldsymbol x'||^2} \]

其中 \(\mathrm d A\) 为单位立体面的面积。若面光源为矩形面光源,则我们还需要将其投影到矩形面上。记光源的法向为 \(\boldsymbol n'\),则

\[ \mathrm d A = \mathrm d S \cdot (\boldsymbol n' \cdot - \boldsymbol \omega_i)_+ \]

其中 \(\mathrm d S\) 为单位矩形面的面积。整合得到

\[ L_o(\boldsymbol x, \boldsymbol \omega_o) = \int_{\Omega} L_i(\boldsymbol x, \boldsymbol \omega_i) f_r(\boldsymbol x, \boldsymbol \omega_o, \boldsymbol \omega_i) \frac{(\boldsymbol \omega_i \cdot \boldsymbol n)_{+} \cdot (-\boldsymbol \omega_i \cdot \boldsymbol n')_{+}}{||\boldsymbol x - \boldsymbol x'||^2} \, \mathrm d A \]

那么,我们在用蒙特卡洛积分时,就可以在均匀面光源上采样,即 PDF 为

\[ p(\boldsymbol \omega_i) = \frac{1}{A}, \]

其中 \(A\) 为该面光源的面积。

或等价地,使用原式

\[ L_o(\boldsymbol x, \boldsymbol \omega_o) \approx \frac{1}{N} \sum_{i=1}^N \frac{L_i(\boldsymbol x, \boldsymbol \omega_i) f_r(\boldsymbol x, \boldsymbol \omega_o, \boldsymbol \omega_i) (\boldsymbol \omega_i \cdot \boldsymbol n)_{+}}{p(\boldsymbol \omega_i)}, \]

令 PDF 为

\[ p(\boldsymbol \omega_i) = \frac{||\boldsymbol x - \boldsymbol x'||^2}{(-\boldsymbol \omega_i \cdot \boldsymbol n')_{+}} \cdot \frac{1}{A} \]

亦可。

如果有多个面光源,简单的方法是均匀随机地取一个面光源采样即可。也可以进一步地,在光源这方面做分层采样(stratified sampling)。

最后,我们可以累加光源采样部分的 \(L_o\) 和间接光照采样部分的 \(L_o\),获得最终的 \(L_o\)

光源的分层采样

设场景中有若干个面光源,它们的功率、位置与面积不同。简单地每次均匀随机地取一个面光源采样显然是有偏的,会引入较大的方差。

因此,我们可以考虑根据光源功率与面积的乘积加权进行采样,这样高贡献的光源就更容易被选中。在实践上,这也更接近无偏的结果。

均匀采样面光源

选中了面光源之后,我们还需要从该面光源中随机选择一点,作为光线来源的采样点。通常的算法都需要在该面光源中获取均匀随机一点,以避免引入偏差。

因此,需要注意实现对三角形、圆面和球面等的均匀随机采样算法。一些很朴素的采样算法得到的结果并不是均匀的,需要仔细设计。

BRDF 的重要性采样

对 BRDF 的重要性采样的一般思路是,让 PDF \(p(\boldsymbol \omega_i)\) 正比于 \(f_r(\boldsymbol x, \boldsymbol \omega_o, \boldsymbol \omega_i) (\boldsymbol \omega_i \cdot \boldsymbol n)_{+}\)

在理想情况下,让 PDF 直接解析地正比于 \(f_r(\boldsymbol x, \boldsymbol \omega_o, \boldsymbol \omega_i) (\boldsymbol \omega_i \cdot \boldsymbol n)_{+}\),可以取得完全正确的结果,即蒙特卡洛积分与求和之间取等号。但一般情况下,无法做到完全正比,只能做到大致走向一致。

例如,在 PBR 模型中,包含 diffuse 和 specular 两项,两者可以分别采样。

  • 对于 diffuse,只需让 PDF 正比于 \((\boldsymbol \omega_i \cdot \boldsymbol n)_{+}\) 即可,这不难。
  • 对于 specular,其中有 DFG 三项,只能让 PDF 正比于法线分布函数(NDF)\(D\)

推导出相应的 PDF \(p_d, p_s\) 后,需要将它们用系数整合成完整的 PDF

\[ p = k_d p_d + k_sp_s, \]

其中 \(k_d + k_s = 1\)。具体使用哪个 PDF 采样,可以使用运行时随机数 \(u \sim U(0,1)\) 决定。

当使用一些会计算 metallic \(m\)\(F_0\) 的 PBR 模型时,可以重新考虑 BRDF 的采样系数,即 \(k_s\) 可能与 \(F_0, m\) 等系数均有关。

在重要性采样中,采样 GGX 等 NDF 的计算量很大。只有 Blinn-Phong 的 NDF(经过了某种归一化)

\[ D(\boldsymbol \omega_h) = \frac{\alpha + 2}{2 \pi} (\boldsymbol \omega_h \cdot \boldsymbol n)_{+}^{\alpha} \]

在采样上有比较解析的方法,因此计算量最小,也是作者的 Path Tracer 实现的唯一材质类型。

结合光源采样和 BRDF 采样——多重重要性采样(MIS)

可能出现这种情况:

  • 在某些光滑金属区域,采样光源位置函数的结果很难贡献到近似冲激函数的 BRDF 上,因此产生噪点状的结果。
  • 在某些粗糙区域,采样正比于 BRDF 函数的结果很难命中极小的光源,因此产生噪点状的结果。

因此,可以用某个权重函数把两种重要性采样的 PDF 结合起来,形成新的 PDF

\[ \begin{aligned} L_o(\boldsymbol x, \boldsymbol \omega_o) & \approx \frac{L_i(\boldsymbol x, \boldsymbol \omega_i) f_r(\boldsymbol x, \boldsymbol \omega_o, \boldsymbol \omega_i) (\boldsymbol \omega_i \cdot \boldsymbol n)_{+}}{p(\boldsymbol \omega_i)} \\ &= w_1(\boldsymbol \omega_1) \frac{L_i(\boldsymbol x, \boldsymbol \omega_1) f_r(\boldsymbol x, \boldsymbol \omega_o, \boldsymbol \omega_1) (\boldsymbol \omega_1 \cdot \boldsymbol n)_{+}}{p_1(\boldsymbol \omega_1)} + w_2(\boldsymbol \omega_2) \frac{L_i(\boldsymbol x, \boldsymbol \omega_2) f_r(\boldsymbol x, \boldsymbol \omega_o, \boldsymbol \omega_2) (\boldsymbol \omega_2 \cdot \boldsymbol n)_{+}}{p_2(\boldsymbol \omega_2)} \end{aligned} \]

常用的权重函数为 power-heuristic:

\[ w_s(\boldsymbol \omega_i) = \frac{p_s^{\beta}(\boldsymbol \omega_i)}{\sum_{j=1}^2 p_j^{\beta}(\boldsymbol \omega_i)}. \]

其中 \(\beta\) 为自定义参数,一般 \(\beta = 2\) 效果较好。这样的结果是有偏的,但可以取得较低的方差,快速降噪。

如果希望取得无偏的结果,可以设 \(\beta=1\),但方差较大。

科学地中断递归

在 path tracing 的过程中,单纯地限定最大递归深度会使图像整体损失能量(亮度偏低)。因此,建议使用俄罗斯轮盘赌的方法,取得期望正确的能量结果。

方法1

俄罗斯轮盘赌。即事先规定一个概率 \(p\),它将成为在当前表面,是否要采样 \(\boldsymbol \omega_i\) 计算 \(L_o(\boldsymbol x, \boldsymbol \omega_o)\) 的凭据。

即,每次计算 \(L_o(\boldsymbol x, \boldsymbol \omega_o)\) 前,生成 \(u \sim U(0,1)\)

  1. \(u < p\),则跟随光线 \(\boldsymbol \omega_i\),计算本次 \(L_o(\boldsymbol x, \boldsymbol \omega_o)\),且可能还要继续跟随光线 \(\boldsymbol \omega_i\) 的表面,计算 \(L_o(\boldsymbol x, \boldsymbol \omega_i)\)。但最终函数返回,赋值时使用 \(L_o(\boldsymbol x, \boldsymbol \omega_o)= L_o(\boldsymbol x, \boldsymbol \omega_o) / p\)
  2. \(u \geq p\),则终止递归,并令 \(L_o(\boldsymbol x, \boldsymbol \omega_o) = 0\)

综合考虑,每个 \(L_o(\boldsymbol x, \boldsymbol \omega_o)\) 的计算期望为

\[ p \cdot L_o(\boldsymbol x, \boldsymbol \omega_o) / p + (1-p) \cdot 0 = L_o(\boldsymbol x, \boldsymbol \omega_o). \]

因此不会损失能量。

缺点:\(p\) 较大时,期望递归数较多,且不可控制。

方法2

使用 throughput,考虑衰减的同时,让递归终止条件更科学。

monte carlo - Is Russian Roulette really the answer? - Computer Graphics Stack Exchange