transparency question

We’re rendering an array of objects with OpenGL. We allow the user to control the transparency of individual objects from completely opaque (1.0) down to almost completely transparent (0.05).

In general this seems to work. We’re using the below rough outline to do our rendering.

  1. enable depth mask
  2. render all completely opaque (1.0) objects
  3. disable depth mask
  4. render all other objects (< 1.0)

The problem we’ve run into is when you have 2 objects which are both almost completely opaque (0.95). In this case they both render in step 4 above. But we’ve found that it only works correctly if they happen to be rendered in order based on depth. If we render the farther object first, then the nearer object, it works fine. If we render them in the other order in step 4, then the object which should be on top is not drawn as such.

My conclusion at this point is that we need to adjust our logic a bit. Specifically, I think step 4 needs to sort the objects in z-order and use the sorted list to render.

Am I on the right track? Anyone else have experience with this sort of thing? Also, I’m not sure this solution is going to handle objects which aren’t neatly separated in the Z direction. Suppose you have objects crossing through each other. There wouldn’t be an easy way to determine which one to render first in that case.

Any ideas?

Sadly, yes, you have to depth-sort things you render transparently.

Suppose you have objects crossing through each other. There wouldn’t be an easy way to determine which one to render first in that case.

If you have interpenetrating objects, then there is no order you can render them in that is correct.

Such is the annoyance of dealing with transparency in a rasterizer.

Thanks for the reply. For the interpenetrating objects would this be a case where pixel shaders could help? i.e. its not sufficient to just sort the objects in that case since the objects aren’t cleanly separated in the z direction. So perhaps sorting the individual pixels and rendering them in z-order would do it? I shudder to think of the performance impact of that though :slight_smile:

Google “Order Independent Transparency” (OIT), you should be able to find descriptions of techniques like (dual) depth peeling and alpha buffers (? - sorry, I’m not certain that is the right name). These are not exactly cheap, but it depends on the number/size of transparent objects how bad their impact is.
There is also alpha to coverage, which is technically wrong, but can look “good enough” for some cases.

Another technique you might consider which I think ZbuffeR mentioned a while back is “Weighted Average” transparency. It’s not perfect, but doesn’t require sorting IIRC: