Rendering Scenes With Translucent Objects:
A (Nearly) Pure CPU Approach
render Methods in SceneElement subclasses
Within the render methods for
your SceneElement subclasses, you can do
something like the following:
ExtendedController* ec = dynamic_cast<ExtendedController*>(Controller::getCurrentController());
if (ec->drawingOpaque() && this-object-has-opaque-pieces)
do-actual-rendering-of-opaque-pieces
else if (!ec->drawingOpaque() && this-object-has-translucent-pieces)
do-actual-rendering-of-translucent-pieces
Advantages
- Minimizes time required for display callback. Only render objects once.
- This approach could be enhanced by storing pointers to SceneElement
instances with translucent pieces discovered during the opaque rendering pass
on a queue. Then the subsequent translucent rendering pass would just empty the
queue rather than do a complete retraversal of the entire scene. (Although
this would require some changes in the overridden handleDisplay method and
ExtendedController subclass.) Moreover, if the
queue were a priority queue where the priority was based on some measure of
distance from the eye,
some visual anomalies could be avoided.
Disadvantages
- Requires potentially lots of translucency-related tests throughout the CPU rendering code.
- May be difficult to support efficiently or conveniently complex model structures in which
some portions are opaque and others translucent.
- Procedural and/or image-based textures applied in fragment shaders (or possibly even operations in tessellation and/or geometry shaders) may result in
pixel-by-pixel
changes between opaque and translucent, which would require the fragment shader know whether opaque or translucent
objects are currently being drawn as is required in the "(Nearly) pure
GPU approach".