Tutorial-Changing the ALIAS OpenRender Template

In this section we detail which sections of the ALIAS OpenRender Template file should be modified to write your own ALIAS OpenRender C code module.

The first step is to decide what type of data your module will need. To do this, you need to know that Alias already has some standard data items that it maintains. Each type of object (light/shader/texture) has a certain number of standard, Alias-defined data items that are parsed, evaluated and initialized automatically. These standard data items are available to you in the CALC routines in the data structures: AR_LightInfo, AR_ShaderData or AR_TextureData (depending, of course, on which type of ALIAS OpenRender C module you are writing).

Note: It cannot be stressed enough that the values in the Alias supplied AR_ structures should not be changed by you at any time, unless explicitly requested in the prototypes.

The following tables contain the fields in the various data structures that are available for you to use in the CALC routines. These types are defined in ALIAS OCR_types.h. Any fields not described below are for Alias internal use only.

Standard Alias Shader Data Items

All values in the following AR_ShadeData structure are final values of the current point. If any of these values have been textured, the values in these fields have had the textures applied. The Normal and the crosspt have already been bump mapped and displacement mapped if such textures were applied.

The only field in AR_ShadeData that can (and must) be modified by you is the transcol field. This field must hold the result of the shading computation when the shader returns.

AR_ShadeData Structure
Field Name Type Meaning
surfColor AR_Rgba * A pointer to the color of the surface at the current point.
incandescence AR_Rgba The incandescence of the surface at the current point.
surfTrans AR_Rgba The transparency of the surface at the current point.
crosspt AR_Point * A pointer to the current point's coordinates (x, y, z).
Normal AR_Vector The normal at the current point.
utangent AR_Vector The tangent in the U parametric direction.
vtangent AR_Vector The tangent in the V parametric direction.
Sight AR_Vector * A pointer to the normalized direction vector of the incident ray.
lights AR_LightList * A list of lights that can possibly illuminate this point.
transcol AR_Rgba * A pointer to the color behind the current surface (see shader template).
refractive_index double The refractive index of the surface.
void* user_shade_data place holder for per pixel user defined data

Standard Alias Light Data Items

AR_LightInfo Structure
Field Name Type Meaning
name char * The unique name of the light (not the model name).
intensity float The intensity of the light.
color AR_TextureType The color of the light.
transformed_color AR_Rgb The color of the light multiplied by the intensity.
shadows AR_Boolean TRUE if shadows are to be calculated for this light.
user_light_info void * This is a pointer to the data structure you have defined.

AR_LightData Structure
ambient AR_Boolean TRUE if light contributes to ambient shading
diffuse AR_Boolean TRUE if light contributes to diffuse shading
specular AR_Boolean TRUE if light contributes to specular shading
intensity AR_Rgb Returned color of lighting
direction AR_Vector Returned direction from surface to light
void * user_data For user-defined data structures
computed_cosln AR_Boolean TRUE if cosln has been computed by the shader.
cosln float* The dot product between the surface normal and the light vector.

Standard Alias Texture Data Items

Every texture must place results into the TDcolor field of the AR_TextureData structure before returning successfully. Upon a successful texturing, the textures must place values in each of the red, green, blue and alpha channels. If the texturing is unsuccessful, then the value in the TDcolor field should not be modified.

AR_TextureData Structure
Field Name Type Meaning
TDdata AR_TextureInfo * Should only be used to get your INFO_TYPE data structure.
TDu float The value of the U parametric coordinate at the point of intersection.
TDv float The value of the V parametric coordinate at the point of intersection.
TDsize float The projected length of subtended pixel (used for blurring in Alias textures).
TDhit AR_Point * A pointer to the world space coordinates of the current point.
TDnormal AR_Vector * A pointer to the surface normal of the current point.
TDray AR_Vector * A pointer to the normalized direction vector of the incident ray.
TDcolor AR_Rgba * A pointer to space for the result of the texture.
TDblurmult float The value for the blur multiplication.
TDbluroffset float The value for the blur offset.

Standard SDL Parameters

