GXSetChanCtrl

Syntax

#include <revolution/gx.h>

void GXSetChanCtrl(
    GXChannelID   chan,
    GXBool         enable,
    GXColorSrc    amb_src,
    GXColorSrc    mat_src,
    GXLightID     light_mask,
    GXDiffuseFn   diff_fn,
    GXAttnFn      attn_fn );

Arguments

chan Color channel. Accepted values are:
Name Target channel
GX_COLOR0 Color channel 0.
GX_ALPHA0 Alpha channel 0.
GX_COLOR1 Color channel 1.
GX_ALPHA1 Alpha channel 1.
GX_COLOR0A0 The same setting is simultaneously made for color channel 0 and alpha channel 0.
GX_COLOR1A1 The same setting is simultaneously made for color channel 1 and alpha channel 1.
enable If enable = GX_ENABLE, lighting for this color channel is enabled.
amb_src Ambient color source. Accepted values are:
Name Source
GX_SRC_REG Use the ambient color register.
GX_SRC_VTX Use the vertex color.
mat_src Material color source. Accepted values are:
Name Source
GX_SRC_REG Use the material color register.
GX_SRC_VTX Use the vertex color.
light_mask The light used for this channel used by the light formula. This is the bitwise OR of GX_LIGHT0, GX_LIGHT1, GX_LIGHT2, ... , GX_LIGHT7.
diff_fn Diffusion function for lighting. Accepted values are:
Name Type of diffuse function
GX_DF_NONE No diffuse function.
GX_DF_CLAMP Clamp type diffuse function (for conventional use).
GX_DF_SIGN Sign type diffuse function (for special use).
attn_fn Attenuation function for lighting. Accepted values are:
Name Type of attenuation function
GX_AF_NONE Consider the light to be a plain (unattenuated) point of light. Attenuation coefficients for each light object do not work under this setting.
GX_AF_SPOT Angular attenuation and distance attenuation are applied to each light.
GX_AF_SPEC The light is taken as a specular light.

Return Values

None.

Description

This function sets the lighting controls for a color channel. Color channels can have one or more lights associated with them, set using light_mask. The diff_fn and attn_fn parameters control the lighting equation for all lights associated with this channel. The amb_src and mat_src can be used to select whether the input source colors come from register colors or vertex colors. When enable is set to GX_FALSE for the channel, the material color source (set by mat_src) is passed as the channel's output color. When the channel enable is GX_TRUE, the output color depends on the settings of the other controls (i.e., the lighting equation). GXInit sets the enable for all channels to GX_FALSE. The GXSetChanCtrl function only configures the lighting channel. To output the results of channel calculations, use the GXSetNumChans function.

Even though channels GX_COLOR0 and GX_ALPHA0 are controlled separately for lighting, they are rasterized together as one RGBA color, effectively GX_COLOR0A0. The same is true for GX_COLOR1 and GX_ALPHA1 — effectively, they are rasterized as GX_COLOR1A1. Since there is only one rasterizer for color in the graphics hardware, you must choose which color to rasterize for each stage in the texture environment (TEV) unit. This is accomplished using the GXSetTevOrder function.

In order to use a vertex color in channel GX_COLOR1A1, two colors per vertex are needed. Therefore both GX_VA_CLR0 and GX_VA_CLR1 must be enabled in the current vertex descriptor. If either only GX_VA_CLR0 or only GX_VA_CLR1 is enabled in the current vertex descriptor, the vertex color is directed to the GX_VA_COLOR0A0 channel.

When amb_src is set to GX_SRC_REG, the color set by the GXSetChanAmbColor function is used as the ambient color. When mat_src is GX_SRC_REG, the color set by the GXSetChanMatColor function is used as the material color.

Example: Local Diffuse Spot Lighting

