7

I'm using OpenGL to draw in 2D. I'm trying to overlay textures with alpha. I have done this:

glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);

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

And then I draw in reverse z-order. However, I'm getting strange discolorations. Here's an example of something that should smoothly fade from one image to another (in fact, the images are seamless in this particular case, but that won't always happen (so, no, I can't just not have alpha)): Strange discoloration from alpha blending

See the grey patch in the middle? That patch is in neither of the source PNGs. Does anyone know what's causing this and how to fix it? Perhaps a completely different alpha strategy?

EDIT: For reference, here are the two textures being blended:

enter image description here

andyvn22
  • 14,696
  • 1
  • 52
  • 74

3 Answers3

2

Is there any change if you use this as your blending function?

glBlendFunc(GL_SRC_ONE,GL_ONE_MINUS_SRC_ALPHA);

EDIT/SOLUTION:

Pre-multiplied alpha in the PNG was the culprit. Alpha needed to be divided back out of RGB to correct the image and remove the gray artifact (see comment chain for details)

holtavolt
  • 4,378
  • 1
  • 26
  • 40
  • Using GL_ONE caused the same spots to become extra-bright rather than discolored. – andyvn22 Jun 11 '11 at 00:34
  • GL_DECAL or GL_REPLACE (if the former, try the latter) – holtavolt Jun 11 '11 at 02:14
  • GL_REPLACE seemed to have no effect; GL_DECAL caused white background on all quads (this is with my original blend func. With the new one, same results, only everything is extra-bright). – andyvn22 Jun 11 '11 at 02:57
  • 1
    I think your source PNG (the one with transparency) may have premultiplied alpha, causing the non-oqaque regions to be too dark. You should be able to correct this by adjusting the RGB channels (divide by their alpha) to restore them, so see if there's an option to store non-premultiplied. – holtavolt Jun 11 '11 at 14:09
  • WOO! Yes, I think you're right about it being a premultiplied alpha problem. I'm still not sure exactly what's wrong, but after your comment about correcting for it, I experimented and added this line to my fragment shader: `texColor = vec4(texColor.rgb / sqrt(texColor.a), texColor.a);`. Everything looks great now! Maybe put the premultiplied alpha thing in the main post for future reference? – andyvn22 Jun 11 '11 at 15:37
  • Glad to hear it (although I wouldn't expect the sqrt to be needed?) I encountered similar issues recently, and this thread reminded me of your "dark region" problem: http://stackoverflow.com/questions/4854839/how-to-use-pre-multiplied-during-image-convolution-to-solve-alpha-bleed-problem – holtavolt Jun 12 '11 at 02:10
  • Yeah, sqrt was unexpected. But it appears perfect, and linear was too dark. – andyvn22 Jun 12 '11 at 03:21
0

If your GL_TEXTURE_ENV is the default GL_MODULATE you may have some old color state floating around.

Try resetting that with glColor3ub(255,255,255) before you render your textured geometry.

genpfault
  • 51,148
  • 11
  • 85
  • 139
0

I'm now wildly guessing here, but if Z fighting and color modulation are ruled out this may be some kind of filtering artifact. For a quick test switch between

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

and

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

if the effect changes between the two you, some filtering somehow messes up your coloration. Solution: Use mipmaping and generate the mipmap levels with a downsampling method that keeps the desired features. Standard gluBuildMipmaps uses a rather stupid box filter, so don't use that.

datenwolf
  • 159,371
  • 13
  • 185
  • 298
  • To complete the experiment, can you try setting GL_TEXTURE_MAG_FILTER to GL_NEAREST as well? I'm having a little trouble telling what your screenshot is showing, you say you're drawing in 2D but that almost looks like a 3D scene (maybe my eyes are tricking me). Can you post a more clear picture of exactly what you're rendering? – eodabash Jun 07 '11 at 21:15
  • Tried, no go. It's supposed to look like a 3D scene, but it's made of 2D pre-rendered tiles. What you're looking at there is just two quads directly atop one another, one containing the pillar and blending into the other (where the grey spot is). Basically, near 0% top tile alpha, I'm fine, and near 100% I'm fine, but near 50% it's like the top tile is somehow muting the bottom tile's color (or its own?) – andyvn22 Jun 08 '11 at 04:48
  • Could you post the original textures somewhere? – datenwolf Jun 08 '11 at 06:22
  • Just added 'em to the question. :) – andyvn22 Jun 08 '11 at 21:24
  • So isn't the gray patch then just that gradient area of the top texture blending with the gray/brown floor texture behind it? – eodabash Jun 09 '11 at 17:58
  • Yes, but the front and back textures are the same color there--how can I get a smooth blend without discoloration? – andyvn22 Jun 11 '11 at 02:57