Premultiplied alpha trouble - Printable Version
+- iDevGames Forums (http://www.idevgames.com/forums)
+-- Forum: Development Zone (/forum-3.html)
+--- Forum: Graphics & Audio Programming (/forum-9.html)
+--- Thread: Premultiplied alpha trouble (/thread-6132.html)
Pages: 1 2
Premultiplied alpha trouble - Fenris - Nov 2, 2004 12:59 PM
I've been working on premultiplying all the El Ballo texture files, and they look just fine in Preview and Photoshop. However, when I load them into the actual game, they blow up and produce very odd color values. Here's a composited screenshot of what's happening: top half is using my pre-multiplied textures and bottom half is using the non-premmed ones. I've tried with glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA) as well, but with the same results.
Can anyone guess as to what is going wrong here? It looks as if pure yellow goes into pure cyan, which would mean that (pure red + pure green) becomes (pure green + pure blue) (#FFFF00 -> #00FFFF). Also, if you look at the text in the upper half, right below GL_SRC_ALPHA: that text is black in the texture, but is completely transparent here. Looks to me as if the pixels become badly swizzled somewhere, but the same code works if I just use the non-premultiplied textures instead. Any guesses?
Premultiplied alpha trouble - OneSadCookie - Nov 2, 2004 01:09 PM
The correct blend function for premultiplied images is ONE, ONE_MINUS_SRC_ALPHA.
Are you sure you haven't accidentally swizzled your textures' color channels during premultiplication? That's what it looks like's happened to me...
Premultiplied alpha trouble - Fenris - Nov 2, 2004 05:29 PM
OK, fixed that. Turned out to be a very subtle bug in my file loading code (which ought to have broken every file loaded since the dawn of this game) which caused a pointer offset which, yes, in a way swizzled the channels. Now, however, everything looks great. Except, whenever I draw with an glColor* alpha less than 1, I get a strange glowing effect. Similarily, half-transparent textures look awfully dark. Any hints?
Premultiplied alpha trouble - OneSadCookie - Nov 2, 2004 05:32 PM
any glColor calls you make must also be premultiplied.
Eg, if you would have done glColor4f(r, g, b, a); , instead do glColor4f(r*a, g*a, b*a, a);
Premultiplied alpha trouble - arekkusu - Nov 2, 2004 07:36 PM
Why do you want to premultiply everything? Unlike Quartz, there's really no penalty in GL.
Premultiplied alpha trouble - OneSadCookie - Nov 2, 2004 08:30 PM
because premultiplication avoids halos around sprites when they're bilinearly filtered, and it's simpler than ensuring that the color channels bleed into the transparent areas appropriately.
Premultiplied alpha trouble - arekkusu - Nov 2, 2004 08:58 PM
RGB * alpha * one = RGB * alpha. There's no difference between premultipling the alpha, using GL_ONE for the src blending factor and not premultipling the alpha, using GL_SRC_ALPHA for the src blending factor. Except, of course, that premultipling destroys your RGB data so you can't turn the alpha channel off whenever you want to.
Premultiplied alpha trouble - Fenris - Nov 3, 2004 03:05 AM
Well, my problem is that I have bright halos around my quads. (This is 2D all the way, you see) Arekkusu, could you elaborate on your second post? Not quite following you here...
Premultiplied alpha trouble - arekkusu - Nov 3, 2004 03:12 AM
There's no requirement to premultiply your texel data.
If you take some RGB+A image from photoshop, and premultiply it (for example with tiffutil, or programatically) then you build an RGBA texture out of it and blend it into your scene with glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA). That's fine, the resulting framebuffer pixel is src_rgb * src_alpha * one + dst_rgb * (one - src_alpha);
Alternatively you can take some RGB+A image from photoshop as is, build an RGBA texture out of it and blend it into your scene with glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA). The resulting framebuffer pixel is src_rgb * src_alpha + dst_rgb * (one - src_alpha).
It's exactly the same. That's what I was saying. I've done it both ways.
If you have fringes, check your image data. In hex.
Premultiplied alpha trouble - OneSadCookie - Nov 3, 2004 03:33 AM
As I said, the problem is only when the nonpremultiplied image is bilinearly filtered. halfway between an opaque green texel and a transparent white texel, a semitransparent light-green fragment is generated, which produces the effect of a light halo. Halfway between an opaque green texel and a transparent black texel, a semitransparent dark-green fragment is generated, which produces the effect of a dark halo. Only if the transparent texel is the same shade of green as the opaque one is the halo eliminated.
By contrast, if the image is premultiplied there is only one case -- an opaque green texel next to a transparent black texel. In this case the filtered fragment (semitransparent dark green) is actually a premultiplied pure green, the desired color. No halo is visible.
So, premultiplication isn't the only solution, but it is the most practical solution -- premultiplication of the image is easier than ensuring the transparent texels are the same color as the surrounding opaque texels.
Premultiplied alpha trouble - reubert - Nov 3, 2004 12:26 PM
an alternative: http://www.vterrain.org/Plants/Alpha/
Premultiplied alpha trouble - Fenris - Nov 3, 2004 02:43 PM
Thanks for the insightful discussion, both Keith and Arekkusu (actually, I have no idea what your real name is. ) It seems to work fine now, and my haloes are gone. Wohoo!
Reubert, that's very cool, and I've seen it in files exported from Illustrator, just never knew what the heck was going on. Thanks for posting!
Premultiplied alpha trouble - arekkusu - Nov 3, 2004 04:44 PM
(arekkusu == alex)
Premultiplied alpha trouble - Fenris - Nov 4, 2004 10:39 AM
Alex, got that. Very cool web page. Too bad Ivan just translates into Iwan, which isn't very cool at all.
EDIT: Oh, you edited your post. Disregard the web page stuff.
Premultiplied alpha trouble - phydeaux - Nov 4, 2004 12:40 PM
I haven't used premultiplied alpha before (it sounds like a good idea) though correct me if I'm wrong- if you have a particularly transparent amount of color, then your precision goes down provided you are using integral channels (e.g. if you were making a 1/2 transparent image, then you'd only use values 0-127 instead of the whole range of 0-255 of a byte.) I assume that's the downside of using premultiplied alpha?
After a quick google, this is the problem I had in mind: http://www.teamten.com/lawrence/graphics/premultiplication/
Though it does sound like the benefits outweigh the downside. In my game I actually intentionally make some of the black haloes because it gives an interesting look to some of the icons. The rest of my images I have a blurred copy of the image in the transparent pixels to make sure surrounding pixels aren't black or white.