【问题标题】:How to add alpha value in blur shader如何在模糊着色器中添加 alpha 值
【发布时间】:2020-09-13 05:40:28
【问题描述】:

在下面的模糊着色器中,当前输出图像的 alpha 值为 1.0,但我希望 alpha 取决于图像的模糊。

着色器代码取自以下问题。

OpenGL es 2.0 Gaussian blur on triangle

不显示模糊的图像部分的 alpha 值应为 0。

我尝试了很多选项,但我真的不明白如何将 alpha 值添加到最终图像。

#version 330 core
out vec4 FragColor;
in vec2 pos;

// texture sampler
uniform sampler2D u_texture;
uniform vec2      u_textureSize;
uniform float     u_sigma;
uniform float     u_radius;
uniform vec2      u_dir;

float CalcGauss( float x, float sigma)
{
   if( sigma <= 0.0 )
    return 0.0;
return exp( -(x * x) / ( 2.0 * sigma)) / ( 2.0 * 3.14157 * sigma);

}

void main()
{
    vec2 texC     = pos.st * 0.5 + 0.5;
    vec4 texCol   = texture2D( u_texture, texC );
    vec4 gaussCol = vec4( texCol.rgb, 1.0 );
    vec2 step     = u_dir / u_textureSize;
    float weight;
    for ( int i = 1; i <= 16; ++ i )
    {
        weight = CalcGauss( float(i) / 16.0, u_sigma * 0.5 );
        if ( weight < 1.0/255.0 )
            break;
        texCol    = texture2D( u_texture, texC + u_radius * step * float(i) );
        gaussCol += vec4( texCol.rgb * weight, weight );
        texCol    = texture2D( u_texture, texC - u_radius * step * float(i) );
        gaussCol += vec4( texCol.rgb * weight, weight );
    }
    
   gaussCol.rgb = clamp( gaussCol.rgb / gaussCol.w, 0.0, 1.0 );
   FragColor = vec4( gaussCol.rgb , 1.0 );

}

我已经更改了着色器这是新代码。

void main()
{
    vec2 texC     = pos.st * 0.5 + 0.5;
    vec4 texCol   = texture2D( u_texture, texC );
    vec4 gaussCol = vec4(texCol);
    vec2 step     = u_dir / u_textureSize;
    float weight;
    for ( int i = 1; i <= 64; ++ i )
    {
        weight = CalcGauss( float(i) / 64, u_sigma * 0.5 );
        if ( weight < 1.0 / 255.0 )
            break;
        texCol    = texture2D( u_texture, texC + u_radius * step * float(i) );
        gaussCol += vec4( texCol.rgb * weight ,  weight);
        texCol    = texture2D( u_texture, texC - u_radius * step * float(i) );
        gaussCol += vec4( texCol.rgb * weight ,  weight);
    }
    
    gaussCol.rgba = clamp(gaussCol.rgba, 0.0, 1.0);  
    FragColor =   vec4(gaussCol.rgb , gaussCol.a);

}

下图是新结果。

【问题讨论】:

    标签: opengl glsl shader gaussianblur


    【解决方案1】:

    您已从WebGL 复制着色器。 WebGL 默认使用premultiplied alpha,但您的桌面应用程序不使用。见Straight versus premultiplied。与 WebGL 着色器相比,您必须跳过颜色通道的加权总和除以 Alpha 通道的加权总和:

    gaussCol.rgb = clamp( gaussCol.rgb / gaussCol.w, 0.0, 1.0 );

    gaussCol.rgb = clamp(gaussCol.rgb, 0.0, 1.0);
    

    如果使用 0.0 的 Alpha 通道清除背景(例如 glClearColor(0.0, 0.0, 0.0, 0.0),这是默认设置,那么您也可以“模糊”Alpha 通道。

    用纹理的所有 4 个通道初始化 gaussCol

    vec4 gaussCol = texCol.rgba;
    

    考虑最终的 Alpha 通道:

    gaussCol.rgba = clamp(gaussCol.rgba, 0.0, 1.0);
    FragColor = gaussCol;
    

    分别

    FragColor = clamp(gaussCol, 0.0, 1.0);
    

    如果您希望 alpha 通道为 0 或 1,则必须根据 alpha 值设置通道:

    gaussCol = clamp(gaussCol, 0.0, 1.0);
    FragColor = vec4(gaussCol.rgb, gaussCol > 0.001 ? 1.0 : 0.0);
    

    【讨论】:

    • 我已经进行了更改,但现在模糊效果消失了。
    • 如果我只渲染 alpha FragColor = vec4(gaussCol.a, gaussCol.a , gaussCol.a, gaussCol.a );
    • 全屏变白。
    • 当我使用这个 vec4(gaussCol.rgb , gaussCol.r);
    • @Summit vec4 gaussCol = vec4(texCol.rgb, 1.0); -> vec4 gaussCol = texCol.rgba
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-30
    • 2020-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多