【问题标题】:OpenGL ES 2.0 fragment shader to blur is slow and low quality用于模糊的 OpenGL ES 2.0 片段着色器速度慢且质量低
【发布时间】:2010-12-04 19:58:05
【问题描述】:

我正在尝试为 iPad 编写模糊着色器。我有它的工作,但我对结果不是很满意。我得到非常不稳定的帧速率,并且当模糊量很高时,模糊看起来像废话。

关于如何改进的任何想法?

一些示例输出:

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;

这是框模糊输出(请注意,它只是水平模糊,但对于我想要的可能就足够了):

【问题讨论】:

    标签: iphone ipad ios opengl-es opengl-es-2.0


    【解决方案1】:

    该着色器需要运行两次才能正常工作,您调用的 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 次纹理查找。

    【讨论】:

    • 是的,我认为这是我在调整代码方面的失误。谢谢。我认为我真的不需要完整的高斯来实现我的目的,因此简单的框模糊可能会足够好并且更快。
    【解决方案2】:

    执行两个或更多框模糊通道可将质量提高到非常接近高斯模糊,同时保持相对较高的性能。盒子模糊也可以相对容易地加速。看看http://web.archive.org/web/20060718054020/http://www.acm.uiuc.edu/siggraph/workshops/wjarosz_convolution_2001.pdf

    在任何情况下,在大多数移动场景中,您都可以使用比屏幕截图看起来明显的更低保真度的渲染。

    【讨论】:

      【解决方案3】:

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

      关于变量blurSize - 它的名称有点误导。模糊的大小取决于您的卷积矩阵。你的是 7 像素宽。这决定了大小。该变量更像是模糊的“强度”,只能淡化卷积矩阵的效果。如果给定的值太高,就会出现伪像。

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

      【讨论】:

      • 我决定试试盒子模糊。似乎工作得很好,但我还没有在我的 iPad 上尝试过,看看它是否足够快,但看起来还不错。我将在上面的答案中发布代码。谢谢
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多