my fragment shader does two things :
- displays original pixel color from texture, v_Color variable is set to r=0,g=0,b=0,a=0
- or discards original pixel color to color stored in v_Color. This value is taken if I set alpha in v_Color to 1.0, in other cases is used original pixel's color.
However I have problem in second case if I apply this shader on images which have pixels with alpha == 0.0. I expected that these pixels will be invisible, but they are colored too. In first case I don't have this problem. I need discard pixels with alpha == 0
For example : I have texture of person silhouette which should be colorized, but transparent pixels should be skipped.
At beginning of program I set :
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
and here is my fragment shader :
void main()
{
vec4 c = vec4(v_Color);
vec4 p = texture2D( s_texture, v_texCoord);
gl_FragColor = mix(p, c, c.a);
}
However if I add discard then all works like is expected. Pixels with alpha==0.0 are removed. But I am working with OpenGL ES 2.0, shader will run across different android devices and I read about possible performance issues caused by "if" and "discard". That's why I used "mix" instead "if".
void main()
{
vec4 c = vec4(v_Color);
vec4 p = texture2D( s_texture, v_texCoord);
if (p.a == 0.0) {
discard;
}
gl_FragColor = mix(p, c, c.a);
}
I tried another attempt to fix that. I remember original alpha from texture and I apply it at the end. But it still gives me weird results. gl_FragColor.a = backup_alpha does something with resulted alpha, it is somehow transparent but not fully.
void main()
{
vec4 c = vec4(v_Color);
vec4 p = texture2D( s_texture, v_texCoord);
float backup_alpha = p.a;
gl_FragColor = mix(p, c, c.a);
gl_FragColor.a = backup_alpha;
}
Thanks you @Rabbid76 for help, this is correct :
gl_FragColor = vec4(mix(p.rgb, c.rgb*p.a, c.a), p.a);