ObjReplacementHandler ProceduralTextureHandler Classes Table of Contents

PixelFilterHandler
PixelFilterInterface

Pixel filters apply image processing effects to individual pixels in the rendered image.

Background

Pixel filters look like image filters at first glance, but they differ in several significant ways. Pixel filters are applied during rendering, before antialiasing and motion blur, so their effects are accumulated for antialiasing and motion blur purposes by Layout automatically. And unlike image filters, which have access to the entire image and are called once per frame, pixel filters only evaluate, and only have access to, a single pixel sample at a time, and they can be called multiple times per pixel during the rendering of a frame.

In perhaps a less obvious way, pixel filters also resemble shaders, although they evaluate samples of the entire rendered image rather than a single surface, and they have access to somewhat different information. References to the documentation of both image filters and shaders will be made here.

Handler Activation Function

   XCALL_( int ) MyPixelFilter( long version, GlobalFunc *global,
      LWPixelFilterHandler *local, void *serverData );

The local argument to a pixel filter's activation function is an LWPixelFilterHandler.

   typedef struct st_LWPixelFilterHandler {
      LWInstanceFuncs *inst;
      LWItemFuncs     *item;
      LWRenderFuncs   *rend;
      void            (*evaluate) (LWInstance, const LWPixelAccess *);
      unsigned int    (*flags)    (LWInstance);
   } LWPixelFilterHandler;

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

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

flags( instance )
Returns an int that tells the renderer which buffers the pixel filter will need to examine and whether the evaluation function will call one of the raytracing functions in the access structure. The return value contains bitfields combined using bitwise-OR.

LWPFF_RAYTRACE
Indicates that the evaluation function will call one of the raytracing functions. Unless this flag is part of the return value, the raytracing functions won't be available.

See the ImageFilterHandler page for a list of the buffer codes. The LWBUF codes listed there and in lwfilter.h are bit positions, not the flags themselves, so you'll need to form the expression (1 << LWBUF_WHATEVER) to create the flags before ORing them together. (You don't need to do this to LWPFF_RAYTRACE.) For efficiency reasons, the renderer will ignore requests from the evaluation function for access to any buffers that weren't indicated by the bit flags returned from the flags function.

Interface Activation Function

   XCALL_( int ) MyInterface( long version, GlobalFunc *global,
      ??? *???, void *serverData );

TBD.

Pixel Access

This is the access structure passed to the evaluation function. Because the sampling of the output image is adaptive, pixel positions may be evaluated in any order, multiple times, or not at all. The evaluation function must call setRGBA for every pixel it evaluates, even if the filter doesn't modify the pixel.

   typedef struct st_LWPixelAccess {
      double            sx, sy;
      void             (*bufVal)  (int type, int num, LWBufferValue *);
      void             (*fltVal)  (int type, int num, float *);
      void             (*setRGBA) (LWBufferValue[4]);
      LWIlluminateFunc *illuminate;
      LWRayTraceFunc   *rayTrace;
      LWRayCastFunc    *rayCast;
      LWRayShadeFunc   *rayShade;
   } LWPixelAccess;
sx, sy
Image coordinates of the sample, in pixel units. These are floating point values that indicate the position of the sample on some idealized continuously valued image. The integer pixel coordinates are just these values truncated.

bufVal( type, buflen, buf )
fltVal( type, buflen, buf )
Get a pixel value from one of the buffers. bufVal returns values from byte-encoded buffers and fltVal returns values from float-encoded buffers. If the buffer type is invalid, or a buffer not requested by the flags function, the returned pixel value is undefined.

type
The LWBUF code of the buffer to examine. See the image filter page for a complete list.
buflen
The number of contiguous values to return. For most buffers, this number will be 1, but the RGB buffers can be retrieved all at once. With a type of LWBUF_RAW_RED, for example, the number can be up to 3 to get RAW_RED, RAW_GREEN and RAW_BLUE, and for LWBUF_RED it can be up to 4, for the RGBA values.
buf
The requested pixel values are copied to this location. It must point to enough memory to hold buflen values, buflen * sizeof( LWBufferValue ) for bufVal and buflen * sizeof( float ) for fltVal.

setRGBA( rgba )
The output of the pixel filter (red, green, blue and alpha) is set by calling this function. The pixel filter must set the output RGBA even if it doesn't modify the input value.

illuminate( lightID, position, direction, color )
rayTrace( position, direction, color )
rayCast( position, direction )
rayShade( position, direction, shaderAccess )
These functions trace rays into the scene. See the discussion of the raytracing functions in the ShaderHandler documentation for details.