ALIAS OpenRender C code modules let you extend the SDL syntax and increase the Alias Renderer's functionality. However, there are standard Alias SDL parameters that you can use in your shaders, lights, and textures. This section outlines the SDL parameters that Alias automatically parses, evaluates and calculates for your ALIAS OpenRender modules to use.

Note: The following lists are reserved SDL keywords. You cannot use these keywords for your SDL extensions because the Alias field will take precedence. For example, if you have a NODE field that you link to the SDL keyword "color," your field will never have anything put into it since the Alias shader keyword "color" is already linked to an Alias defined NODE structure.

Standard SDL Shader Parameters
SDL keyword AR_ShaderInfo field
refractive_index AR_ShaderInfo->refractive_index
color AR_ShaderInfo->color
colour AR_ShaderInfo->color (note:same as above)
incandescence AR_ShaderInfo->incandescence
transparency AR_ShaderInfo->transparency
bump AR_ShaderInfo->rel_bump
displacement AR_ShaderInfo->rel_displacement
transparency_shade AR_ShaderInfo->transparency_shade
reflection_limit AR_ShaderInfo->reflection_limit
refraction_limit AR_ShaderInfo->refraction_limit
shadow_level_limit AR_ShaderInfo->shadow_level_limit
respect_reflection_map AR_ShaderInfo->respect_reflection_map
shading_map AR_ShaderInfo->shading_map
surface_width AR_ShaderInfo->surface_width
transparency_depth AR_ShaderInfo->transparency_depth
refraction_jitter AR_ShaderInfo->refraction_jitter
refraction_samples AR_ShaderInfo->refraction_samples
chromatic_abberation AR_ShaderInfo->chromatic_abberation
fill_color AR_ShaderInfo->hl_fill_color
line_thickness AR_ShaderInfo->hl_line_width
u_patch_lines AR_ShaderInfo->hl_isoparam_u
v_patch_lines AR_ShaderInfo->hl_isoparam_v
glow_intensity AR_ShaderInfo->glow_intensity
hide_glow_source AR_ShaderInfo->hide_glow_source

Standard SDL Light Parameters
SDL keyword AR_LightInfo field
active AR_LightInfo->active
exclusive AR_LightInfo->exclusive
color AR_LightInfo->color
colour AR_LightInfo->color (note: same as above)
intensity AR_LightInfo->intensity
shadow AR_LightInfo->shadows
glow_type AR_LightInfo->glow->glow_type
halo_type AR_LightInfo->glow->halo_type
fog_type AR_LightInfo->glow->fog_type
glow_intensity AR_LightInfo->glow->glow_intensity
halo_intensity AR_LightInfo->glow->halo_intensity
fog_intensity AR_LightInfo->glow->fog_intensity
glow_spread AR_LightInfo->glow->glow_spread
halo_spread AR_LightInfo->glow->halo_spread
fog_spread AR_LightInfo->glow->fog_spread
glow_2D_noise AR_LightInfo->glow->glow_2Dnoise
fog_2D_noise AR_LightInfo->glow->fog_2Dnoise
glow_radial_noise AR_LightInfo->glow->glow_radial_noise
fog_radial_noise AR_LightInfo->glow->fog_radial_noise
glow_star_level AR_LightInfo->glow->glow_star_level
fog_star_level AR_LightInfo->glow->fog_star_level
glow_opacity AR_LightInfo->glow->glow_opacity
fog_opacity AR_LightInfo->glow->fog_opacity
radial_noise_frequency AR_LightInfo->glow->radial_frequency
star_points AR_LightInfo->glow->star_points
glow_rotation AR_LightInfo->glow->rotation
noise_uscale AR_LightInfo->glow->noise_uscale
noise_vscale AR_LightInfo->glow->noise_vscale
noise_uoffset AR_LightInfo->glow->noise_uoffset
noise_voffset AR_LightInfo->glow->noise_voffset
noise_threshold AR_LightInfo->glow->noise_threshold

Standard SDL Texture Parameters
SDL keyword AR_TextureInfo field
ucoverage AR_TextureInfo->uscale
vcoverage AR_TextureInfo->vscale
urepeat AR_TextureInfo->urepeat
vrepeat AR_TextureInfo->vrepeat
utranslate AR_TextureInfo->utranslate
vtranslate AR_TextureInfo->vtranslate
rgbmult AR_TextureInfo->RGBAmult
amult AR_TextureInfo->RGBAmult
blurmult AR_TextureInfo->blurmult
uoffset AR_TextureInfo->uoffset
voffset AR_TextureInfo->voffset
rgboffset AR_TextureInfo->RGBAoffset
aoffset AR_TextureInfo->RGBAoffset
bluroffset AR_TextureInfo->bluroffset
rgbout AR_TextureInfo->RGBout
aout AR_TextureInfo->aout
uwrap AR_TextureInfo->uwrap
vwrap AR_TextureInfo->vwrap
worldspace AR_TextureInfo->worldspace
chordTexture AR_TextureInfo->chordTextured
rotate AR_TextureInfo->rotate
active AR_TextureInfo->active
mirror AR_TextureInfo->mirror
invert AR_TextureInfo->invert
color_remap AR_TextureInfo->color_remap
smear_map AR_TextureInfo->uv_offset
overlay AR_TextureInfo->overlay
transformation_name AR_TextureInfo->TM

Customizing the ALIAS OpenRender Template File

This section walks through the changing of a very simple shader. The shader calculates only the ambient and diffuse contribution from each light source. For this example, we walk through the file simple_shader.c and extend it to calculate a "glow" contribution as well.

Briefly examine the file simple_shader.c. It uses its own definition for "color." This is not necessary, since this field is also maintained by Alias in the AR_ShadeData structure. The "color" field is defined here for clarity. Although you are free to use the information passed into your shader(s) in the AR_ShadeData structure, it is clearer if you define all the parameters you are going to use in your own data structures (as you have done with "color" in the simple_shader.c example).

Copy the file simple_shader.c to a file called new_shader.c, and read new_shader.c into your favorite editor.

The first thing to change is the data structures. Locate the NODE_TYPE and INFO_TYPE data structures in the file and add "glow," an AR_Rgb, to both data structures. The structures should now look like:

typedef struct NODE_TYPE {
RR_ExpNode *diffuse_node;
RR_ExpNode *color_node;
RR_ExpNode *glow_node;
} NODE_TYPE;

typedef struct INFO_TYPE {
float diffuse;
AR_Rgb color;
AR_Rgb glow;
} INFO_TYPE;

Next, you must customize the name of this shader. Locate the MODULE_NAME define-it should be only a few lines below the data structure definitions that you just changed. Now change the MODULE_NAME to "new_shader" (or whatever you choose to call it). This allows Alias-defined functions in OCR_predef_routines.h to print out meaningful warning and error messages.

You want your new "glow" parameter to have a default. Let's say that the default is a nice red (200, 20, 10). Locate the line that reads:

static const int diffuse_default = 0.8;
and add the following line, to be the default for your new "glow" parameter:

static const AR_Rgb glow_default = (200.0, 20.0, 10.0);
The next thing you want to do is tell the Renderer which keyword to add to SDL, and where to place information from that keyword in the data structures you have just modified. Locate the PARAM_TAB[] array. This is the array that extends the syntax of SDL. You want to have the "glow" parameter use "glow" as its keyword in SDL, so you add the line beginning with "glow" to the following table:

static const OcrCtlParamTabType PARAM_TAB[]={
/*
*SDL param Node Field Info Field Info Type Default
*------- ---------- ---------- --------- ------- */
"ldiffuse", NODE(diffuse_node), INFO(diffuse), SCALAR, (void*)&diffuse_default,
"lcolor", NODE(color_node), INFO(color), TRIPLE, (void*)&color_default,
"glow", NODE(glow_node), INFO(glow), TRIPLE, (void*)&glow_default,
NULL, 0, 0, 0, NULL
};


The new "glow" line must come before the line that starts with NULL. The line that starts with NULL is used to terminate the list, and anything added after the NULL line is ignored by the Alias Renderer. Once you have made the above change to PARAM_TAB[], the Alias Renderer knows that when it sees the keyword "glow" in the SDL file, the Renderer must place whatever "glow" is assigned into the NODE field "glow_node," and that at evaluate time, the NODE field "glow_node" must be evaluated into the INFO field "glow." You have also told the renderer that "glow" must be a TRIPLE (in this case, red, green, and blue) and that if there is no keyword "glow" in the SDL file, the values you placed in "glow_default" are to be used (see the next section, Notes on the PARAM_TAB Array, for more information).

