OpenGL ES 2.0片段着色器模糊,速度慢,质量低 [英] OpenGL ES 2.0 fragment shader to blur is slow and low quality

查看:206
本文介绍了OpenGL ES 2.0片段着色器模糊,速度慢,质量低的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to write a blur shader for the iPad. I have it working but I am not very happy with the results. I get very choppy frame rates and the blur looks like crap when blur amount is high.

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

Any ideas on how to improve things?

一些样本输出:

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

编辑:
盒子模糊可能是要走的路。
以下是着色器的框模糊版本:

A box blur may be the way to go. Here is a box blur version of the shader:

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;

这是盒子模糊输出(注意它只是一个水平模糊,但它可能就足够了我想):

Here is the box blur output(note it's only a horizontal blur, but it might be enough for what i want) :

推荐答案

该着色器需要运行两次才能工作,你所谓的 blurSize 应该是 vec2 ,其值应为 vec2(0,1.0 / height)表示垂直模糊, vec2(1.0 /宽, 0)用于水平模糊。

That shader needs to run twice for it to work, what you call blurSize should be a vec2 and the value of that should be vec2(0, 1.0/height) for vertical blur and vec2(1.0/width, 0) for horizontal blur.

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

做两次模糊的想法是它会大大减少纹理查找次数,并希望提高速度。内核大小为7x7的双通模糊将需要14次纹理查找,但如果它在嵌套循环中完成,则需要进行49次纹理查找。

The idea behind doing a two pass blur is that it will dramatically reduce the number of texture lookups and hopefully increase the speed. A two pass blur with kernel size of 7x7 will require 14 texture lookups but if it done in a nested loop you'll need to do 49 texture lookups.

这篇关于OpenGL ES 2.0片段着色器模糊,速度慢,质量低的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