本人水平有限,若有错误也请指正~
前文提及了光线追踪的一些常用手法,但是其中path tracing的实现最为简单,但是其最致命的一个缺点就是图像收敛速度很慢。。原因在于从摄影机发射出的每一条光线若不与场景中的光源相交,则这条光线就是无贡献的,或者遇到了一个漫反射表面,该表面反射环境光的值很低,这时候这条光线就成为了一条低贡献的光线,同时也可能增加整体图像的噪点数量。
这时候bidirectional path tracing提出了,其基本思想是从摄影机和光源两个视角出发,如下图所示,
光线分别从视点和光源出发,我们不妨将视点发出的光线为采样光线,光源发出的称为实际光线,该算法即是取采样光线与场景的每一个交点,这些交点与实际光线与场景的每一个交点形成一条连线,对每一条连线应用BRDF,再将这些多个采样值进行加权求和得到一个像素在一次迭代中的采样,这样做实际上提高了每条光线的贡献度,使得图片收敛的速度更快,但是里面仍有一些算法细节还是比较困惑:
1)当场景中存在很多遮挡,例如发生如下情况(这种情况也很常见),
当连线与场景中的一个障碍物有交点时(图中虚线),这时候我们应该在虚线所代表的那个采样值的权重设为0,使得这条虚线不会对最终的采样造成影响。这个方法对于那些障碍物是不透光的实体是可行的,但是如果障碍物是一个透光物体,该如何处理?按理讲应该还是应当将其权重设为0,因为虚线两端连接的光线是无法一次到达的(透光物体折射使得光线偏转,而偏转后的光线再次到达虚线另一端的概率为0),但是设为0着实不太合适,因为如下情况发生也是有可能的:
如上图绿线标注的那样,这条连线也可以使A对A'的采样值产生贡献,但是这时候的贡献权重就很难计算,况且很多情况下的透光物体不像图中那么规则,这时候权重的求解就更麻烦。通过一些hack的方式可以弥补这种情况带来的误差,但是如果hack手段用得多了,就失去了图形渲染的意义(毕竟我们要将正确性放在首位,不然就与那些实时交互性强的游戏没其它优越性可言了。。。)如果简单暴力的将权重置为0,那么会使得图像与真实图像来得暗,而且对于如下的极端情况处理的也不好:
上图中的所有虚线的贡献均为0,使得该采样值为0,这样的误差就比较大了。
2)能量是否守恒
如上图,从视点发射出的两条光线的采样值(图中两条与光源的灰色连线)会产生相同的贡献度,在像素的呈现上就会呈现相同的颜色,这是不对的,要解决这个问题就需要引入距离权重,会使得求解方程的形式更复杂,同时距离权重的引入还要处理好能量守恒的问题。这一方面看起来也是挺麻烦的。。。
以上就是学习bidirectional path tracing后的一些困惑。。从其他利用了bdpt算法的人渲染出的图片来看,他们处理上述情形处理的很好,不知道用了何种补偿措施,希望知道如何处理的大神们给出一条指导性的建议~