如何在模糊着色器中添加 alpha 值

How to add alpha value in blur shader

在下面的模糊着色器中,当前输出图像的 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);

}

下图是新的结果

您已经从 WebGL. WebGL by default uses premultiplied alpha, but your desktop application does not. See 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);