Tutorial-The ScanLine Shader

In V7.01, a new type of plugin (the scanline shader) was added to OpenRender. Like all OpenRender shaders, the scanline shader centers around a CALC function. This CALC function gets called once per scanline. For example, if you are rendering an image that is 640x480, your scanline shader plugin will be called 480 times. Within the CALC function, your shader has access to the RGBA colors for all pixels on the previous, current, and next scanlines, and also has access to any custom data that you may need (more on this later).

Example code for this type of shader can be found in:

/usr/aw/alias/ODS/OpenRender/samples/plabel
or possibly:
/usr/aw/alias/ODS/OpenRender/samples/scanline

The CALC Function

Recall that the shader CALC function looks like:

static int CALC (
AR_ShaderInfo *pShader,
AR_GeometryInfo *ar_geom,
AR_ShadeData *pShadeData,
AR_OCR_ObjectInfo *object_info,
void *ni,
void *rt_ray_rec
)

For the scanline shader, the scanline data is found in the second parameter, ar_geom. Typically you will access the scanline data by casting the ar_geom variable to type AR_PoseShadeData:

AR_PostShadeData* postShadeData =
(AR_PostShadeData*) ar_geom;

where AR_PostShadeData is defined as:

typedef struct AR_PostShadeData {
AR_PostScanlineData* previous;
AR_PostScanlineData* current;
AR_PostScanlineData* next;
AR_Rgba* previous_color;
AR_Rgba* current_color;
AR_Rgba* next_color;
int resolution;
char* image_output;
} AR_PostShadeData;

For each call to the CALC function, you have access to the current scanline, and also the previous and next scanlines. If this is the first scanline, then the previous scanline pointer will be NULL, and if this is the last scanline, the next scanline will be NULL. For example, to print out the RGB colors for all pixels in the current scan static int nScanLine = 0;

for (int i=0;i<postShadeData->resolution;i++)
{
printf("RGB of pixel (%4d,%4d) = (%4d,%4d,%4d)\n",
i,nScanLine,current_color->[i].r,
current_color->[i].g,
current_color->[i].b);
}
nScanLine ++;

The size of the Image

The number of pixels per scanline can be found in the resolution field of the AR_PostShadeData structure. The number of scanlines can be calculated by counting the number of times the CALC function is called. If you need to know this information up front, here is an easy way to do it:

static int nXSize;
static int nYSize;
// grab data on first call to CALC
if (postShadeData->previous == NULL)
{
nXSize = ar_render_options.xresolution;
nYSize = ar_render_options.yresolution;
}

Passing other data

So far, we have seen that you can access the color information for each scanline, but what if you want some other type of data. For instance, you may want to know the normal vector, object id, object name, or some other piece of data. This is where the previous, next, current fields of the AR_PostShadeData structure come into play. For example, the current field is an array of pointers to data that is created in a standard shader plugin. If the pointer is NULL, then no data was created for that pixel; if the pointer is not NULL, then another shader allocated a data structure for this pixel.

This is best explained with an example. Please refer to the following directory and files:

./ODS/OpenRender/ocr/samples/scanline

file: orNormal1.c - Source file for an OpenRender shader plugin. This plugin stores the normal vector for each pixel in user data, which is later looked at in the scanline shader (orNormal2.c)

file: orNormal2.c - Source file for an OpenRender scanline shader plugin. This plug-in gathers the normal vector data that was generated in orNormal1.c, and stores the whole image worth of data into a new image.

file: orNormal.perl - This perl script reads the file input.sdl and generates the file output.sdl. The input.sdl file is a normal sdl that you would save in Alias. The output.sdl is a modified sdl that contains the load calls for the OpenRender plug-ins, the image_shader stanza, and also adds a layered shader to all geometry. This layered shader is orNormal1.c; this way, all geometry gets passed through this shader.

file: runit - A script to run the perl script, render, and look at the results.

To run this example, please type ./runit





[email protected]
Copyright ©1998, Alias|Wavefront, a Silicon Graphics Company. All rights reserved.