Transparency in OpenGL |
This document is a quick description of how to implement transparency in OpenGL. Using this in the scene graph is generally accomplished by creating a "blend" node, though you have to be careful about the rendering order. Transparency is a powerful feature, but it introduces many new complications in z-buffer systems such as OpenGL.
To make something transparent, you have to:
You enable blending using the line:
glEnable(GL_BLEND);
Add this before the transparent content is rendered. Add the following line after the transparent content is rendered:
glDisable(GL_BLEND);
It's good practice to disable blending when it is not required because blending is more costly than just rendering onto the screen.
Next we have to tell OpenGL just how we will blend things together. We're going to use alpha values, so we want our new objects brightness to be based on its own alpha, something with an alpha of 0.3 would be 0.3 as bright and allow 70% of the light through. So, we want set the blending fucntion for the source to GL_SRC_ALPHA. Likewise, if the source has an alpha of 0.3, we want the background to be multiplied by 0.7, or 1 minus alpha, so we'll use a blending function of GL_ONE_MINUS_SRC_ALPHA. The line you add, right after the glEnable(GL_BLEND) line is:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Note that there are a variety of blending functions available, see the documentation for what they all do.
Lastly, we need to set the alpha value in the lungs material to something less than one. A good value for transparency is often 0.5, so in the lung material, change alpha from 1.0f to 0.5f.
In scene graphs, you'll usually put the enable, disable, and blend funciton in a "blend" node and enables blending for it's children.
The first law of transparency is:
Draw All Transparent Items Last!
The fundamental problem is the you can't draw anything behind something transparent you have already drawn. So, all items behind the transparent object must be drawn first.
A trick when doing transparency is also to turn off writing of the z-buffer. When you turn on transparency, so this as well:
glDepthMask(GL_FALSE);
When done, be sure to turn this back on:
glDepthMask(GL_TRUE);
There's lots of detail in transparency in the OpenGL red book.