在一些应用中,高质量的过滤是至关重要的,可以用像素shader代码执行任何过滤。GPU着色程序不用于CPU的主要之处在于:一般来说,CPU数学操作比纹理访问更快,而在GPU中恰恰相反。图像过滤的目的很简单:对于给你的输入图像A,我们想要创建新的图像B。把源图像A变换到目标图像B的操作就是图像滤波。最一般的变换是调整图像大小,锐化,变化颜色,模糊图像等。
源像素的图案和它们对图像B像素的相对贡献,就称为过滤核心(kernel)。把核心应用到源图像的过程叫做卷积。如果核心只是把像素简单的进行平均,我们称这个模型为盒式滤波器。
我们可以把kernel作为参数直接代入shader,如下图所示及代码所示。
float4 convolve3x3PS(vertexOutput IN,uniform sampler2D ColorMap,uniform float W00, uniform float W01, uniform float W02,uniform float W10, uniform float W11, uniform float W12,uniform float W20, uniform float W21, uniform float W22,uniform float Sum,uniform float StepHoriz,uniform float StepVert) : COLOR
{float2 ox = float2(StepHoriz, 0.0);float2 oy = float2(0.0, StepVert);float2 PP = IN.UV.xy - oy;float4 C00 = tex2D(ColorMap, PP - ox);float4 C01 = tex2D(ColorMap, PP);float4 C02 = tex2D(ColorMap, PP + ox);PP = IN.UV.xy;float4 C10 = tex2D(ColorMap, PP - ox);float4 C11 = tex2D(ColorMap, PP);float4 C12 = tex2D(ColorMap, PP + ox);PP = IN.UV.xy + oy;float4 C20 = tex2D(ColorMap, PP - ox);float4 C21 = tex2D(ColorMap, PP);float4 C22 = tex2D(ColorMap, PP + ox);float4 Ci = C00 * W00;Ci += C01 * W01;Ci += C02 * W02;Ci += C10 * W10;Ci += C11 * W11;Ci += C12 * W12;Ci += C20 * W20;Ci += C21 * W21;Ci += C22 * W22;return (Ci/Sum);
}
通过辅助图像,我们可以进行优化。充分利用纹理中的rgba通道,可以调用一个tex2D函数访问四个相邻像素而不必调整纹理索引。现在的卷积shader变得很短:
float4 convolve3x3GrayHPS(vertexOutput IN,uniform sampler2D GrayMap,uniform sampler2D NeighborMap,uniform sampler2D CornerMap,uniform float W00, uniform float W01, uniform float W02,uniform float W10, uniform float W11, uniform float W12,uniform float W20, uniform float W21, uniform float W22,uniform float Sum) : COLOR
{float gray = tex2D(GrayMap, IN.UV).x;float4 ntex = tex2D(NeighborMap, IN.UV);float4 ctex = tex2D(CornerMap, IN.UV);float Ci = ctex.x * W00;Ci += ntex.z * W01;Ci += ctex.y * W02;Ci += ntex.x * W10;Ci += gray * W11;Ci += ntex.y * W12;Ci += ctex.z * W20;Ci += ntex.w * W21;Ci += ctex.w * W22;return (Ci/Sum).xxxx;
}
本文随后介绍了双立方过滤等其他过滤技术以及反走样的理论,这里就不细讲了。
可以写一个函数为每个采样像素计算过滤值,但是因为在过滤范围中不需要高频精度,所以查询表就能工作得很好,可以简单地把这些数值写进小的浮点纹理,不但精度适当,而且查询速度快(典型的空间换时间)。