# Transparent parts of texture are opaque black instead

I render a sprite twice, one on top of the other. The sprites have transparent parts, so I should be able to see the bottom sprite under the top sprite. The transparent parts are black (the clear colour) and opaque instead though and the topmost sprite blocks the bottom sprite.

uniform sampler2D texture;
varying vec2 f_texcoord;
void main()
{
gl_FragColor = texture2D(texture, f_texcoord);
}


I have glEnable(GL_BLEND) and glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) in my initialization code. My texture comes from a PNG file that I load with libpng. I'm sure to use GL_RGBA when initializing the texture with glTexImage2D (otherwise the sprites look like noise).

Edit: Here's a screenshot.

• Shouldn't it be glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);? Check this examples, machwerx.com/2009/02/11/glblendfunc – Dan Jul 10 '12 at 14:52
• No, the posted code should work fine. Thanks for your comment. – Oskar Jul 10 '12 at 15:06
• Keep in mind that alpha blend happens after the fragment shader (ie you have very little control over it other than setting glBlendFunc()). Check this question and see if it helps you (alpha channel being dropped). I would suggest trying to render 2 nontextured squares on top of one another to make sure blending is working, in case your alpha channel is somehow getting dropped. – bobobobo Jul 10 '12 at 15:11

What do you get if you try and swap the order you draw them in?

Transparent pixels still create depth buffer entries. If you're drawing the back one after the first it's not processing the pixels behind the front image, making it look like there's no alpha.

For reference, take a look at the Painter's alogrithm.

• Switching the order fixed the issue. I was drawing the bottom sprite last, where its position was controlled by its z-coordinate. I suppose there's no way to get this kind of transparency working without sorting the sprites? – Aaron Jul 11 '12 at 0:51
• @Aaron There is no solution for partially opaque surfaces that works for all scenes. Sorting works as long as your objects do not intersect. Another trick is that if your blending is additive (e.g. in a fire particle system) then you can simply disable depth testing. – Kevin Reid Jul 11 '12 at 1:18
• Oh oh oh. Yeah. Here's my answer on SO – bobobobo Jul 11 '12 at 2:12
• Right. I knew about the drawing order issues with translucent (not completely transparent) polygons, but didn't consider the effect of the depth buffer on polygons with transparent regions. I've discovered though that I can use the discard command in my fragment shader to reject transparent pixels regardless of drawing order, though I lose support for translucent objects and get aliasing around the final opaque objects. – Aaron Jul 11 '12 at 16:20

I don't think your textures have the desired alpha inside them, so calling gl_FragColor = texture2D(texture, f_texcoord) won't generate any transparent fragments. You should pass the alpha through as a varying from the vertex program to the fragment program if you want transparency.

EDIT: Teodron suggestion writing the following code to verify that alpha information is getting passed to the shaders (this is in the fragment shader and color is a varying which is assigned in the vertex program). vec4 color = texture2D(texture, f_texcoord); if (color.w < 1) gl_FragColor = vec4(1,0,0,1); else gl_FragColor = vec4(0,1,0,1);

• Perhaps the OP can verify the alpha channel of the png files and chime in. Sending the alpha as an interpolated from a per-vertex information is geometry dependent, not image/texture dependent and not the way to go. I suggest this: a simple vec4 color = texture2D(texture, f_texcoord); if (color.w < 1) gl_FragColor = vec4(1,0,0,1); else gl_FragColor = vec4(0,1,0,1); and see whether there exists any alpha information getting through to the shader at all. – teodron Jul 10 '12 at 15:14
• Brilliant! Thanks a lot, I will incorporate this into my answer. – Oskar Jul 10 '12 at 15:19
• I've tried teodron's test and can verify that the transparent parts are correctly coloured red. – Aaron Jul 10 '12 at 22:41

If you know that those pixels have zero alpha and you want to discard them, a trivial solution is:

if (color.a <= 0.0) {