![]() |
For rendering, the surface voxels are replicated into three RenderList structures, one for each principal viewing
direction. Within each one,
the voxels are sorted according to the coordinate which corresponds to the
axis most parallel to the viewing direction (For simplicity referred to
as
coordinate. The procedure for the other viewing-axes is
analogous). As the sorting produces groups of voxels with equal
coordinates such that they are stored at consecutive positions
within the array, the
coordinate does not have to be stored for each voxel. Instead,
voxels with the same
coordinate are grouped into RenderListEntrys which store the
coordinate once for all
contained voxels.
For rendering, the RenderListEntrys of all surfaces (as several
surfaces could be viewed simultaneously, see figure 4.18) are
merged and sorted by the
coordinate into a single list. To be able to distinguish objects
during rendering, additional properties like the opacity of the surface
are stored in each RenderListEntry.
During projection, the RenderListEntrys are processed in back-to-front order and their voxels are projected onto the base plane. For performance reasons, each voxel is projected onto exactly one pixel of the intermediate image plane, without interpolation. As the scaling component of the viewing matrix is not considered during this step of the projection, neighboring voxels within a slice of the volume are projected onto neighboring pixels of the intermediate image plane. During projection, compositing is performed, blending the old pixel value with the value of the current voxel according to the opacity stored at the currently processed RenderListEntry.
![]() |
Clipping planes (see figure 4.19a) which operate on the RenderList voxel storage scheme can be implemented in a very efficient way. A RenderListEntry stores voxels with the same depth with respect to the intermediate image plane. The order in which the voxels are projected onto the plane is not relevant, as each of them is projected onto a unique pixel of the intermediate image plane. Thus, if a clipping plane is applied, the voxels within a RenderListEntry can be resorted in a way, that voxels, which are clipped and become invisible, are moved to the end of the array section which belongs to this RenderListEntry. By setting a pointer to the last voxel which is not removed at the RenderListEntry, the clipped voxels can be efficiently skipped during rendering. The resorting of the voxels into clipped/non-clipped voxels requires just a single scan of the array with swapping of pairs of voxels. This approach is able to handle clipping at arbitrary planes or even non-planar objects.
Common visualization scenarios require not only the clipping and removal
of parts of the data, but also to display original data values at
the clipping plane within the context of the 3D object (see
figure 4.19b). The display of
original data on planar sections through the scene can be easily
integrated into the presented surface-rendering approach. Usually,
only voxels
with values above the threshold which defines the surface have to be
displayed, providing information on data within the object. When
a new position for a clipping plane is defined, voxels which contain
the plane and have a value above the threshold are extracted from the
volume and stored in a similar way as surface voxels. Instead of
storing gradient vectors, the data value at the voxel is stored as
an attribute. The
extracted voxels are again sorted according to their
coordinate
and grouped into RenderListEntrys, which are merged with the
remaining objects of the scene. During rendering, a flag at each
RenderListEntry is evaluated to decide whether the attribute stored at
it's voxels is a gradient and should be used for shading or if it is a
data value which should be immediately written into the base plane.