1.5.3. Volume rendering quality settings

Most volume rendering quality settings are part of the SoVolumeRenderingQuality( C++ | Java | .NET ) node, but not all. For example, the number of samples and related setting are part of the SoVolumeRender( C++ | Java | .NET ) node. SoVolumeRenderingQuality( C++ | Java | .NET ) also has fields that control volume rendering effects (e.g. lighting) and volume rendering modes (e.g. isosurface rendering). Those fields will be discussed in the corresponding sections. SoVolumeRenderingQuality( C++ | Java | .NET ) is a “property” node and should appear after the SoVolumeData( C++ | Java | .NET ) node and before the SoVolumeRender( C++ | Java | .NET ) node that it applies to. SoVolumeRenderingQuality( C++ | Java | .NET ) is also a shader node (derived from SoShaderProgram( C++ | Java | .NET ) and SoVolumeShader( C++ | Java | .NET )). Applications may use this node (instead of SoVolumeShader( C++ | Java | .NET )) to install custom shaders, in order to use the advanced rendering settings together with their shader. Because this is a shader node, it will affect the rendering of standard Open Inventor geometry nodes (usually in an undesirable way). Standard geometry and volume primitives can be used in the same scene, but generally the application should put them under different SoSeparator( C++ | Java | .NET ) nodes in the scene graph.

In this section we will discuss:

In addition to the common volume primitive parameters – interpolation and composition – the SoVolumeRender( C++ | Java | .NET ) node has additional parameters for controlling the number of samples computed along each ray. For historical reasons these parameters use the term “slice” instead of “sample”. Increasing the number of samples will generally increase the image quality, but reduce performance (frame rate) because of the extra computation required. Conversely, decreasing the number of samples will generally improve performance (frame rate), but reduce the image quality. It is often useful to use a high sample number for “static” rendering (when the user is not interacting with the scene) and a lower number of samples when the user is moving the camera or dragging objects in the scene. There are several other ways to temporarily increase performance that will be discussed in a later section. As with any “sampling problem”, the number of samples generally needs to be larger than the size (voxel dimensions) of the volume to ensure that every voxel contributes to the final image. “Super-sampling”, increasing the number of samples beyond the dimensions of the volume, is supported.

The numSlicesControl field controls how the number of samples is computed.

ALL

Number of samples is based on the volume dimensions. (Default.)

The number of slices depends on the viewing direction.

MANUAL

Use the number of samples specified by the numSlices field. The number of slices does not depend on the viewing direction.

AUTOMATIC

Number of samples is computed as follows:

If numSlices is greater than zero, then

n = complexity * 2 * numSlices

where complexity comes from the value field of the SoComplexity( C++ | Java | .NET ) node and numSlices comes from the numSlices field. The default value for complexity is 0.5. The number of samples does not depend on the viewing direction.

If numSlices is any value less than or equal to 0, the dimension of the volume data is used instead of numSlices, so

n = complexity * 2 * volumeDimension

The number of samples depends on the viewing direction.

The factor 2 is used because by default complexity is equal to 0.5. So, by default, the behavior for numSlices greater than zero is the same as MANUAL and the default behavior for numSlices less than or equal to zero is the same as ALL.

You can increase the complexity up to 1.0, which would double the number of samples used. You can decrease the complexity to reduce the number of samples used. By default, the global alpha is corrected so that the brightness looks the same (see opacityCorrection).

MAIN_AXIS

Number of samples is computed as follows:

n = complexity * 2 * volumeDataDimension[mainVisibleAxis]

where complexity comes from the value field of the SoComplexity( C++ | Java | .NET ) node. The number of samples depends on the viewing direction.

The numSlices field controls the number of samples when numSlicesControl is not set to ALL. The default is zero, which means to use the volume dimension.

The fixedNumSlicesInRoi field. When this field is set to FALSE (the default), the number of samples set by numSlices is the number of samples across the current region of interest (ROI). Therefore the sample interval, or density of samples, may change when the ROI size changes. When this field is TRUE, numSlices is the number of samples across the whole volume. So the sample density is constant, independent of the ROI size. The default is FALSE. Region of interest is discussed in section Section 1.7, “Clipping”.

The opacityCorrection field controls whether opacity correction is done. If TRUE, opacity is automatically adjusted to give a similar appearance no matter how many samples are used. If FALSE, opacity is not corrected and increasing the number of samples will increase the opacity. The default value is TRUE.

Volume projection (SoProjection( C++ | Java | .NET ) and its subclasses) is incompatible with some options enabled by this node. In particular do not enable the preintegrated, jittering or edgeDetect2D fields when using projection.

With pre-integrated volume rendering, VolumeViz precomputes the volume rendering integral for pairs of sample values using the current transfer function. At rendering time the ray casting engine effectively considers a “slab” of data rather than an individual sample point. The volume is sampled at the front and back of the sampling slab. Pre-integrated rendering can significantly increase image quality without increasing the sampling rate. This is especially true if the transfer function contains sharp changes in value. Default value for preIntegrated field is TRUE.



If the jittering field is set to true, a random offset is added to the coordinates of each sample point. Using a relatively low number of samples along the ray (the section called “Number of samples” 22.5.3.1) can cause aliasing effects commonly called “wood grain” or “ring” artifacts. Increasing the number of samples will reduce these artifacts but also reduce performance. Jittering is an anti-aliasing technique that reduces these artifacts, for the same number of samples, by introducing a small amount of noise into the image. Jittering is only available when the preIntegrated field is set to true, else it has no effect. The default is FALSE.




If the cubicInterpolation field is set to true, cubic interpolation (instead of linear interpolation) is used to compute a data value from the neighboring voxels. This can produce higher quality images, but reduces rendering performance. Applications may implement their own interpolation algorithms using custom shaders.