2012-08-14 113 views
0

我怎样才能改善这个片段着色器:提高Opengl的2.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;  
} 

我用它来模糊的线,所以大多数时间它是融合了相同的颜色。我想让它忽略(留下背景颜色)具有相同周围颜色的像素。我怎么能这样做?

回答

3

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

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

在片段着色器。

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

第二个也许更重要的优点是,在基于瓦片的延迟渲染器(例如iOS设备中的PowerVR系列)中,从作为变化馈入的坐标提取纹理可避免依赖纹理读取。这可以让这些GPU在纹理提取上做一些很好的缓存,我已经看到它在这个特定的硬件上的性能有很大的不同。

随着一些聪明的逻辑,你可能仍然能够减少纹理抓取的数量,但这是一个简单的优化,我在我的OpenGL ES片段着色器中到处使用,它总是给我一个很好的性能提升。

1

很多在着色器中的if检查是不可以的。

另一种选择可能是添加一个统一的(或者一个统一的数组,如果你有很多行),它告诉着色器该行的中心(x坐标只针对你的行)。然后

着色器可以有一个,如果检查为:

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

这可以提高整体性能,如果你有大量的留白周围未经历模糊。