This example demonstrates how to configure the GX_COLOR0 channel to light the vertex color with a local diffuse spot light. The functions GXInitLightPos and GXInitLightDir are used to initialize the light position and direction. The light direction and position are assumed to have been transformed into the view space prior to setting the light object. In order to enable diffuse lighting, diff_fn is set to GX_DF_CLAMP. Since this is a spot light, attn_fn is set to GX_AF_SPOT. The type of spot light angle attenuation function is determined here by the light set by the GXInitLightSpot function. The distance attenuation function is set using the GXInitLightDistAttn function.

// Assumes vertex will supply color0.

// init light position, direction, atten functions
GXInitLightPosv( &myLightObj, &pos );
GXInitLightDirv( &myLightObj, &dir );
GXInitLightSpot( &myLightObj, 30.0f, GX_SP_COS2 );
GXInitLightDistAttn( &myLightObj, 100.0f, 0.5f, GX_DA_GENTLE );

GXLoadLightObjImm( &myLightObj, GX_LIGHT0 );
GXSetChanAmbColor( GX_COLOR0, black );
GXSetChanCtrl(
GX_COLOR0,
GX_TRUE, // enable lighting
GX_SRC_REG, // ambient = 0
GX_SRC_VTX, // material color
GX_LIGHT0,
GX_DF_CLAMP, // normal diffuse light
GX_AF_SPOT );  // spot light attenuation

// Set number of channels to light
GXSetNumChans( 1 );

Example: Specular Lighting

This example demonstrates how to set up the GX_COLOR0 channel for specular lighting. The function GXInitSpecularDir is used to set the light direction. The direction must be transformed to the view space prior to initializing the light object. Specular lights are considered to be infinitely far away, so a position argument is not necessary. The angle attenuation and distance attenuation functions are used to approximate an exponential attenuation function for specular lights. Call the GXInitLightShininess function to control how shiny the lighted material appears (set the attenuation parameters). The attn_fn argument is set to GX_AF_SPEC, enabling the specular computation.

// Assumes vertex will supply color0.

// init light direction, attn functions
GXInitSpecularDirv( &myLightObj, &dir );
GXInitLightShininess( &myLightObj, 5.0f );
GXLoadLightObjImm( &myLightObj, GX_LIGHT0 );
GXSetChanAmbColor( GX_COLOR0, black );
GXSetChanCtrl(
GX_COLOR0,
GX_TRUE, // enable lighting
GX_SRC_REG, // ambient = 0
GX_SRC_VTX, // material color
GX_LIGHT0,
GX_DF_NONE, // no diffuse light
GX_AF_SPEC );  // specular light

// Set number of channels to light
GXSetNumChans( 1 );

Example: Parallel Diffuse Lighting

Although the hardware doesn't support parallel diffuse lights, it is possible to obtain an "almost parallel" light by putting a light very far away from all objects to be lit. If the light's position is sufficiently distant from the object, all rays can be considered parallel.

// prepares large number
#define LARGE_NUMBER  1.0E+18F

// light direction on view space
// the 3D vector (dx, dy, dz) is supposed to be normalized.
f32  dx, dy, dz;

// init light parameters
GXInitLightPos(
&myLightObj,
- dx * LARGE_NUMBER,
- dy * LARGE_NUMBER,
- dz * LARGE_NUMBER );
GXInitLightColor( &myLightObj, white );
GXLoadLightObjImm( &myLightObj, GX_LIGHT0 );
GXSetChanAmbColor( GX_COLOR0, ambColor );
GXSetChanMatColor( GX_COLOR0, matColor );
GXSetChanCtrl(
GX_COLOR0,
GX_TRUE,       // enable lighting
GX_SRC_REG,    // ambient = black
GX_SRC_REG,    // material color
GX_LIGHT0,
GX_DF_CLAMP,   // normal diffuse light
GX_AF_NONE );  // no attenuation

// Set number of channels to light
GXSetNumChans( 1 );

Using Both Diffuse and Specular Lighting