Note: The SDL keyword for your "color" field is defined to be lcolor to avoid conflict with the Alias defined keyword color. See the note at the top of Standard SDL Parameters for more explanation.

The final change to make in order to add our new "glow" parameter to the simple shader is to modify the CALC routine. Locate the line:

/* Calculate Transparency */
in the file. Just before this line, add the following code:

result.r += pUserInfo->glow.r;
result.g += pUserInfo->glow.g;
result.b += pUserInfo->glow.b;
Once you have done this, you have completed the modifications to your "new_shader." You can now write the file, exit your editor and compile "new_shader.c." Once you have compiled the shader, you can try it by adding the following to an SDL file somewhere in the DEFINITION section:

create shader ( model = new_shader, filename = "new_shader.o" );

shader my_shader(
model = new_shader,
lcolor = (150, 150, 150), /* grey */
ldiffuse = 0.8,
glow = (20, 20, 180) /* blue */
);

Modify one of the surfaces in your SDL file so that it uses this new shader you have just added, then render the SDL file.

Notes on the PARAM_TAB Array

The PARAM_TAB[] array is interpreted by the Parse and Evaluate routines. In the following example array, the first row is an example of how an SDL parameter keyword corresponds to a field in the NODE struct called fieldNODE and a field in the INFO structure called fieldINFO.

typedef struct NODE_TYPE {
RR_ExpNode *fieldNODE;
RR_ExpNode *fieldColn;
} NODE_TYPE;

typedef struct INFO_TYPE{
int fieldINFO;
AR_Rgb fieldColi;
}INFO_TYPE;

static const OcrCtlParamTabType PARAM_TAB[]={
/*
*SDL param Node Field Info Field Info Type Default
*------- ---------- ---------- --------- -------
*/
"paramSDL", NODE(fieldNODE), INFO(fieldINFO), SCALAR, NULL,
"mcolour", NODE(fieldColn), INFO(fieldColi), TRIPLE, (void*)&ColDef,
"mcolor", NODE(fieldColn), INFO(fieldColi), DO_NOT_EVAL, NULL,
NULL, 0, 0, 0, NULL
};

Suppose you are adding a new sort of light to the SDL:

create light (model=example, filename="example.o");
.
.
.
light (model=example, paramSDL=1.0);

The line starting with paramSDL in the above PARAM_TAB array associates the NODE field fieldNODE with paramSDL for the purposes of SDL parsing and with the INFO struct field fieldINFO for the purposes of evaluation. In this case, by the time the INIT() routine is called, the field fieldINFO has the value 1.0 in it.

The next two lines of the above PARAM_TAB array assume that there is a color field (fieldColn in the NODE struct and fieldColi in the INFO struct) that you want to be associated with two synonymous SDL parameters ("mcolour" and "mcolor"). Since you only want to evaluate the information in the NODE_TYPE structure once, the second binding of an SDL keyword to a field must have the Info Type set to DO_NOT_EVAL. All INFO fields that should not be evaluated, but can be parsed, should have DO_NOT_EVAL in the type field.

Data Types Available

There are several types of data that the Renderer can parse and evaluate. The following table lists the types of data you can specify in the Info Type field of the PARAM_TAB[] array.
Field Entry Description
SCALAR float, double, integer, boolean
TRIPLE color, point, vector
TEXTURE Checker, sWood, file, sFractal, etc.
FILENAME array of char (possibly with frame number extension)
TRANSFORM_REFERENCE (for use with solid textures)

There are usage examples of all of these Info Types in the example ALIAS OpenRender modules.

Changing Glow to a Texturable Parameter

In this section, you will change the glow parameter you just added to new_shader.c into a texturable parameter. The first thing to do is edit new_shader.c. Locate the INFO_TYPE data structure. Change the definition of glow from AR_Rgb to AR_TextureType.

