Real-Time Ray Tracing 2

高斯滤波:某一个像素i,周围的像素j(包括i自己)会对其滤波做出贡献,根据j离i的距离,得到高斯对应的值给i。

其伪代码大致意思是:根据j离i的距离,算出其对i的贡献,然后用j的值乘以这个贡献就是对i的作用,再把这些加起来就是sum_of_weighted_values,所以的贡献加起来就是sum_of_weights。用sum_of_weighted_values除以sum_of_weights就是每个像素的平均贡献。

 双边滤波:Bilateral filtering,高斯滤波会把图片中的所有内容全部模糊化,当我们想要让下图中人物边缘不滤波,也就是保留边缘。

 

 如何保留边界,根据两个像素的颜色差异是否非常大来判断,如何颜色差异非常大,就把那个像素的贡献减小,反之就是正常使用高斯滤波。下图中的公式i,j,k,l就是两个点的坐标,相当于(x1,y1)和(x2,y2)。后面的I(i,j)-I(k,l)就是两个像素的颜色差值。

 

 联合双边滤波:Joint Bilateral filtering,高斯滤波是根据距离来算的,双边滤波在高斯的基础上加了颜色的差异,所以联合双边滤波可以加入更多的条件判定。

 

 比如使用G-Buffer中的法向量,空间坐标,深度。

 

 在下图中,A和B如果只考虑距离和颜色差值就不能等到滤波后的边界,这时可以考虑深度,因为他们的深度差别很大。B和C就要考虑他们的法向量,因为他们俩的法向量夹角是90°,对于D和E考虑颜色差值,因为D点在阴影里。也相当于是高斯函数,但这些高斯函数的横坐标是深度、法向量、颜色等等。

 

 对于一些大范围的滤波,使用这些方法就会非常耗时了,这里有两种方法。

方法1:之前是对N*N的滤波,这里可以简化为横着(1xN)和竖着(Nx1)的两次滤波。

 

2D的高斯函数可以拆分为在x轴上和y轴上的两个高斯函数,由于滤波等于卷积,所以可以写成积分的形式,然后根据高斯的拆分,把积分拆分成x部分和y部分,这样就是先算x的积分,然后再算y的积分。理论上如果是双边滤波或者更复杂的联合双边滤波,就不能用高斯拆分来算,但实际上如果不是计算非常大的那种范围滤波,也确实可以用高斯拆分来算双边滤波或者联合双边滤波。

 

 方法2:假设对642求范围滤波,我们使用5X5滤波,第一趟选择间隔为1,即临近左右旁边4个点加自身一共5个点,然后这5个点在另一个方向上再选择同样方法的5个点,这样就是5X5的滤波。第二趟选择间隔为2的点,第三趟选择间隔为4的店。就这样选择2i间隔的点。

 

 

在一些场景中,会有一些非常亮的点,如果对这些点进行滤波,虽然也会把它的亮度降下来,但还是很亮,且会把它的亮度贡献到它周围,使得这个亮点变大,这个亮点叫做outliers。主要做法是在滤波之前就把它的亮度降下来。

 

 首先是要找到那个很亮的点,遍历所有像素,对于每个像素取它周围比如7X7的点,算出它的亮度均值和方差,根据均值和方差的范围来找出很亮的点,当然这个范围是自己定义的。这里的高亮度点并没有扔掉,而是降低了它的亮度。

 

 在算当前帧的最后结果中,需要上一帧的已经算好的结果对当前帧的贡献,这里也是把上一帧拉向当前帧。只不过这里是先计算该点周围比如还是7X7的范围,然后计算它们在上一帧中对应的位置,如果得到的结果就比如像之前那个被遮挡的点,就把上一帧拉向当前帧,接近正确的效果,然后再计算线性值到当前帧。

posted @ 2022-09-20 20:40  捞的不谈  阅读(38)  评论(0编辑  收藏  举报