Wednesday, July 22, 2009

Faking transparency without alpha channel

I brushed again the gl Blending Functions (glBlendFunc) and I discovered you can fake transparent textures without having an alpha channel. You can have a simple RGB texture with a black background (like a lens flare for example) and then set the blending function to GL_ONE, GL_ONE (Some also make the source factor GL_SRC_ALPHA but since there is no alpha, might as well do it GL_ONE). So the source (pixel which is going to be output) factor and destination (pixel in the existing color buffer) factor are both 1. So if the source (texture) pixel is black (0, 0, 0), and the destination (frame buffer) pixel is red(1, 0, 0), the result would be red(1, 0, 0), i.e. nothing will change in the destination (frame buffer)... more formally the result is Sf * Sp + Df * Dp, where:
S = source
D = destination
p = pixel tuple
f = factor

Using our example, Sf and Df are 1 and we have black (0, 0, 0) and red (1, 0, 0)
1 * (0, 0, 0) + 1 * (1, 0, 0) = (0, 0, 0) + (1, 0, 0) = (1, 0, 0)
Using another example
1 * (0.2, 0, 0) + 1 * (0.4, 0, 0) = (0.6, 0, 0)

So it's just adding them together. If it's completely black, it's as if it is invisible.

Of course for accurate transparencies we need the alpha channel and use GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA so that they are blended together properly. If the alpha of the texture pixel is 0.2f then it would be
0.2 * (0.2, 0, 0) + (1-0.2) * (0.4, 0, 0) = (0.04, 0, 0) + ( 0.32, 0, 0) = (0.36, 0, 0)

No comments: