ShaderHandler AnimLoaderHandler Classes Table of Contents


Availability  LightWave® 6.0
Component  Layout
Header  lwvolume.h

Volumetric handlers model the attenuation and scattering of light in gases, differences in density in 3D medical imaging data, or the shapes of surfaces too complex to model explicitly with geometry. They do this by participating in LightWave®'s raytracing mechanism.

For each ray fired into the scene, the volumetric handler calculates a color and opacity for one or more samples. It hands each sample back to LightWave®, which integrates all of the samples from all of the volumetrics to produce the final color seen from the source of the ray.

A sample represents a segment of the ray over which the color and opacity are constant.  Consider a simple cloud pierced by a ray. The handler that draws the cloud isn't interested in the parts of the ray that are outside it, so it creates no samples there. In the simplest case, it may create a single sample that begins at the point where the ray enters the cloud and extends as far as the ray remains inside. If the cloud is somewhat transparent, the color might be a linear combination of the cloud color and the backdrop color, and the opacity will be somewhat less than 1.0.

Handler Activation Function

   XCALL_( int ) MyVolumetric( int version, GlobalFunc *global,
      LWVolumetricHandler *local, void *serverData );

The local argument to a volumetric handler's activation function is an LWVolumetricHandler.

   typedef struct st_LWVolumetricHandler {
      LWInstanceFuncs *inst;
      LWItemFuncs     *item;
      LWRenderFuncs   *rend;
      double          (*evaluate) (LWInstance, LWVolumeAccess *);
      unsigned int    (*flags)    (LWInstance);
   } LWVolumetricHandler;

The first three members of this structure point to the standard handler functions. In addition to these, a volumetric handler provides an evaluation function and a flags function.

d = evaluate( instance, access )
Called for each ray fired into the scene. The evaluation function adds zero or more samples to the ray, based on the information in the access structure, described below.

f = flags( instance )
Returns an int that tells the renderer which effects the handler supplies. The return value contains bitfields combined using bitwise-or.

The evaluation function can be called for shadow rays.
Can be evaluated for reflection rays.
Can be evaluated for refraction rays.

Interface Activation Function

   XCALL_( int ) MyInterface( int version, GlobalFunc *global,
      LWInterface *local, void *serverData );

This is the standard interface activation for handlers.

Volumetric Access

This is the structure passed to the handler's evaluation function.

   typedef struct st_LWVolumeAccess {
      void             *ray;
      int               flags;
      LWItemID          source;
      double            o[3], dir[3];
      double            rayColor[3];
      double            farClip, nearClip;
      double            oDist, frustum;
      void             (*addSample) (void *ray, LWVolumeSample *smp);
      double           (*getOpacity)(void *ray, double dist,
                                       double opa[3]);
      LWIlluminateFunc *illuminate;
      LWRayTraceFunc   *rayTrace;
      LWRayCastFunc    *rayCast;
      LWRayShadeFunc   *rayShade;
      double            sx, sy;
      int               bounces;
      LWRayTraceModeFunc     *rayTraceMode;
      LWIlluminateSampleFunc *illuminateSample;
      RandomFloatData        randomData;
      LWRandomFloatFunc      *randomFloat;
      LWIlluminateNormalFunc *illuminateNormal;
      LWIlluminateSampleNormalFunc *illuminateSampleNormal;
   } LWVolumeAccess;
An opaque pointer to LightWave®'s representation of the ray. Pass this as the first argument to the addSample and getOpacity functions.

Evaluation flags. Some of these allow the evaluation function to streamline its calculations.

Calculate an opacity value for each sample. When this flag is absent, the opacity calculation can be omitted.
Calculate a color for each sample.
If this flag is absent, the evaluation function is being called during the volumetric pass that occurs before pixel filtering but after normal rendering. Otherwise the evaluation function is being called during "regular" raytracing (reflection, refraction or shadow rays, for example).
The ray originates from the camera. When this flag is absent, a secondary ray is being evaluated ie. (reflection, refraction or shadow rays, for example).
The ray originates from radiosity.
This flag is on if the incoming ray was cast for sampling soft reflections, etc.
This flag is on if the incoming ray is a radiosity preprocess ray.
This flag is on if the incoming ray is a reflection ray. If this flag is absent, the camera ray flag is absent and the color flag is present, its a refracted ray.

The item from which the ray originated. This can be a light (for shadow rays), a camera, or LWITEM_NULL for other sources.

, dir
The origin and direction of the ray. The origin is the position of the source item or of a spot on the surface of the source object.

, near
Far and near clipping distances. These are distances along the ray measured from the origin o along the direction dir. All sample segments will normally fall between these two.

The color seen from the origin of the ray, before volumetric effects are applied.

Distance from the origin o to the true start of the viewing path. This is non-zero for reflection and refraction rays. If the origin o is a spot on the surface of an object, oDist is the distance from that spot to the camera. This is good to know if your calculations will be based on the length of the path to the viewer (the camera) and not just on the length of the ray fired from the spot on the object.

Pixel frustum, equal to 2 * tan(0.5 * hfov)/w, where hfov is the horizontal field of view and w is the width of the rendered image in pixels. The frustum is a measure of the size of a pixel relative to the ray. (It's the actual size of the pixel at a distance of 1.0.) This quantity plays a role in calculating sample size, or stride, during raymarching. A typical calculation of the stride might look like
increment = scale_factor * frustum;
stride = dist * increment;
addSample( ray, sample )
Add a new volume sample to the ray. This is how volumetric handlers submit their contributions to the integration of opacity and color along the ray. The sample structure is described below.

opacity = getOpacity( ray, dist, opa )
Returns the currently calculated opacity (vector and scalar) at the specified distance.

Rendering Functions

lit = illuminate( lightID, position, direction, color )
len = rayTrace( position, direction, color )
len = rayCast( position, direction )
len = rayShade( position, direction, shaderAccess )
len = rayTraceMode( position, direction, color, eta, rtmode )
lit = illuminateSample( lightID, position, direction, sampler, data )
lit = illuminateNormal( lightID, position, direction, normal, color )
lit = illuminateSampleNormal( lightID, position, direction, normal, sampler, data )
See the raytracing functions page for a description of these.

, sy
The position of the pixel for which the volumetric is being evaluated. The position includes the sub-pixel position due to anti-aliasing for example.

The number of times the viewing ray has branched to reach the evaluation of this volumetric.

The function generates a random number on [>0, <1] interval.

Volume Sample

A volume sample is a single ray segment with a uniform color and opacity. The distance and stride define the position and size of the sample, and the opacity and color are given as color vectors. By the way, you can create surface samples by setting stride to 0 and dist to 0.9999 * farClip.

   typedef struct st_LWVolumeSample {
      double  dist;
      double  stride;
      double  opacity[3];
      double  color[3];
   } LWVolumeSample;
The starting point of the sample expressed as a distance from the origin of the ray. This should be greater than or equal to nearClip.

The length of the sample. dist + stride should be less than or equal to farClip.

The red, green and blue components of the opacity of this sample.

The color at this sample.


LightWave® 9.0 (volumetric class version 5) added the sx, sy and bounces fields to the volumetric access structure.

Class version 6 added the illuminateSample function to the volumetric access structure.


The atmosphere sample is a straightforward implementation of some of the volumetric techniques discussed in chapter 14 (K. Musgrave, L. Gritz, S. Worley) of Texturing and Modeling, 2nd ed., Academic Press, 1998. It includes both a fast analytical solution that creates a single sample and a more refined solution that uses raymarching and multiple samples per ray.