2010-12-04 119 views
6

我正在尝试为iPad编写模糊着色器。我有它的工作,但我对结果并不满意。当帧模糊率很高时,帧模糊不清,模糊看起来像是废话。OpenGL ES 2.0片段着色器模糊速度慢,质量低

关于如何改善事情的任何想法?

一些样本输出:

alt text

uniform sampler2D texture; 
varying mediump vec2 fragTexCoord; 
varying mediump vec3 eyespaceNormal; 

varying highp float blurAmount; 

void main(void) 
{ 
    highp vec2 gaussFilter[7]; 
    gaussFilter[0] = vec2(-3.0, 0.015625); 
    gaussFilter[1] = vec2(-2.0, 0.09375); 
    gaussFilter[2] = vec2(-1.0, 0.234375); 
    gaussFilter[3] = vec2(0.0, 0.3125); 
    gaussFilter[4] = vec2(1.0, 0.234375); 
    gaussFilter[5] = vec2(2.0, 0.09375); 
    gaussFilter[6] = vec2(3.0, 0.015625); 

    highp float blurSize = blurAmount * 1.0; 

    ///////////////////////////////////////////////// 
    // 7x1 gaussian blur fragment shader 
    ///////////////////////////////////////////////// 

    highp vec4 color = vec4(0,0,0,1); 

    for(int i = 0; i < 7; i++) 
    { 
     color += texture2D(texture, vec2(fragTexCoord.x+gaussFilter[i].x*blurSize, fragTexCoord.y+gaussFilter[i].x*blurSize))*gaussFilter[i].y; 
    } 

    gl_FragColor = color; 
} 

编辑: 一个盒子模糊可能是要走的路。 这里是着色器的盒子模糊版本:

highp vec4 color = vec4(0,0,0,1); 

color += texture2D(texture, vec2(fragTexCoord.x, fragTexCoord.y - 4.0*blurAmount)) * 0.05; 
color += texture2D(texture, vec2(fragTexCoord.x, fragTexCoord.y - 3.0*blurAmount)) * 0.09; 
color += texture2D(texture, vec2(fragTexCoord.x, fragTexCoord.y - 2.0*blurAmount)) * 0.12; 
color += texture2D(texture, vec2(fragTexCoord.x, fragTexCoord.y - blurAmount)) * 0.15; 
color += texture2D(texture, vec2(fragTexCoord.x, fragTexCoord.y)) * 0.16; 
color += texture2D(texture, vec2(fragTexCoord.x, fragTexCoord.y + blurAmount)) * 0.15; 
color += texture2D(texture, vec2(fragTexCoord.x, fragTexCoord.y + 2.0*blurAmount)) * 0.12; 
color += texture2D(texture, vec2(fragTexCoord.x, fragTexCoord.y + 3.0*blurAmount)) * 0.09; 
color += texture2D(texture, vec2(fragTexCoord.x, fragTexCoord.y + 4.0*blurAmount)) * 0.05; 

gl_FragColor = color; 

这里是箱模糊输出(注意:这只是一个水平模糊,但它可能会为我想要的东西是不够的): alt text

回答

10

该着色器需要运行两次为它工作,你叫什么blurSize应该是vec2和该值应该是vec2(0, 1.0/height)垂直模糊和vec2(1.0/width, 0)的水平模糊。

http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=240334

背后做了两遍模糊的想法是,这将大大减少纹理查找的数量,并希望增加的速度。内核大小为7x7的两遍模糊将需要14次纹理查找,但是如果在嵌套循环中完成,则需要执行49次纹理查找。

+0

是的,我认为这是我调整代码的麻烦。谢谢。我认为我并不需要一个完整的高斯来达到我的目的,所以简单的盒子模糊效果可能会更好,速度更快。 – Brian 2010-12-04 22:09:55

1

这是不清楚你的代码到底在做什么。您正在使用建议2D滤镜的texture2D。然而你的卷积矩阵有一个维度,你只循环一次。我可能是错的,但看起来你正在对角地应用模糊。如果它的意图是2D过滤器,则需要分别用于x和y的两个(嵌套)循环来覆盖2D区域。

而关于变量blurSize - 它的名字有点误导。模糊的大小取决于您的卷积矩阵。你的是7个像素宽。这决定了尺寸。这个变量更像是模糊的“强度”,它只能消除卷积矩阵的影响。如果赋予太高的价值,会出现文物。

我不是专家,除了“hello world”mandelbrot之外没有写过任何像素着色器。如果我没有错,比模糊着色器是最糟糕的加速之一。我看到的大多数实时模糊是box-blurs。尝试从这里移植一些代码:gameDev thread

+0

我决定尝试一个框模糊。似乎工作得很好,但我还没有在我的iPad上尝试过,看看它是否足够快,但看起来不错。我会在上面的答案中发布代码。谢谢 – Brian 2010-12-04 22:02:07