Gamasutra is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.

Shader Integration: Merging Shading Technologies on the Nintendo Gamecube
View All     RSS
November 29, 2020
View All     Post     RSS
November 29, 2020
Press Releases
November 29, 2020
Games Press
View All     RSS

If you enjoy reading this site, you might also want to check out these UBM Tech sites:

# Shader Integration: Merging Shading Technologies on the Nintendo Gamecube

October 2, 2002 Page 5 of 5

## Code Listing 1: Generating texture coordinates for specular highlights.

void shadingMath_ComputeSpecularPostMtx(mt32 *pOut, v32 *ldir_viewspace, f32 size)

{
f32 scale, dotp, r, tweak;
v32 vaxis, vhalf;
q32 q;

// convert input...
assert(size >= 0.0f && size <= 1.0f);

size = mathClampMinMax(size, 0.0f, 1.0f);
tweak = (PHONG_MAX - PHONG_MIN)*size + PHONG_MIN;

// check for singular point...
dotp = -ldir_viewspace->z;

if (dotp <= -1.0f)
{
mathMatSetScale(pOut, 0.0f);
return;
}

// The obtained half-angle vector directs an opposite side...
if (dotp >= 1.0f)
{
// Looking exactly with the light...
mathMatInit(pOut);
}
else
{
vhalf.x = -ldir_viewspace->x;
vhalf.y = -ldir_viewspace->y;
vhalf.z = -ldir_viewspace->z + 1.0f;

mathVecNormalize(&vhalf);

r = facos(-vhalf.z);
vaxis.x = -vhalf.y;
vaxis.y = vhalf.x;
vaxis.z = 0.0f;

mathQuatMakeRad(&q, &vaxis, r);
mathQuatToMatrix(pOut, &q);
};

scale = 2.0f * tweak + 1.5f;
mathMatAddScale(pOut, scale);

pOut->m[RD_U][RD_T] =
pOut->m[RD_V][RD_T] = 0.5f;

// setup w to be always one...
pOut->m[RD_W][RD_X] =
pOut->m[RD_W][RD_Y] =
pOut->m[RD_W][RD_Z] = 0.0f;
pOut->m[RD_W][RD_T] = 1.0f;
}

## Code Listing 2: Generating texture coordinates for environment lookups.

void shadingMath_ComputeSphereLookupPostMtx(mt32 *pOut, f32 nrm_scale, bool bBinormal)

{
mathMatSetScale(pOut, nrm_scale * 0.5f);
pOut->m[RD_V][RD_Y] *= -1.0f;
pOut->m[RD_U][RD_T] =
pOut->m[RD_V][RD_T] = bBinormal ? 0.0f : 0.5f;
// setup w to be always 1.0f -> i.e. 'disable' w divide...
pOut->m[RD_W][RD_Z] = 0.0f;
pOut->m[RD_W][RD_T] = 1.0f;
}

## Code Listing 3: Correcting texture coordinates for bumped specular lookups.

// compute fancy mtx...
shadingMath_ComputeSpecularPostMtx(&m, shadingLightGroup_GetPhongDirEye(), cosinePower);
// get correction factor...
f = (f32)gpSG->GetEnvMapSize() / (f32)GXGetTexObjWidth(pSpecMap);
// need to 'undo' lightmap lookup...
m.m[RD_X][RD_RIGHT] += -0.5f * f;
m.m[RD_Y][RD_UP] += 0.5f * f;
m.m[RD_X][RD_T] += -0.5f * f;
m.m[RD_Y][RD_T] += -0.5f * f;
GXLoadTexMtxImm(m.m, GX_PT_SPECULAR_FROM_NORM, GX_MTX3x4);

## Code Listing 4: Computing intensity values for layered fog lookup textures.

static u8 _fogFunction(tLayeredFog *pFog, f32 x, f32 y)

{
f32 v;
assert(pFog);
assert(x >= 0.0f && x < pFog->rampWidth);
assert(y >= 0.0f && y < pFog->rampHeight);
assert(pFog->inFogFactor >= 0.0f && pFog->inFogFactor <= 1.0f);
x /= pFog->rampWidth - 1.0f;
y /= pFog->rampHeight - 1.0f;
// height...
v = x * x;
v = v * (1.0f - pFog->inFogFactor) + pFog->inFogFactor;
// distance...
v *= y * y;
v *= 255.0f;
return ((u8)mathClampMax(v, pFog->currentSettings.maxIntensity));
}

______________________________________________________

Page 5 of 5

### Related Jobs

Airship Syndicate — Austin, Texas, United States
[11.27.20]

Junior to Mid Programmer
New Moon Production — Hamburg, Germany
[11.27.20]

Technical Artist (all genders)
Wooga GmbH — Berlin, Germany
[11.26.20]

(Senior) QA Automation Engineer
Hit Factor Inc — San Diego, California, United States
[11.25.20]

Game Studio Engineering Lead - Remote