GXSetChanCtrl

C Specification

#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 the 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 made simultaneously for color channel 0 and alpha channel 0.
GX_COLOR1A1 The same setting is made simultaneously for color channel 1 and alpha channel 1.
enable> If enable = GX_ENABLE, lighting for this color channel is enabled.
amb_src the ambient color source
Accepted values are:
Name Source
GX_SRC_REG uses the ambient color register
GX_SRC_VTX uses the vertex color
mat_src the material color source
Accepted values are:
Name Source
GX_SRC_REG uses the material color register
GX_SRC_VTX uses the vertex color
light_mask Which lights to use in the lighting equation for this channel.
This is the bitwise OR of GX_LIGHT0, GX_LIGHT1,GX_LIGHT2,..., GX_LIGHT7.
diff_fn the diffusion function for lighting
Accepted values are:
Name Type of Diffusion Function
GX_DF_NONE no diffusion function
GX_DF_CLAMP clamp type diffusion function (for normal use)
GX_DF_SIGN clamp type diffusion function (for special effects)
attn_fn the attenuation function for lighting
Accepted values are:
Name Type of Attenuation Function
GX_AF_NONE the light is considered to be a plain (unattenuated) point light
Light object attenuation coefficients will not not work for this setting.
GX_AF_SPOT angular attenuation and distance attenuation applied to each light
GX_AF_SPEC the light is used as a specular light

Return Values

None.

Description

This function sets the lighting controls for a color channel. The color channel can have one or more (up to eight) lights associated with it, set using light_mask. The diff_fn and attn_fn arguments control the lighting equation for all lights associated with this channel. The amb_src and mat_src parameters can be used to select whether input source colors come from register or vertex colors. When enable for the channel is set to GX_FALSE, the material color source (set by mat_src) is passed as the channel's output color. When enable for the channel is set to GX_TRUE, the output color will depend on the other controls's settings (i.e., the lighting equation). GXInit sets enable for all channels to GX_FALSE. This function, however, 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, GX_COLOR0A0. The same is true for GX_COLOR1 and GX_ALPHA1—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 only either GX_VA_CLR0 or 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 GXSetChanAmbColor is used as the ambient color. When mat_src is GX_SRC_REG, the color set by GXSetChanMatColor 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 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 by the light, set here by GXInitLightSpot. The distance attenuation function is set using GXInitLightDistAttn.

// 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 the GX_COLOR0 channel for specular lighting. The function GXInitSpecularDir is used to set 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 GXInitLightShininess (to set the attenuation coefficient) to control how shiny the lighted material appears. The attn_fn parameter is set to GX_AF_SPEC, enabling specular calculations.

// 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 lighting, it is possible to obtain nearly parallel lighting by putting a light very far away from every object 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 arguments for the light (associated with the channel) are normally set with either of these 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 GXInitSpecularDir.

Example:  Per-Vertex Lighting using Pre-Lighting

This example will add a pre-lit color (calculated by the CG tool) as a per-vertex GX_VA_CLR0 (see GXSetVtxDesc) to the result for 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. The sum of amb_scale and diff_scale should equal 1.0; when the object is in the brightest light, the vertex color is equal to the pre-lit color.

The material color is set to be the vertex color (pre-lit color). The ambient color register is set to be equal 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 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 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