PixelFilterHandler
PixelFilterInterface
Availability LightWave 6.0
Component Layout, Modeler
Header lwfilter.h
Pixel filters apply image processing effects to individual pixels in
the rendered image.
Pixel filters look like image filters at
first glance, but they differ in several significant ways. Pixel filters
can modify any of the buffers, not just the red, green, blue and alpha
values, and they have access to the raytracing
functions. They're applied during rendering, before antialiasing and
motion blur, so their effects are automatically accumulated by Layout for
antialiasing and motion blur purposes.
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.
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.
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.
A pixel 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 pixel filter relies on Layout-only globals,
those won't be available when Modeler calls your callbacks.
-
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 values.
-
flags( instance )
-
Returns an int that tells the renderer which buffers the pixel filter will
examine and/or modify 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. See the image
filter page for a list of the buffer codes. In addition to these, the
LWPFF_RAYTRACE flag indicates that the evaluation function will
call the raytracing functions, and the LWPFF_EVERYPIXEL flag indicates
that the filter should be evaluated for every pixel, despite adaptive sampling
settings.
Interface Activation Function
XCALL_( int ) MyInterface( long version, GlobalFunc *global,
LWInterface *local, void *serverData );
This is the standard interface activation
for handlers.
Pixel Access
The pixel access structure passed to the evaluation function contains
the pixel coordinates for the sample, functions for getting and setting
pixel values, and the raytracing functions. 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 (*getVal) (int type, int num, float *);
void (*setRGBA) (const float[4]);
void (*setVal) (int type, int num, float *);
LWIlluminateFunc *illuminate;
LWRayTraceFunc *rayTrace;
LWRayCastFunc *rayCast;
LWRayShadeFunc *rayShade;
} LWPixelAccess;
-
sx, sy
-
Image coordinates of the sample, in pixel units. These will often contain
fractional values.
-
getVal( type, buflen, buf )
-
Get a pixel value from one of the buffers. If the buffer type is invalid
or a type not requested by the flags function, the pixel value returned
in buf is undefined. See the image
filter page for the list of buffer types. buflen is 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.
-
setRGBA( rgba )
-
The RGBA (red, green, blue and alpha) output of the pixel filter. This
must be called even if the filter doesn't modify the values.
-
setVal( type, buflen, buf )
-
Write a value to one of the buffers.
-
lit = illuminate( lightID, position, direction, color )
len = rayTrace( position, direction, color )
len = rayCast( position, direction )
len = rayShade( position, direction, shaderAccess )
-
These functions trace rays into the scene. See the raytracing
functions page for details. You can only use these if the return value
of your flags function includes the LWPFF_RAYTRACE flag.
Example
The zcomp sample includes a pixel
filter that composites the render with an image sequence using the LWBUF_DEPTH
buffer. zcomp compares the depth at each pixel with the corresponding depth
in the image to be composited, and substitutes the image pixel if it's
nearer in z order to the camera.
The mandfilt sample turns LightWave
into a Mandelbrot set renderer. Unlike most real pixel filters, it simply
overwrites the pixel values with its own output, so it should be run in
an empty scene. But it does demonstrate how pixel filter output is antialiased
and adaptively sampled by LightWave. |