Rendering translucent geometry intermixed with volumes

On a former blog post we discussed about the addition of dual-depth peeling to VTK  (vtkDualDepthPeelingPass).  As mentioned there, dual-depth peeling roughly doubled the frame rate of correctly-ordered translucent-geometry rendering when compared to legacy depth-peeling.

Rendering correctness in a rasterized scene containing translucent geometry and volumes has been a long standing issue in VTK.  Understandably so, it is not simple to architecturally achieve this given the necessity for various rendering  passes and resource sharing across different mappers.  Likewise, achieving any reasonable performance is challenging.  Recently, thanks to the performance improvements of dual-depth peeling we were able to extend the rendering pass to correctly handle intermixed translucent geometry with volumes.

Industrial CT scan of a human tooth.  Dentin and pulp rendered as a volume (orange) while an iso-contour of the enamel is rendered as translucent geometry (blue).  The volume is not included in the depth-peeling pass so the compositing order is incorrect (the volume appears always on top of the translucent geometry).

Volume-peeling: additions to the dual depth-peeling algorithm

Dual-depth peeling for geometry computes color and depth of front and back layers (peels)  in a single render pass, computed colors are accumulated in separate buffers and the updated depths are used to feed the next pair of peels in a following render pass.  In order to handle volumes, the resulting depths obtained from a geometry-peeling pass are used as entry/exit points for ray-casting in an additional pass where the volume mapper is invoked, essentially rendering the peels of volume contained within peels of geometry.  As with translucent geometry,  a single render-pass accommodates both front and back ray-casting of the current peels. Sections of the volume not enclosed within translucent geometry are rendered altogether in a separate pass at the beginning (before the peeling passes) and the computed fragment colors are used to initialize the front and back rendering targets.

The following example shows some of the passes to render a frame from TestGPURayCastDepthPeeling.  This test renders a volume vase enclosed in two transparent polygonal spheres.

Initial volumetric pass rendering sections not enclosed in translucent geometry (PeelVolumesOutsideTranslucentRange()):

Back and front accumulation buffers are shown in the left and right images respectively.

First volumetric peel (PeelVolumetricGeometry()), the resulting depths from the first translucent geometry peel (PeelTranslucentGeometry()) are used as entry/exit points for ray-casting:

Resulting fragment colors from back (left) and front (right) ray-casting. The front color is directly written to the front accumulation buffer while the back color is accumulated in a following pass.

Final state of the accumulation buffers before its final composition:

Back buffer (left) and front buffer (right).

Final result

Additions to the API

Volume-peeling is currently off by default and needs to be explicitly enabled.  As with the rest of the API, it is directly exposed through the renderer.

vtkNew<vtkRenderer> ren;
ren->SetUseDepthPeelingForVolumes(true);

Performance notes

As before, performance highly depends on the geometry complexity (for higher complexity, higher number of passes are required for a full set of correctly ordered fragments).  In addition, when volume-peeling is enabled performance will also depend on the ray-sampling distance.  Our initial benchmark suggests that the time spent rendering volume peels is far greater than the time spent drawing the translucent geometry, so adjusting volume mapper settings will have a significant impact on performance. In addition, the accumulated time spent peeling the volumes is around 75% greater than the time required to render them without peeling. This appears to be due to the overhead of repeatedly initializing the ray-casting code as we switch between volumetric and translucent geometry, so limiting the number of peels (and thus ray-cast initializations) will have significant performance impacts.

With volume-peeling on, correctly ordering translucent geometry and volume layers.

Questions or comments are always welcome!