The channel controls determine which calculations, either local-diffuse or specular, are performed in a channel. The parameters for the light associated with the channel are normally configured with one of these sets of calculations in mind. For example, a position and direction is set for local diffuse lights (used with a diffuse channel) and only the direction is set for a specular light (used with a specular channel). However, if you only need a directional diffuse light (when the light's position is so far away that its rays are considered parallel), then the same light's arguments can be used for both specular and diffuse channels. In this case, initialize the light's arguments using the GXInitSpecularDir function.

Example:  Per-Vertex Lighting using Pre-Lighting

This example will add a pre-lit color (already computed by the CG tool) supplied as the per-vertex GX_VA_CLR0 (see the GXSetVtxDesc function) to the result of a diffuse local light. In this example we want to implement the equation:

lit_clr = pre_lit_clr * (amb_scale + diff_scale * other_atten * lit_color)

The ambient scale defines the minimum amount of pre-lit color when no lights are shining on an object. Because the sum of amb_scale and diff_scale must be equal to 1.0, when an object is in the brightest light, its vertex color is equivalent to pre-lit color.

The material color is set to be the vertex color (pre-lit color). The ambient color register is set to be equivalent to amb_scale. The light color is scaled by diff_scale.

//
// Assumes vertex will supply color0 = pre-lit color.
//
GXInitLightColor(
myLightObj,
ScaleColor(myLitClr, 0.75)); // diffuse scale
//
// init light position, direction, atten functions
// not shown
GXLoadLightObjImm(
myLightObj,
GX_LIGHT0);
GXSetChanAmbColor(
GX_COLOR0,
ScaleColor(white, 0.25)); // ambient scale
GXSetChanCtrl(
GX_COLOR0,
GX_TRUE, // enable lighting
GX_SRC_REG, // ambient scale
GX_SRC_VTX, // material color = pre-lit color(vtx)
GX_LIGHT0,
GX_DF_CLAMP, // normal diffuse light
GX_AF_SPOT );  // spot light attenuation
//
// Set the material color register
GXSetChanMatColor( GX_COLOR0, (GXColor){0xff,0x00,0x80,0xff} );
GXSetNumChans( 1 );

Example: Four Attenuations for Projected Lighting

This example shows how to compute local-light attenuation values for four projected texture lights. No colors are passed to the vertices. The material color comes from the channel material register and is set to apparently pass the attenuation (multiply by 1.0). There is no contribution from the ambient color. Each channel can be used to attenuate a projected texture in the texture environment (TEV) unit.

// Assumes that 4 light objects have been initialized and loaded
//
GXSetChanCtrl(
GX_COLOR0,
GX_TRUE,
GX_SRC_REG,
GX_SRC_REG,
GX_LIGHT0,
GX_DF_CLAMP,
GX_AF_SPOT );
GXSetChanCtrl(
GX_ALPHA0,
GX_TRUE,
GX_SRC_REG,
GX_SRC_REG,
GX_LIGHT1,
GX_DF_CLAMP,
GX_AF_SPOT );
GXSetChanCtrl(
GX_COLOR1,
GX_TRUE,
GX_SRC_REG,
GX_SRC_REG,
GX_LIGHT2,
GX_DF_CLAMP,
GX_AF_SPOT );
GXSetChanCtrl(
GX_ALPHA1,
GX_TRUE,
GX_SRC_REG,
GX_SRC_REG,
GX_LIGHT3,
GX_DF_CLAMP,
GX_AF_SPOT );
GXSetChanMatColor( GX_COLOR0A0, WhiteOpaque );
GXSetChanMatColor( GX_COLOR1A1, WhiteOpaque );
GXSetChanAmbColor( GX_COLOR0A0, BlackXlu );
GXSetChanAmbColor( GX_COLOR1A1, BlackXlu );
GXSetNumChans( 2 );

See Also

GXSetChanMatColor
GXSetChanAmbColor
GXSetNumChans

Revision History

2006/03/01 Initial version.


CONFIDENTIAL