0

如何改进这个片段着色器:

  #ifdef GL_ES
precision mediump float;
#endif

varying vec4 v_fragmentColor;
varying vec2 v_texCoord;

uniform sampler2D u_texture;

uniform vec2 blurSize;
uniform vec4 substract;

  void main() {
    vec4 sum = vec4(0.0);
    sum += texture2D(u_texture, vec2(v_texCoord.x - 4.0 * blurSize.x, v_texCoord.y)) * 0.05;
    sum += texture2D(u_texture, vec2(v_texCoord.x - 3.0*blurSize.x, v_texCoord.y)) * 0.09;
    sum += texture2D(u_texture, vec2(v_texCoord.x - 2.0*blurSize.x, v_texCoord.y)) * 0.12;
    sum += texture2D(u_texture, vec2(v_texCoord.x - blurSize.x, v_texCoord.y)) * 0.15;
    sum += texture2D(u_texture, vec2(v_texCoord.x, v_texCoord.y)) * 0.16;
    sum += texture2D(u_texture, vec2(v_texCoord.x + blurSize.x, v_texCoord.y)) * 0.15;
    sum += texture2D(u_texture, vec2(v_texCoord.x + 2.0*blurSize.x, v_texCoord.y)) * 0.12;
    sum += texture2D(u_texture, vec2(v_texCoord.x + 3.0*blurSize.x, v_texCoord.y)) * 0.09;
    sum += texture2D(u_texture, vec2(v_texCoord.x + 4.0*blurSize.x, v_texCoord.y)) * 0.05;
    gl_FragColor = sum;    
}

我用它来模糊一条线,所以大多数时候它混合了相同的颜色。我希望它忽略(保留为背景颜色)具有相同周围颜色的像素。我怎么能那样做?

4

2 回答 2

3

忽略对线条颜色的检查,我提出的一个建议是将纹理坐标计算向上移动到顶点着色器中并将它们作为变量传递。例如,您可以将 移动vec2(v_texCoord.x - 4.0 * blurSize.x, v_texCoord.y)到顶点着色器中,并将其作为firstTextureCoordinate变量传递,这样您只需要执行

sum += texture2D(u_texture, firstTextureCoordinate) * 0.05;

在您的片段着色器中。

这有两个显着的优点,第一个是它不是对每个片段执行计算,而是每个顶点只运行一次计算,然后使用快速硬件插值将其输入片段着色器。顶点通常比片段少得多,这样可以节省一些计算。

第二个也许更重要的优势是,在 iOS 设备中的 PowerVR 系列等基于 tile 的延迟渲染器上,从作为变量输入的坐标进行纹理提取可以避免依赖纹理读取。这让这些 GPU 可以对纹理提取进行一些很好的缓存,而且我已经看到它在这个特定硬件上的性能上产生了巨大的差异。

通过一些巧妙的逻辑,您可能仍然能够减少纹理提取的数量,但这是我在 OpenGL ES 片段着色器中随处使用的简单优化,它总能给我带来不错的性能提升。

于 2012-08-14T15:07:41.333 回答
1

着色器中的大量 if 检查是不行的。

另一种选择可能是添加一个统一(如果你有很多行,则为统一数组),它告诉着色器该行的中心(x 坐标仅适用于你的线)在哪里。

然后,着色器可以有一个 if 检查,如下所示:

float spread = 4.0 * blurSize.x;
if(lineCentre-spread < gl_FragCoord.x && gl_FragCoord.x < lineCentre+spread){
   //You existing logic for blurr goes here.
}else{
    gl_FragColor = texture2D(u_texture, vec2(v_texCoord.x, v_texCoord.y)) * 0.16;
}

如果您周围有很多空白区域不会出现模糊,这可以提高整体性能。

于 2012-08-14T08:21:01.807 回答