Selective transparency (transmit some wavelengths but not others)

Anybody know of a way to make an object transmit a certain color but block out other colors (e.g. colored glass)? I believe to do this right, during a blend you would have to be able to multiply a framebuffer value by a 3-vector instead of by a single float. As far as I know, the current blending options in OpenGL only give you a single float to work with.

I have heard talk of blend shaders, but those don’t exist yet.

The only way I can think to accomplish this is to copy a piece of the framebuffer into a texture and then use that texture in a shader when you render your transparent object. Anyone have any better ideas?

Does BlendFuncSeparateEXT help?


i think even glBlendFunc is ok with the mode DST_COLOR and ONE_MINUS_DST_COLOR instead of the usual _ALPHA ones.

Thanks for the suggestions guys; your responses got me digging in the right places. Looks like GL_CONSTANT_COLOR and glBlendColor might be the solution. Looks like I also need a more up-to-date red book because I’ve never heard of either of those before today.

You could accomplish the result you seek by using the accumulation buffer.

…and kill your frame rate.

The Radeon 9800 says it has a hardware accelerated accumulation buffer, although I’ve never tested its performance.

I sorta don’t get it. How is what you want different from a regular blend? If you want to scale what is already in the framebuffer by a different value than the color of your glass, you could do a multipass-solution, and first render the color you wish to scale by, and then add the color of the glass. Then again, I probably just don’t get it :slight_smile:

If the SRC_COLOR and DST_COLOR are insufficient for you then just draw the object three times with different alpha values and use glColorMask.

Depending on your data you could get away with two passes if you use one pass with SRC_COLOR for source and ZERO for destination in the first pass then ZERO for destination factor and GL_ONE for the second pass if you premultiply component alphas by component color for the object’s second pass rendering. It depends a lot of whether you can preprocess the source data.

Neither solution is very difficult and both are doable with reasonable performance.