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