方框模糊、高斯模糊和双重模糊的实现原理和方法
方框模糊(Box Blur)
我们知道,位图其实都是由无数个像素点组合而成的,每个像素点都带有颜色值,方框模糊的基本原理就是:遍历每一个像素点,对像素点进行重新赋值,采样方法通常是取临近像素点颜色值之和的均值,因此方框模糊又被称为均值模糊。
最简单的一种采样方法就是2*2采样,取目标像素点周围四个角的像素值,然后求均值。
举个最简单的例子!把下面左图理解为一张图片,每个色块代表一个像素点。

使用2*2采样方法遍历每一个像素点,那么最后方框模糊的效果就像右图这样。以左上角的像素块为例,它的RGB色值为(75,75,194),因为是边缘色块,它只有右下角色值为RGB(153,75,194)一个色块,那模糊后的色值计算方法(四舍五入取整数值)为:
R = 153 / 4 = 67
G = 75 / 4 = 18
B = 194 / 4 = 48
它模糊后的最终色值为RGB(67,18,48),也就是右侧左上方的暗紫色色块。
其他像素点的模糊算法也以此类推。
具体用Unity Shader 实现如下:
2*2 采样方法虽然计算简单,但它的模糊效果并不理想,单次迭代模糊过渡并不顺滑,很容易出现色块,就像下面一样。

要解决这个问题,需要经过多次迭代才能达到比较好的效果。
既然22采样方法不太理想,那么可以考虑采样33的采样方法,也就是采样目标像素周围9个像素点的色值(包括自身)。采样方法可以根据实际项目需要灵活调整,比如说44、55的采样方法,这里就不再一一列举了,只给出3*3采样方法的简单示例:

还是以左上方色块为例,使用3*3采样方法,他的邻近像素色块只有四块,那么方框模糊后的色值计算方法(四舍五入取整数值)为:
R = (75+75+75+153)/ 9 = 42
G = (75+117+194+75)/9 = 51
B = (194+194+125+194)/9 = 79
它模糊后的最终色值为RGB(67,18,48),也就是右侧左上方的灰紫色色块。
其他像素点的模糊算法也以此类推。
具体用Unity Shader 实现如下:
在其他参数相同的情况下,3*3采样方法模糊后的效果,会比2*2采样方法过渡更自然,更不容易产生色块,颜色细节也会更加丰富。

高斯模糊(Gaussian Blur)
理解了方框模糊,再来解释高斯模糊就更加容易了。
首先,高斯模糊是采用5*5的采样方法,也就是需要采样目标像素点周围25个像素点的色值(包括目标像素)。
但区别于方框模糊,高斯模糊采样的每个像素点需要再乘以一个权重值,越靠近目标值,权重值越大。

如果计算每一个像素点高斯模糊后的值,工作量将会变得特别大。有一种方法能将计算变得非常简单,那就是先对像素进行水平采样,然后再垂直拆样。具体采样方法如下:

使用unity shader 实现代码如下:
实现的效果如下:

相比之下,高斯模糊的过渡效果会比方框模糊更加平滑自然。
双重模糊(Dual Blur)
严格来说,双重模糊并不是一种模糊算法,而是一种模糊的优化方法,它可以应用在方框模糊、高斯模糊或者其他模糊算法之上。它的实现思路在于:在原有模糊方法的基础上,采用降采样、升采样的方法进行迭代,从而达到模糊的优化。
那么什么叫降采样?什么叫升采样呢?
先看以下一段代码:
这是一段最简单采样渲染图片的代码,新建了两块画布,画布的尺寸为屏幕的宽、高。
在采样的过程中,如果画布的宽高越来越小,采样的速度越快,画质会变模糊,渲染速度变快,这个过程就叫做降采样。
与此相反,画布的宽高越来越大,采样的速度变慢,但画质渲染会更加精细,渲染速度变慢,这样过程就叫做升采样。
双重模糊就是通过不断迭代,先降采样然后再升采样的方法,来达到优化模糊效果的。

以高斯模糊为例,它使用双重模糊的代码如下: