图形学(8)Path Tracing Algorithm
蒙特卡罗算法
注意到对于一个连续随机变量 \(X\sim p(x)\),则 \(q(X)\) 的期望 \(E[q(X)]=\displaystyle\int q(x)p(x)\mathrm d x\)。
若要求积分 \(\displaystyle\int f(x)\mathrm dx\),令随机变量 \(X\sim p(x)\),则 \(\displaystyle E[\frac{f(X)}{p(X)}]\) 即为所求,即有
Path Tracing
用蒙特卡洛解渲染方程即可,但有以下几点问题亟待解决:
- 每次计算积分要进行多少次采样
- 在封闭环境对渲染方程求解会导致无限递归
对于问题一,由于每次采样 \(\#R\) 次,反射 \(N\) 次后有 \(\#R^N\) 条射线,复杂度指数级增长,故在 Path Tracing 算法中每次只追踪一条射线,\(\#R=1\)。
对于问题二,可以采取俄罗斯轮盘赌的方法,每次追踪有 \(P\) 的概率继续追踪,\(1-P\) 的概率结束追踪,若后续追踪得出的正确答案为 \(L_o\),则进行俄罗斯轮盘赌后实际计算得到的结果期望是 \(E=PL_o+0(1-P)=PL_o\),故要除掉一个 \(P\) 保证算法结果的期望是正确的。
令函数 shade(p,wo)
表示计算点 p
在 wo
方向的亮度(颜色),有伪代码:
shade(p,wo)
L_emit = self emit
L_indir = 0.0
Test Russian Roullete with probability P_RR
Sample the hemisphere with PDF pdf_hemi and generate a ray r
Trace the ray r
if ray r hit a object at q
L_indir = shade(q,-r) * brdf * cosine / pdf_hemi / P_RR
return L_emit + L_indir
直接光采样
蒙特卡洛的期望是正确的,但是不同的概率密度函数可以使蒙特卡罗更快的收敛,是我们在相同时间内得到质量更好的图像。事实上概率密度函数和被积函数越相似,收敛越快。
注意到由光源直接到 shading 处的贡献是很大的,我们把这一部分从渲染方程里面拆出来:
如果光源很小,那么在 \(H^2\) 上进行蒙特卡罗是很浪费的:很多采样射线不经过光源,导致收敛很缓慢。注意到蒙特卡罗的概率密度函数是任取的,我们直接在光源上采样:
所以有
用蒙特卡洛积分即可。举个例子,对于亮度恒定为 \(L\),面积为 \(a\) 的面光源照射到 \(f_r=\frac{1}{\pi}\) 的理想漫反射物体上,进行一次均匀的蒙特卡罗采样得到的积分结果为
shade(p,wo)
L_indir = 0.0
L_dir = 0.0
For all light
Sample the Light with PDF pdf_light
L_dir += L_i * f_r * cos theta * cos theta' / d ^ 2 / pdf_light
Test Russian Roullete with probability P_RR
Sample the hemisphere with PDF pdf_hemi and generate a ray r
Trace the ray r
if ray r hit a object at q
L_indir = shade(q,-r) * brdf * cosine / pdf_hemi / P_RR
return L_emit + L_indir