Global ImageLoader Classes Table of Contents


Availability  LightWave® 6.0
Component  Layout, Modeler
Header  lwfilter.h

Image filter plug-ins apply image post processing (filtering) effects to the rendered image.

Handler Activation Function

   XCALL_( int ) MyImageFilter( int version, GlobalFunc *global,
      LWImageFilterHandler *local, void *serverData );

The local argument to an image filter's activation function is an LWImageFilterHandler.

   typedef struct st_LWImageFilterHandler {
      LWInstanceFuncs *inst;
      LWItemFuncs     *item;
      void            (*process)(LWInstance, const LWFilterAccess *);
      unsigned int    (*flags)  (LWInstance);
   } LWImageFilterHandler;

The first two members of this structure contain standard handler functions. In addition to these, an image filter provides a processing function and a flags function.

The context argument to the inst->create function is a pointer to an integer containing context flags. If the LWFCF_PREPROCESS flag is set, the instance is being created for an image other than the rendered output, and buffers other than the RGBA of the image won't be available.

An image filter can be activated by both Layout and Modeler. When activated by Modeler, the LWItemFuncs pointer in the local data is NULL. Be sure to test for this before filling in the useItems and changeID fields. Note too that if your image filter relies on Layout-only globals, those won't be available when Modeler calls your callbacks.

process( instance, access )
This is where the image filter does its work. For each frame, the filter is given access to the red, green, blue and alpha channels of the rendered image, along with any other image buffers requested by the flags function. The access structure, described below, provides image information and functions for examining the buffers and writing new RGB and alpha values.

flags( instance )
Returns an unsigned int that tells the renderer which buffers the image filter will need to examine. The return value contains bitfields combined using bitwise-or. Note that there are two sets of values supplied in lwfilter.h: buffer types, and corresponding buffer flags. However, not all buffer types can be asked for, some buffers are always available, and some buffers are calculated from other buffers. Before LW9.6 the buffer types were used for both the flags and the processing callbacks. To avoid some confusion, in LW9.6 buffer types and flags were separated in a compatible manner.

The renderer may ignore requests from the processing function for access to any buffers you haven't asked for here. The buffers are:

The final output of the rendering pass. These form the image to be modified by the filter. They are always provided to every image filter (it isn't necessary to return flags for them in the flags function).

The raw, unshaded values of the surface parameters at each pixel.

A picture of the diffuse shading and specular highlights applied to the objects in the scene. This is a component of the rendering calculations that depends solely on the angle of incidence of the lights on a surface. It doesn't include the effects of explicit shadow calculations.

Like the LWBUFF_SHADING buffer, but these store the amount of diffuse and specular shading (highlighting) separately, rather than adding them together. They should not be confused with the LWBUFF_DIFFUSE and LWBUFF_SPECULAR buffers, which store the unshaded surface values for those parameters.

Indicates where shadows are falling in the final image. It may also be thought of as an illumination map, showing what parts of the image are visible to the lights in the scene.

The values in this buffer are the dot-products of the surface normals with the eye vector (or the cosine of the angle of the surfaces to the eye). They reveal something about the underlying shape of the objects in the image. Where the value is 1.0, the surface is facing directly toward the camera, and where it's 0, the surface is edge-on to the camera.

The distance from the camera to the nearest object visible in a pixel. Strictly speaking, this is the perpendicular distance from the plane defined by the camera's position and view vector. Also known as the z-buffer.

Support for 2D vector-based motion blur. These buffers contain the pixel distance moved by the item visible in each pixel. The amount of movement depends on the amount of time the shutter was open (controlled by the blur length user setting) and includes the effects of the camera's own motion.

The RGB levels of the contribution from mirror reflections calculated by raytracing or environment mapping.

Contains user-assigned values that are unique for each surface.

The refraction color and alpha values.

Interface Activation Function

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

This is the standard interface activation for handlers.

Filter Access

This is the access structure passed to the processing function. The data members are read-only. The functions provide the means to get and set pixel values, and the optional monitor informs the user of the filter's progress.

   typedef struct st_LWFilterAccess {
      int        width, height;
      LWFrame    frame;
      LWTime     start, end;
      float *   (*getLine)  (int type, int y);
      void      (*setRGB)   (int x, int y, const LWFVector rgb);
      void      (*setAlpha) (int x, int y, float alpha);
      LWMonitor *monitor;
   } LWFilterAccess;
width, height
The dimensions, in pixels, of all of the image buffers.

The frame number.

start, end
The start and end times for the frame. These times are the same unless the frame was rendered with motion blur, in which case the difference between them can be considered the exposure time for the frame.

buf = getLine( buftype, y )
Returns a pointer to the start of a scanline from the specified buffer. y=0 is the top line of the buffer, and y=height-1 is the bottom line. Don't try to look past the end of a scanline. Layout may not store scanlines contiguously for a given buffer. In fact, scanlines aren't guaranteed to exist at all until they're requested through these functions. The type codes are of the form LWBUF_* listed in lwfilter.h, and are not to be confused with the buffer flags (LWBUFF_*). Generally each buffer flag has a corresponding buffer type. NULL is returned for invalid type codes, or type codes for buffers not requested by the flags function.

setRGB( x, y, rgb )
setAlpha( x, y, a )
Use these functions to set the output values of the filter. The input RGBA buffers do not change as the output buffers are modified. A filter must set every pixel in the output image even if it does not alter the value, but it can set them in any order.

The filter can use this to update the user about its progress through the frame. This also allows the user to cancel the rendering during the filter's processing. The monitor mechanism is the same one provided by the monitor global. As with all monitors, the number of steps should be kept fairly low since checking for abort can have significant overhead on some systems.


The negative sample is a simple filter that inverts the colors of the image. The convolve sample is a somewhat more complete example. It applies a 3 x 3 convolution to the image and includes an interface that allows the user to set the values of the filter kernel. These values are stored and retrieved using the handler save and load functions. The zcomp sample includes an image filter that saves the current LWBUF_DEPTH buffer to a file.