typedef struct INFO_TYPE{
float diffuse;
AR_Rgb color;
AR_TextureType glow;
}INFO_TYPE;

Note that its type remains RR_ExpNode in the NODE_TYPE structure.

Next, locate the definition of glow_default. All textures are 4 channel textures, so the default for a texture must be an AR_Rgba. Therefore, you must change its definition, and add a scalar to the default value:

static const AR_Rgba glow_default = (200.0, 20.0, 10.0, 0.0);

Next, locate the PARAM_TAB[] array. You must change the Info Type field from TRIPLE to TEXTURE.

"glow", NODE(glow_node), INFO(glow), TEXTURE, (void*)&glow_default,
Textures require initialization in the INIT() routine, so locate the OCR_Init() routine. Currently it is an empty function. Add the following line to initialize the texture:

static AR_Boolean
OCR_Init(
INFO_TYPE *pUserInfo
)
{
OCR_initialize_texture( pUserInfo->glow.map );
return TRUE;
}

Finally, the last change required is in the CALC routine. You must now call the CALC routine for the texture before you add glow to the result. To do this, you need some extra variables defined at the top of the CALC routine:

AR_TextureData tx; /* Texture mapping variables */
AR_Rgba rgba;

Then, you need to set up the AR_TextureData structure so that the texture can evaluate the value at the current location properly. Locate the code you put in to add the glow to the result (it should look like:)

result.r += pUserInfo->glow.r;
result.g += pUserInfo->glow.g;
result.b += pUserInfo->glow.b;

Delete the above code (it will no longer work for textures) and replace it with:

/* Set up AR_TextureData structure. */
tx.TDgeom = pGeometry;
tx.TDray = &ray;
tx.TDnormal = &(pShadeData->Normal);
/* Set up location for result of texture. */
tx.TDcolor = &rgba;

/* Call the texture (this will work even if a literal or the */
/* default value was assigned to this parameter in SDL). */
OCR_INVOKE_MAPPING( tx, pInfo->reflectivity, pShadeData->Sight );

/* Add the textured glow to the result. */
result.r += rgba.r;
result.g += rgba.g;
result.b += rgba.b;
Notice how you added the values in rgba to the result after the texture had been invoked. You could have taken the values out of tx.TDcolor as well, since it also points to rgba.

If you write the file and compile it, you can now place a texture or a triple on the glow parameter in the SDL file. Try running the Renderer on the same file you modified last time (it has a constant, literal value for glow, and the image should look no different from the last time you ran it). Now try placing a texture on the glow parameter. Modify the SDL to read:

shader my_shader(
model = new_shader,
lcolor = (150, 150, 150), /* grey */
ldiffuse = 0.8,
glow = texture(
procedure = Checker,
urepeat = 20,
vrepeat = 20,
rgbout = (0, 150, 255),
contrast = 1.0,
color1 = (255, 255, 255),
color2 = (0, 0, 0)
)
);
Try rendering this modified SDL file. Notice how the object appears to be checkered. Congratulations-you have just added a texturable attribute to your ALIAS OpenRender shader.

Modifying SDL files

The Alias Scene Description Language (SDL) has a new extension to allow you to specify the ALIAS OpenRender shaders, lights and textures. The new keyword is create. The syntax for this keyword is as follows:

create [light|shader|texture] ( model = <model name>, filename = "<filename.o>" );
After the create statement is placed in the SDL file, the ALIAS OpenRender model you have created can be used just like an Alias model. (Look at the simple_shader SDL file in the ALIAS OpenRender sdl directory for an example.)

For example, if you have modified the ALIAS OpenRender Template file to define a shader that you want to call "glossy," and you have compiled the modified ALIAS OpenRender Template file into a file called "glossy.o," then the create command in SDL would look like this:

create shader ( model = glossy, filename = glossy.o );
and subsequent uses of the shader would look like:

shader (model = glossy, ...... );
Of course, the remaining arguments to the shader "glossy" depend on what parameters you have defined in the ALIAS OpenRender Template file. You must create an ALIAS OpenRender code module in the SDL higher up in the file than where it is used (that is, the ALIAS OpenRender code module must be defined before it is used).





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