Q89:全局光照(Global Illumination)——Path Tracing(只用于间接光照)

来源:互联网 发布:淘宝小二是什么意思 编辑:程序博客网 时间:2024/06/13 14:45

 

89.1 Path Tracing只用于间接光照

 

根据Path Trace的算法,只有当最终的反射光线撞击到发光材质物体时,才会对最初的撞击点进行“有效”着色,否则着色为“黑色”。这就给图形带来大量的噪声。所以,接下来,我们只将Path Tracing算法用于间接光照;而直接光照部分,则是直接对面积光源进行采样获得,这样可以确保被光源直接照射的点不至于呈现黑色,从而可以减少噪声。注意,直接光照部分是要用到“光源”的,而间接光照部分只是用到“发光材质”。

 

这里,我们需要注意的是:不要在对直接光照使用Path Tracing算法了,否则直接光照部分的光照强度就翻倍了(因为,我们用面积光源已经计算过一次)。

 

我们直到光线反射一次之后,对应的depth加一。原始光线和阴影光线(用于求面积光源的直接光照)的depth为0。为了避免直接光照部分被计算两次,我们只需判断撞击到发光材料的反射光线的depth是否为1。如果是1,则说明原始光线经一次反射就撞击到了发光材料物体,这条光线和阴影光线是重复的,所以此时发光材料对Path Tracing算法中的这类光线应该返回“黑色”。如下图示意:


图中红色圈标注的反射光线的depth为1,该光线和绿色圈标注的阴影光线效果上是“重复的”,所以在Path Tracing算法中发光材料应该对红色圈标注的反射光线返回“黑色”。

 

但是,有个问题:

当原始光线撞击到镜面材质物体时,其反射光线(depth=1)若直接撞击到了发光材质物体,此时的发射光线对应着发光材质在镜中的成像。所以,对于镜面材质,depth=1的光线是不应该返回黑色的。一般情况下,光线反射一次,depth加一。为了解决这个问题,我们设置原始光线撞击镜面材质时,depth加二。

 

89.2 C++代码实现

 

新建一个叫做“GlobalTrace”的Tracer子类。该类的trace_ray()方法如下:


接下来则是需要在各种材质中添加相应的global_shade()方法。(在这里,我们只添加Emissive、Matte、Reflective三种材质的path_shade())

 







另外,World::build()中也要做相应的修改:

 

89.3 测试图形

 

这个是Path Tracing算法只用于间接光照,单像素点采样次数为100(耗时1304s)时的生成的Cornell Box:

 

对比之前的图形(Path Tracing算法用于直接光照和间接光照,单像素点采样次数为100,耗时976s):

对比来看,降噪效果还是比较明显的。

89.4 其他说明

 

完整的代码,参考:http://download.csdn.net/detail/libing_zeng/9783756

 

 

Referrance

[1]. Kevin Suffern, Ray Tracing from theGround Up, A K Peters Ltd, 2007.


4 0