VolumetricHandler
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.
LWVOLF_SHADOWS
- The evaluation function can be called for shadow rays.
- LWVOLF_REFLECTIONS
- Can be evaluated for reflection rays.
- LWVOLF_REFRACTIONS
- 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;
- ray
- An opaque pointer to LightWave®'s representation of the ray. Pass this as the first
argument to the addSample and getOpacity functions.
flags
- Evaluation flags. Some of these allow the evaluation function to streamline its
calculations.
LWVEF_OPACITY
- Calculate an opacity value for each sample. When this flag is absent, the opacity
calculation can be omitted.
- LWVEF_COLOR
- Calculate a color for each sample.
- LWVEF_RAYTRACE
- 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).
- LWVEF_CAMERA
- 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).
- LWVEF_RADIOSITY
- The ray originates from radiosity.
- LWVEF_SAMPLEDRAY
- This flag is on if the incoming ray was cast for sampling soft reflections, etc.
- LWVEF_PREPROCESS
- This flag is on if the incoming ray is a radiosity preprocess ray.
- LWVEF_REFLECTION
- 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.
source
- The item from which the ray originated. This can be a light (for shadow rays), a camera,
or LWITEM_NULL for other sources.
o, 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.
far, 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.
rayColor
- The color seen from the origin of the ray, before volumetric effects are applied.
oDist
- 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.
frustum
- 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.
sx, 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.
bounces
- The number of times the viewing ray has branched to reach the evaluation of this volumetric.
randomFloat
- 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;
- dist
- 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.
stride
- The length of the sample. dist + stride should be less than or equal to farClip.
opacity
- The red, green and blue components of the opacity of this sample.
color
- The color at this sample.
History
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.
Example
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. |