bidirectional pathtracing算法学习

 

      bidirectional pathtracing算法是继pathtracing算法以来的又一个突破。因为经典pathtracing算法有一个很大的问题就是效率极低,每个像素点发出的每个path必须击中光源才会对该像素点的颜色值有所贡献,否则这整条路径都是无效的(对目标颜色值没有任何贡献),所以当光源很小的时候,pathtracing算法渲染的场景一般都很黑,并且噪点严重。还有一种特别的情况,就是光源被遮住的时候,整个场景主要由间接光照明的时候,pathtracing算法的效果也十分差劲,bidirectional pathtracing针对经典pathtracing算法的这些问题,不仅从视点出发发射射线路径E,同时也从光源出发发射射线路径L,最后将这两条路径上的点连接起来,计算每一对点的颜色贡献度,再按一定的规则求得加权和,就是目标像素点的最终颜色了。如下图所示:

       谈到bidirectional pathtracing,不得不提到一种更为古老的算法:Monte Carlo Light Tracing,这是一种与经典raytracing算法针锋相对的算法。该算法的核心思想是:从光源发射粒子到场景,粒子每击中一次物体表面就从交点处引一条射线到视点,若该点在屏幕表示范围内且与视点无阻挡,则该交点的亮度值对屏幕上相应的像素点产生贡献。同时,光线粒子以一定的几率继续在场景中游走(其游走方向由上一次交点处的物体表面属性决定),当然,光线粒子也有一定的几率被物体吸收(主要看物体的反射率),这时就回到起点,从光源发出另外一束粒子继续之前的过程,下图展示了Monte Carlo Light Tracing的算法过程:

如果说raytracing是逆向跟踪算法的话,Light tracing就是正向跟踪,可以看到在场景固定的情况下raytracing的计算量跟最终渲染图片的像素点直接相关,而与场景的大小并无直接关系,Light tracing则跟场景大小有关,如果整个最终图片只显示整个场景的一小部分,就会有大量的粒子交点对屏幕像素毫无贡献,或者贡献很小,所以通常来说raytracing的效率要高于Light tracing。另一方面,我们可以想到在正向跟踪的渲染算法中从一个漫反射表面正好有一束粒子朝镜面表面射来的概率为0,因此它不能很好地表现(L->D->S->E)这类路径,也就是镜面反射现象(折射类似),而这正是raytracing这种逆向跟踪算法所擅长的,并且因为一般的渲染算法中没有实体的视点(视点一般都是一个理想的点,没有大小),无法存储直接击中视点的粒子,所以无法表现镜面高光,而这又是raytracing的看家本领之一。但是Light tracing也并非一无是处,因为它可以表现焦散现象(caustics),可以发现焦散的产生路径(L->S->D->E)正好和镜面反射的路径对称,所以单纯的逆向跟踪算法很难捕捉到焦散现象,正如正向跟踪算法无法处理镜面反射现象一样(这里有个例外,经典pathtracing算法可以模拟焦散,因为它包含了L=0的路径,这就要求光源必须是有体积的,而不是一个无大小的点,并且路径L=0也有利于表现光源可视化等效果)。

注:L:(Light)光源

    S:(Specular)镜面或者透明表面

    D:(Diffuse)漫反射表面

    E:(Eye)视点

 

       上文中提到了正向跟踪和逆向跟踪两类离线渲染的算法,而 bidirectional pathtracing正是结合了这两类算法的优点,达到更好的渲染效果和效率。之前的很多算法可以看成是这种算法的特殊情况,比如pathtracing就可以看出是bidirectional pathtracing中L路径为0的特殊情况,下图显示了四种总长度为3的路径

(a)可以代表pathtracing中的路径;

(b)描述的是raycasting算法,Eye Path为2,也即从视点仅发射一束光线,不反弹,如果我们令Eye Path(图中的t)在遇到镜面表面或者透明表面的时候可以大于2,那么就成了经典的raytracing算法;

(c)中如果令s>=2的话,就可以描述Light Tracing算法;

(d)仅用于视点有体积的场所。

一般情况下,最好将Eye Path和Light Path大小都取为大于等于5,这样才不至于遗漏一些现象(比如当Eye Path较小时不易表现镜面反射等现象,当Light Path较小时不易表现焦散)。

还有一点需要说明的是Eye Path和Light Path上每一对点对最终颜色值贡献度的权值的确定,有很多种权值确定方式,它们都只有一个目的就是让图片看起来更加真实,当然很多方法也比较复杂,我则是采用了最简单的方法,均匀权值法,即每对点的重要程度一样,而对于透明物体的处理效果也始终不好,这个问题目前也没有想明白是什么原因(可能跟权值设定有关)。

最后贴上一张使用bidirectional pathtracing渲染的两张图片:

posted @ 2013-04-04 12:39  星光下的守望者  阅读(3052)  评论(0编辑  收藏  举报