结合 SPPM 的 Path Tracing
随机渐进式光子映射(Stochastic Progressive Photon Mapping, SPPM)是光子映射系列算法的进阶算法,本文介绍如何实现 SPPM 以及如何将 SPPM 与路径追踪(Path Tracing, PT)结合。 光子映射系列算法 光子映射 光子映射(Photon Mapping, PM)是光子映射系列算法中的初代算法,是一个两阶段算法,包括光子追踪和光子映射。其思想就是首先从光源发射光子,光子在场景中不断反弹,模拟现实世界的过程,然后再使用 Path Tracing,过程中在合适的地方使用光子来估计 radiance,加速渲染。 光子的发射 光子是光源的通量/功率的载体,光源实质上是通过发射光子来实现照明。PM 中的光子与物理中的光子不同,物理学中的光子是光能传递的最小单元,即量子化的性质,单个光子的能量是 $E = h\nu$,而 PM 中的光子实际上是一堆物理中的光子,是更符合应用的模型。所以,接下来所讨论的光子都是 PM 意义下的光子。 如何计算单个光子的通量呢?发射光子的过程实际上就类似于对光源的总通量进行 Monte Carlo 估计的过程,每个光子都是一个样本,每一份通量相加就得到了总通量。所以我们就对光源表面和出射方向进行采样,按照类似的过程计算每一个光子的通量。总通量按照以下积分计算 $$ \begin{aligned} \Phi & = \int_M \int_{\Omega^+} L_e(x, \omega) (n \cdot \omega) \mathrm d\omega \mathrm dA \\ & \approx \dfrac{1}{N} \sum_{i = 1}^N \dfrac{L_e(x, \omega) (n \cdot \omega)}{p(x)p(\omega)} \end{aligned} $$所以单个光子的通量就是 $\dfrac{1}{N} \dfrac{L_e(x, \omega) (n \cdot \omega)}{p(x)p(\omega)}$,$N$ 表示被发射光子的总数。严格意义上来说,通量的定义是不考虑立体角和照明面积的,所以所谓的单个光子的通量实际上是通量的二阶差分 $\Delta^2 \Phi$。在实际实现中,我们在计算通量时并不会除以 $N$,这是因为在 SPPM 中光子数量会随着迭代次数增加而增加,因此我们也将其 $\dfrac{L_e(x, \omega) (n \cdot \omega)}{p(x)p(\omega)}$ 视为一种没有放缩的通量,直到最后再除以 $N$ 得到真正的通量。 ...