路径追踪是一种光线追踪方法,原理是:

从视点向像素点发出若干直线,这些直线会碰撞到光源或者物体,如果碰撞光源,得到能量L;如果到物体,从碰撞点继续发出一条直线(模拟光线反弹),收集到能力O。如此循环,直到没有碰到光源或物体。把所有的能量L和O积分,即得到这个像素的总能量。

先说最终最优的表达式和伪代码:

python 光束追踪 光线跟踪算法_递归

 

采样一条路径所收集到的能量,用伪代码表示为:

python 光束追踪 光线跟踪算法_python 光束追踪_02

 

 

 采样多次,则为“从视点向像素点发出若干直线”

python 光束追踪 光线跟踪算法_像素点_03

 

 

 回到采样一条路径,所收集的能量可以分成2部分,一是从面光源得到的能量L,二是从其他物体上反射来的能量O。

能量L的公式为:

python 光束追踪 光线跟踪算法_像素点_04

python 光束追踪 光线跟踪算法_像素点_05

 代表光线的强度,跟光源的功率和物体离光源的距离正相关;

 

 

 

python 光束追踪 光线跟踪算法_python 光束追踪_06

 代表BRDF,即物体表面的材质对光线的反射量;

 

 

python 光束追踪 光线跟踪算法_伪代码_07

 代表对光源面积积分,因为蒙特卡洛积分原本是对半球的立体角进行积分,现在要转换成对光源的面积进行积分,因此需要一个转换公式。这个公式对应的操作,首先需要先把光源面转到正对着反射点,因此需要乘cosθ`;然后再除以光源到反射点距离的平方,即

 

 

 除以

python 光束追踪 光线跟踪算法_python 光束追踪_08


 

 

能量O,则是从物体再发出一条直线,通过递归的方式获得。为了避免一直碰到物体出现递归死循环的情况,用俄罗斯轮盘赌(P_RR)的方式在截断递归。即碰到物体后有一定概率P继续发射一条直线,有1-P的概率停下来不发射直线。继续发射后收集到的能量值除以概率P,这样总的能量期望不变。例如有50%概率发射一条直线,收集到的能量除以0.5。

python 光束追踪 光线跟踪算法_伪代码_09