#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 );
chan |
the color channel Accepted values are:
|
||||||||||||||
enable> |
If enable = GX_ENABLE, lighting for this color channel is enabled. |
||||||||||||||
amb_src |
the ambient color source Accepted values are:
|
||||||||||||||
mat_src |
the material color source Accepted values are:
|
||||||||||||||
light_mask |
Which lights to use in the lighting equation for this channel. |
||||||||||||||
diff_fn |
the diffusion function for lighting Accepted values are:
|
||||||||||||||
attn_fn |
the attenuation function for lighting Accepted values are:
|
None.
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.
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 );
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 );
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 );
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.
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 );
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 );
GXSetChanMatColor
GXSetChanAmbColor
GXSetNumChans
2006/03/01 Initial version.
CONFIDENTIAL