Introduction to volume rendering

Written by Paul Bourke
January 1996


Introduction

Perhaps the most common form of modelling and rendering in conputer graphics involves geometric data made up of points, line, polygons, spheres, curved surfaces, etc. However, there are many application where decomposing the data to be rendered or visualised into those geometric forms is inconvenient or downright inappropriate. An example of this type of data is commonly refered to as volumetric data, in the simplest case this is a volume inside which some scalar property such is density is known at every point (or at least on a grid of some finite resolution).
Often an understanding of the distribution of density, say, within the volume can be obtained by deriving an isosurface. That is, a 3D contour is created at a selected density, the resulting surface shows all the regions that are more (or less) dense than the chosen contour level. This often works well for volumes with strong and obvious internal structure, for example, showing the bone from an MRI scan of a part of the human body. This method doesn't work well for volumes with more subtle variation or when multiple density ranges need to be shown or when illustrating multiple interacting scalar properties.
In these cases a more immediate method is chosen, the volume is rendered directly without decomposing it into geometric primitives. Typically the scalar property within the volume is assigned a colour and transparency depending on lookup tables, rays are traced into the volume and they are attenuated and coloured depending on the transparency of their route through the volume.

Example

In the following example we will create an artificial density distribution within a 100x100x100 grid. While this is quite a coarse grid, the memory and processing required goes up by the third power of the linear dimension. So while a 1003 grid with one byte per grid cell (256 density levels) requires 1MB to store the data, a 3003 grid requires 27MB, and a 6003 grid requires 216MB.

The graph above shows the density distribution for this example, it is the same along all three dimension of the grid. That is, the center of the grid has the highest density and it drops of exponentially towards the edges of the grid. Note that this is a very simple distribution and it doesn't contain any of the artifacts and noise that volume distributions in real applications have. It is however useful to use a simple distribution that is totally understood when experimenting with volume rendering.
The vertical axis isn't shown with units because it isn't that important for this example. Because it is common to store 1 byte at each pixel, the scale in this case would be from 0 (vacuum say) to 255 (maximum density).

The most important aspect of volume rendering is specifying the transfer functions that map density (or other scalar variables) within the volume to colour and transparency. The example volume (Source Code) we're using here has a radial density falloff from the center, so if we make all densities perfectly transparent except for a narrow range of densities that we will make perfectly opaque, we should "see" a sphere when we render the volume. As expected this is shown below. Note that this sphere is hollow but we can't see into the inside because we made the density within a narrow range totally opaque.

The graph on the left above illustrates the transparency transfer function. The horizontal axis is the density axes from 0 to 255 in this case. The vertical axes is opacity that ranges from 0 (totally transparent) to 1 (totally opaque).
The sharpness and bumpiness of the above rendering is a consequence of two factors, the discreteness of the data in this example (only 100x100x100 cells), and the sharpness of the transparency transfer function.

In this next case the transparency will be slowly decreased (opacity increased) from zero at 0 density. All cells with a density greater than some cutoff value will be totally transparent. The result should be a hollow sphere with a cloud-like surround.

The next case combines the last two transparency mappings just to illustrate that there is a transparent cloud. A range of high densities will be made totally opaque forming a ball as in the first example but smaller since the range of densities that are made opaque is higher.

Up to now we've just been considering a transparency map, we can also create colour maps which are also functions of density. For this next case we can make the center dense sphere blue by reducing the red and green components of the same density range.
The top graph on the left below is the transparency map as before, the bottom graph is the colour transfer function. The vertical scale on the colour transfer function ranges from 0 (none of that colour component), to 1 (fully saturated component) in each of the three components, red, green, and blue.


And finally, by similar techniques we can make the transparent cloud-like surround reddish.


Software comments

Volume rendering software distinguish themselves in various ways, some of these are discussed below.