private void CheckShadowCasters( IList casters,
PlaneBoundedVolume nearClipVol,
Light light,
bool extrudeInSoftware,
bool finiteExtrude,
bool zfailAlgo,
Camera camera,
float extrudeDistance,
bool stencil2sided,
LightList tmpLightList )
{
int flags;
for ( int i = 0; i < casters.Count; i++ )
{
ShadowCaster caster = (ShadowCaster)casters[ i ];
if ( nearClipVol.Intersects( caster.GetWorldBoundingBox() ) )
{
// We have a zfail case, we must use zfail for all objects
zfailAlgo = true;
break;
}
}
for ( int ci = 0; ci < casters.Count; ci++ )
{
ShadowCaster caster = (ShadowCaster)casters[ ci ];
flags = 0;
if ( light.Type != LightType.Directional )
{
extrudeDistance = caster.GetPointExtrusionDistance( light );
}
if ( !extrudeInSoftware && !finiteExtrude )
{
// hardware extrusion, to infinity (and beyond!)
flags |= (int)ShadowRenderableFlags.ExtrudeToInfinity;
}
if ( zfailAlgo )
{
// We need to include the light and / or dark cap
// But only if they will be visible
if ( camera.IsObjectVisible( caster.GetLightCapBounds() ) )
{
flags |= (int)ShadowRenderableFlags.IncludeLightCap;
}
}
// Dark cap (no dark cap for directional lights using
// hardware extrusion to infinity)
if ( !( ( flags & (int)ShadowRenderableFlags.ExtrudeToInfinity ) != 0 &&
light.Type == LightType.Directional ) &&
camera.IsObjectVisible( caster.GetDarkCapBounds( light, extrudeDistance ) ) )
{
flags |= (int)ShadowRenderableFlags.IncludeDarkCap;
}
// get shadow renderables
IEnumerator renderables = caster.GetShadowVolumeRenderableEnumerator(
this.shadowTechnique, light, this.shadowIndexBuffer, extrudeInSoftware, extrudeDistance, flags );
// If using one-sided stencil, render the first pass of all shadow
// renderables before all the second passes
for ( int i = 0; i < ( stencil2sided ? 1 : 2 ); i++ )
{
if ( i == 1 )
{
renderables = caster.GetLastShadowVolumeRenderableEnumerator();
}
while ( renderables.MoveNext() )
{
ShadowRenderable sr = (ShadowRenderable)renderables.Current;
// omit hidden renderables
if ( sr.IsVisible )
{
// render volume, including dark and (maybe) light caps
this.RenderSingleShadowVolumeToStencil( sr,
zfailAlgo,
stencil2sided,
tmpLightList,
( i > 0 ) );
// optionally render separate light cap
if ( sr.IsLightCapSeperate
&& ( ( flags & (int)ShadowRenderableFlags.IncludeLightCap ) ) > 0 )
{
// must always fail depth check
this.targetRenderSystem.DepthBufferFunction = CompareFunction.AlwaysFail;
Debug.Assert( sr.LightCapRenderable != null,
"Shadow renderable is missing a separate light cap renderable!" );
this.RenderSingleShadowVolumeToStencil( sr.LightCapRenderable,
zfailAlgo,
stencil2sided,
tmpLightList,
( i > 0 ) );
// reset depth function
this.targetRenderSystem.DepthBufferFunction = CompareFunction.Less;
}
}
}
}
}
}