本文讨论双向路径追踪算法的理论与实现。
(这篇文章说得不太清晰,一是因为BDPT本来就很难讲,我建议直接去看Veach的PhD thesis,网上的博客之类的直接忽略;二是因为我这段时间花了些精力在毕业设计上,没太多心思去写博客。)
LTE的路径和形式
对场景中表面上的某点和某方向,用表示从点沿方向的射线与场景的首个交点。此时,光线传播方程(light transport equation,LTE)可以写作:
现在我们稍微扩张一下符号的含义:
再结合立体角微元和投影面积微元间的关系,便可以将LTE的积分域改写到场景表面上:
其中:
在和间没有遮挡物时为1,否则为0。现在我们不断把新LTE的左侧代换到它的右侧:
就得到了这样一个和式:
其中指长度为的路径,是光源经段传播过程后为最终结果作出的贡献:
这就是LTE的路径和形式,它的含义是:可以拆成以下部分的和:
- 场景中的自发光经次散射后从点射向的辐射亮度(其实就是点的自发光)
- 场景中的自发光经次散射后从点射向的辐射亮度
- 场景中的自发光经次散射后从点射向的辐射亮度
- ……
- 场景中的自发光经次散射后从点射向的辐射亮度
Measurement Equation
在之前的讨论中,我们总是说:只要对任意和能求解,就算是大功告成了。但是仔细一想:把图像上的每个像素放到场景中都是一个矩形,该像素的颜色和函数之间的联系似乎也不是那么清晰?
事实上,设像素在场景中对应的矩形区域是,的颜色是由穿过的radiance flux决定的,也就是得在上积分。而且不是随便从哪个方向穿过的radiance都能被计入该flux中,只有特定方向的才能抵达摄像机镜头。以最基本的透视摄像机为例,设视点位置为,对像素上的每个点,只有沿着方向穿过的radiance才能计入其中。我们简单粗暴地取这些radiance的均值作为的“颜色”:
在这个例子中,每个点仅对应唯一的方向。在更为一般的摄像机模型中(如需要考虑镜头半径、焦距等),每个可能对应了一个方向的集合,记作立体角函数。中每个方向对的“颜色”贡献可能是不一样的,我们用一个分布函数来表达,称为像素的局部重要性函数,此时可以被写作:
具体到基本透视摄像机的例子里,根据:
可以解得:
我们不妨将像素的局部重要性函数延拓到整个和整个,把以外的对应的函数值规定为0即可。此外,中的分母对每个像素而言都是一个常量,不妨用它归一化一下好了,于是我们得到了这玩意儿:
就是所谓的重要性函数了,用表示的是这样的:
用立体角-面积转换把换成,记原来的为,用表示换出来的上的点,就得到了所谓的Measurement Equation:
现在把LTE的路径和形式代入上式:
其中:
路径采样
从LTE的路径和形式看来,我们可以在路径空间上直接采样路径,以对进行估值。如果我们从摄像机出发一路采样出一条路径,就相当于是在使用路径追踪算法;如果我们从光源出发采样进入摄像机镜头的路径,就相当于是在使用“light tracing”。双向路径追踪则是两者的结合:从摄像机出发采样一条子路径(subpath),同时也从光源出发采样一条子路径,最后将这两条子路径连接起来。想法很简单,难点在于如何计算最后得到的路径的采样概率密度,以及一堆奇奇怪怪的corner cases。
首先描述一下从摄像机出发得到子路径的过程:我们让摄像机发射一条射线,一路按照与场景中其他物体的交点处的BSDF进行采样,且使用轮盘赌策略来结束采样过程。现用来表示该子路径上的点(是镜头上的点),它们附带了一系列概率密度:
和是由摄像机给出的,后续的条件概率则是由每一次BSDF采样所使用的概率密度函数所决定的。注意条件概率中需要把轮盘赌的成功概率也算进去。类似地,对从光源出发的子路径,也有相似的计算过程。
最后,我们把和连接起来构成一条完整路径:
它的throughput值是:
整条路径的采样概率则是上面那一大堆概率密度之积:
路径重用
在刚刚已经推出的方案中,我们每次只采样一条路径,将该路径的throughput除以其概率密度函数值,就可以拿来对估值了。Veach很天才地想到:我们能不能把摄像机子路径的每个前缀和光源子路径的每个后缀都连接起来,从而得到一大堆子路径呢?这样做唯一的问题就是这一组路径间存在相关性,但只要我们重复这样的过程许多次,得到组路径,那么某条长度为的路径和这里面个组中长度为的路径都是无关的。随着的增大,我们仍然可以保证估值无偏地收敛到正确的结果。并且当组数增大时,组内路径的相关性在全体路径中会显得愈发微不足道,即correlation也会收敛到0,不会对结果产生视觉可见的影响。
在使用了路径重用技术后,我们注意到,在每一轮采样(生成两条子路径并连接它们得到一堆路径,这样的过程称为一轮采样)中,一条长度为的路径有个顶点,也就对应了种采样方式。比如一条长度为2的路径有以下三种采样方式:
- 长度为0的摄像机路径和长度为2的光源路径连接起来
- 长度为1的摄像机路径和长度为1的光源路径连接起来
- 长度为2的摄像机路径和长度为0的光源路径连接起来
毫无疑问,这三种采样方式各有其擅长之处。譬如,1其实是light tracing的路径采样方式,擅长计算焦散等现象;3就是native path tracing;2是path tracing的直接照明项。我们能不能把这些采样方式的优点综合起来,而不是粗暴地求和呢?说到这里,一个名词已经呼之欲出了——多重重要性采样。
使用多重重要性采样的要点,在于给定按某种采样策略A得到的采样结果时,如何计算在B、C、D等其他采样策略下对应的概率密度函数值。在这个情景下这个问题其实很好办——沿着路径走一遍,把各种策略下的概率密度都算出来就行了。
几种特殊路径
s != 0, t = 0:采用MIS策略,而不是老老实实地连接什么子路径。连接子路径在这里相当于在以前的路径追踪中使用光源采样来计算直接照明。
s = 0, t != 0:这里连接子路径得到完整路径时,谁也不知道完整路径会对应到图像上的哪个像素去。因此要额外把这部分信息传递出去。这里会对系统的接口设计造成一点影响。
摄像机子路径击中了光源:完全不需要光源子路径的一种特殊情况。
光源子路径击中了镜头:要求镜头本身成为场景的一部分,不打算实现这个。
实现
综上所述,我把BDPT算法分为以下两个步骤:
- 从摄像机和光源分别发射子路径,在子路径长度达到一定阈值后引入轮盘赌策略,记录下每个点相对于前一个点的条件概率。
- 对摄像机子路径的每个前缀和光源子路径的每个后缀,连接它们得到一条完整的路径,计算其throughput和MIS技术下的概率,加到最终结果上。
(施工中……)