OpenGL transparent images have black in them

EmbMicro picture EmbMicro · Apr 29, 2012 · Viewed 7.4k times · Source

I am working on a game for Android and I was wondering why whenever I draw images with transparency there seems to always be some black added to the transparent parts. This happens all over and makes some of my effects look strange.

Here is an example. The two circles are only white images with a blur but you can see when one overlaps the other it has a shadow. If I overlap two of the circles say in Inkscape I get pure white where they overlap.

enter image description here

I am using

GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);

for my blending.

Any idea why this happens and how I can avoid it?

Edit: the only thing I can think of is that the two images have the same z so maybe they are blending only with the background instead of each other?

Edit: I changed

GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);

to

GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_DST_ALPHA);

Here is the result I was looking for.

enter image description here

The only thing now is that the transparent images that I had that have a transparent black in them are ignored, which makes sense because I think the destination alpha is 1. Why would One minus source add that gray?

Answer

EmbMicro picture EmbMicro · Apr 30, 2012

I figured out how to fix it.

I changed

GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);

to

GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA);

It turns out that Android pre-multiplies the alpha of textures of PNG images when you load it (making white turn gray).

I added

vColor.r = vColor.r * vColor.a;
vColor.g = vColor.g * vColor.a;
vColor.b = vColor.b * vColor.a;

to my vertex shader to do the multiplying for my other colors.