Iterating Over Lights in a Software Shader
Contrary to the GPU version, a software shader contained in the RED::MTL_LIT
pass have to loop through the lights in order to cumulate their effect.
Here is a simple code to iterate over the lights and perform sampling when needed:
// let:
// - rayctx be the RED::ISoftRayContext.
// - shaderctx be the RED::ISoftShaderContext.
// - renderctx be the RED::ISoftRenderingContext.
double hit[4], normal[4];
double latt[4];
double ldir[4], lcolor[4], lshadows[4];
bool moresamples;
// Get the ray hit and normal.
rayctx.GetWCSHit( hit );
rayctx.GetWCSNormal( normal, shaderctx.GetRenderCode(), RED_VSH_NORMAL );
// Prepare lights before shading.
// This call is mandatory before accessing the lights.
RC_TEST( rayctx.PrepareLights( hit, normal, false, renderctx ) );
// Iterate over the scene lights.
for( unsigned int i = 0; i < renderctx.GetLightsCount(); ++i )
{
const RED::ISoftLight& light = renderctx.GetLight( i );
// Perform culling.
if( !light.GetAttenuation( latt, rayctx.GetThreadID() ) )
continue;
// Sampled light.
if( light.NeedSampling() )
{
moresamples = true;
while( true )
{
RC_TEST( light.GetNextWCSSample( moresamples,
ldir, lcolor, lshadows,
hit, normal,
rayctx, renderctx ) );
if( !moresamples )
break;
// Do something with the light sample...
}
}
// Not sampled light.
else
{
// Do something with the light...
}
}