GPU Gems1 - 24 高质量的过滤

本文深入探讨了利用GPU进行高质量图像滤波的方法,包括像素shader的使用,卷积过程,盒式滤波器原理,以及如何优化卷积shader。此外,还介绍了双立方过滤等高级过滤技术。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在一些应用中,高质量的过滤是至关重要的,可以用像素shader代码执行任何过滤。GPU着色程序不用于CPU的主要之处在于:一般来说,CPU数学操作比纹理访问更快,而在GPU中恰恰相反。图像过滤的目的很简单:对于给你的输入图像A,我们想要创建新的图像B。把源图像A变换到目标图像B的操作就是图像滤波。最一般的变换是调整图像大小,锐化,变化颜色,模糊图像等。

源像素的图案和它们对图像B像素的相对贡献,就称为过滤核心(kernel)。把核心应用到源图像的过程叫做卷积。如果核心只是把像素简单的进行平均,我们称这个模型为盒式滤波器。

我们可以把kernel作为参数直接代入shader,如下图所示及代码所示。

fig24-01.jpg
中心在W11的3x3过滤核心

 

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;
}

本文随后介绍了双立方过滤等其他过滤技术以及反走样的理论,这里就不细讲了。

fig24-04a.jpg

 

fig24-05.jpg
双立方过滤的核心函数

可以写一个函数为每个采样像素计算过滤值,但是因为在过滤范围中不需要高频精度,所以查询表就能工作得很好,可以简单地把这些数值写进小的浮点纹理,不但精度适当,而且查询速度快(典型的空间换时间)。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值