Processing math: 100%

PathTracing

渲染方程:

Lo(p,wo)=Le(p,wo)+Ω+Li(p,wi)fr(p,wi,wo)(nwi)dwi

通过解渲染方程,可以得到正确的算法。

但它有以下两个难点:

  1. 公式的第二项是一个定积分,比较难求,可以使用Monto Calio方法解出它的近似值。
  2. 这是一个递归公式。

用 Monto Calio 方法解定积分

场景1[32:18]

先考虑一个简单场景:

只考虑这一个着色点、只考虑直接光照、且被照射点不发光。
有一个物体会遮住部分、有一个较大的面光源。
入射光线为上半球所有Wi,且均匀分布。出射光线为 Wo。
求这个点接收到并向wo辐射的能量。

根据渲染方程,有:

Lo(p,wo)=Ω+Li(p,wi)fr(p,wi,wo)(nwi)dwi

由于本场景假设只考虑直接光照,那么Li(p,wi)只来自于光源。

用Monto Carlio解定积分,假设使用均匀采样,将公式代入以上公式,可将连续问题转化为离散问题,得到:

采样函数积分函数积分结果
理论上Xkp(x)f(Xk)1Nf(Xi)p(Xi)
实际上12πLi(p,wi)fr(p,wi,wo)(nwi)
均匀采样
2πNLi(p,wi)fr(p,wi,wo)(nwi)

其中wi来自采样

💡 连续问题往往比较难解。通过采样的方式把连续问题转化为离散问题,这样就只是需要考虑几个离散的点,就要好解得多。这是复杂问题简单化的一个思路。

场景2[40:40] 引入间接光照

P接收到的辐射不一定来自光源,也可以来自Q。
P接收到的来自Q的辐射 = Q向P发出的辐射。
对于P来说,辐射是来自直射光还是反射光,没有区别。

Lo(p,wo)1Nfunc(wi)1/2π

当wi来自光源时,

fun=LiFrcos

当wi来自其它物体q时,

fun=shade(qwi)frcos

场景3:一根光线会向多个方向弹射

[46:48] 光线路径数rays=Nbouns 这个量级下计算量会爆炸

因此取 N = l (即 path tracing),才不会发生爆炸。

即:每次使用Monto Calio求定积分时,只做一次采样。

虽然N取1会导致这个path在求定积分这一步引入较大的噪声。但是穿过像素的不止这一个path。[49:4] path足够多时,多个path的平均会缓解N=1带来的噪声。

如何解递归问题

从公式或者从上面的伪代码都能看出,这是一个递归问题。
递归本身不是问题。问题是这里的递归没有停止条件,会无限地递归下去。

人为定义 bounce 的次数

人为定义 bounce 的次数,当光线bounce这么多次(或者说递归到这个深度)后就强行停止。

这种方法能解决无限递归的问题,但会带来能量的损失。

Russian Roulette 俄罗斯轮盘赌

即不明确定义次数,而是以一定概率p决定是否继续 bounce。以此算出能量Lo。
最后使用Lo/p该点输出的能量。
这个结果的期望与无限 bounce 的理论结果相同,因为:
E = P * (Lo/ P) + (1-P) * 0 = Lo

到目前为止,已经得到一个正常的path tracing流程了。


本文出自CaterpillarStudyGroup,转载请注明出处。
https://caterpillarstudygroup.github.io/GAMES101_mdbook/