The fastest software-based rendering method is shear/warp projection. Voxels from the RenderList can be efficiently projected onto the base plane using look-up tables for determining projected positions. To maximize performance, nearest-neighbor interpolation is used during projection of voxels. The calculation of the contribution depends on the compositing mode used. If optical properties of voxels are stored at the corresponding RenderListEntrys (figure 8.1), it is easily possible to assign different parameters to each group of voxels. In practice, all RenderListEntrys which store voxels of the same object will have identical parameters, like color and opacity transfer functions.
Projection is performed, by merging the RenderLists of all distinct objects, and sequentially processing all RenderListEntrys of the joint RenderList which represents the volume. Within each RenderListEntry all voxels are also projected sequentially. The strictly sequential order of voxel projection which does not depend on the viewing direction leads to an excellent cache-efficiency of this approach.
If rendering parameters are changed, some of the extracted voxels may become irrelevant for the visualization. An effective way to skip them during rendering without much effort, is to reorder voxels belonging to each RenderListEntry in a way, that irrelevant voxels are moved to the end of the group. This allows to render the block of relevant voxels at the beginning of the group, and to efficiently skip the remaining, irrelevant ones. Clipping or removal of parts of the volume can be done in a similar way. If voxels which are clipped and become invisible are moved to the end of each RenderListEntry's voxels, they can be skipped in the same way as irrelevant voxels.
For fast evaluation of lighting models, an approach based on look-up tables can be used [19]. For this purpose, the gradient vector is quantized to 12-16 bit, and stored with the voxels as an attribute. The compact representation of the gradient vector is used as an index into a look-up table which stores precomputed shading information. The content of the look-up table has to be recomputed whenever a factor which influences lighting is modified, for example, a light source is moved, or the volume is rotated. Due to the small size of the table (4096-65536 entries, depending on the gradient quantization), various shading models can be applied on a per-object basis at interactive frame rates. Phong shading [49] and non-photorealistic shading models [10,11] can be easily mixed within a single image (figure 8.2a).
| tabularcc [width=.48]Figures/shadingmix.ps [width=.48]Figures/2levelmed.ps |
Using the RenderList-based volume representation, not only shading models can be easily assigned on a per-object basis, also the object-wise assignment of compositing modes can be implemented efficiently. This allows to render each object using the compositing mode which fits its structure best (figure 8.2b). For implementing this feature (two-level volume rendering [22]) based on the RenderList structure, two sets of buffers are used for the base plane image. An object buffer is used for performing rendering within an object, while a global buffer is used to perform inter-object rendering. In addition to intermediate pixel values, each pixel of the object buffer additionally stores a unique ID for the currently front-most object. If a voxel is projected onto the intermediate image, it's ID is compared with the stored ID in the object buffer. If both IDs match, the value in the object buffer is updated using an operation which corresponds to the local rendering mode of the object (maximum selection or blending of the voxel value with the buffer content). If the ID of the voxel differs from the ID of the pixel in the buffer, the viewing ray though this pixel must have entered a new object. The content of the object buffer pixel has to be combined with the corresponding global buffer pixel using an operation which depends on the global rendering strategy (MIP or DVR). Afterwards the object buffer pixel is initialized according to the voxel of the new object and the new local rendering mode. After all voxels have been projected, the contribution of the front-most segment at each pixel has to be included by performing an additional scan of the buffers and merging the segment values left in the local buffer into the global buffer.