后处理经常需要对图片进行模糊操作,例如Bloom,景深等,这里介绍几个高效的计算模糊的要点。
1. 降采样
即先把图片缩小到较低分辨率再进行模糊,然后放大到原来的分辨率。
由于模糊的计算在pixel shader里耗时较多,减小分辨率有助于提高效率,而且把图片先缩小再放大,经过线性过滤之后也有模糊的效果。
2. 二维卷积变成一维卷积
对于高斯模糊而言,由于高斯函数的数学性质,可以优化成两次两次一维卷积,复杂度从O(n^2)变成O(2n)。
3. 抛弃卷积核中较小的权重
以高斯模糊为例,大小为7的卷积核的权重分别是
1 6 15 20 15 6 1
两端的权重为1,相对其他权重而言比较小,可以考虑从大小为9的卷积核
1 8 28 56 70 56 28 8 1
中去掉头尾两个元素,组成新的卷积核
8 28 56 70 56 28 8
也就是
1 3.5 7 8.75 7 3.5 1
这样一个大小为7的卷积核能达到接近原来大小为9的卷积核的效果。
4. 利用硬件的线性插值
GPU对纹理进行采样的时候,如果纹理坐标不在像素的中心,会返回对临近像素进行线性插值的结果。这个硬件层面的插值计算效率较高,只要恰当地计算纹理坐标,就能实现一次采样得到一前两次采样的结果。
例如,对于原来大小为9的卷积核,偏移的像素值和权重分别是
-4 -3 -2 -1 0 1 2 3 4
0.016 0.054 0.122 0.195 0.227 0.195 0.122 0.054 0.016
我们可以用一个大小为5的卷积核达到等价的效果,其偏移的像素值和权重分别为
3.231 1.385 0 1.385 3.231
0.070 0.316 0.227 0.316 0.070
原本大小为N的卷积核,需要采样N次,利用这种方法只需要[N/2]次。