这篇文章中,我们将介绍高斯模糊(Gaussian Blur)以及在 HLSL 中实现这个效果。这个东西虽然听起来比较高端,但其实并不复杂,首先介绍一下他的概念:
高斯模糊(英语:Gaussian Blur),也叫高斯平滑,是在Adobe Photoshop、GIMP以及Paint.NET等图像处理软件中广泛使用的处理效果,通常用它来减少图像噪声以及降低细节层次。这种模糊技术生成的图像,其视觉效果就像是经过一个半透明屏幕在观察图像,这与镜头焦外成像效果散景以及普通照明阴影中的效果都明显不同。高斯平滑也用于计算机视觉算法中的预先处理阶段,以增强图像在不同比例大小下的图像效果(参见尺度空间表示以及尺度空间实现)。 从数学的角度来看,图像的高斯模糊过程就是图像与正态分布做卷积。由于正态分布又叫作高斯分布,所以这项技术就叫作高斯模糊。图像与圆形方框模糊做卷积将会生成更加精确的焦外成像效果。由于高斯函数的傅立叶变换是另外一个高斯函数,所以高斯模糊对于图像来说就是一个低通滤波器。
他的实现原理是对进行模糊的像素进行去中心化,每个像素的值都是周围相邻像素的加权平均,而他本身的值有着最大的高斯分布值,相邻元素随着和要进行模糊的像素的距离变远而权值变低。在二维空间内的高斯分布方程如下:
这些东西如果有兴趣的话可以去看 正态分布 。再次不多介绍,主要来看看我们将要去实现的内容,在 HLSL 中实现模糊。
前边已经说过,要实现这个效果是取这个像素和周围像素的颜色值进行加权平均,而我们可以取周围纹理坐标的值来进行计算。
首先我们定义一个权值矩阵:
1 | float3x3 fil = float3x3( |
fil[1][1]
则是我们要求的像素的值,可以看到确实是距离目标像素距离越近权值越大。由于最终权值是要为1,所以除以16。
现在,我们来定义偏移坐标:
1 | float2 posDelta[3][3] = { // 3x3偏移UV坐标 |
取的值也是在我们要求的像素的周围的位置。然后根据偏移坐标求出偏移后坐标的值,并使用采样器采取颜色,乘以权值,最终叠加到最终的颜色上:
1 | float4 color = float4(0.0f, 0.0f, 0.0f, 1.0f); |
对于我们的透明度,并不会去做计算,所以我们修正透明度,且返回颜色:
1 | color.w = 1.0f; // 透明度矫正 |
完整代码如下:
1 | float4 doFilter(float3x3 fil , float2 texSize , float2 uv) { |
这里需要注意的是 texSize
属性,我们的 UV 坐标取值是 0 到 1 的,所以我们会将纹理的位置映射到 UV 坐标上。
效果如下:
和我们之前的图片比较:
还是很明显的,在这里我们只是使用了周围一圈的像素来做加权平均,如果可以使用更多的话效果会更好。