Files
tech5/bin/base/generated/decls/renderprog/dimshadowdrawhighquality.decl
2026-08-09 04:23:10 -07:00

112 lines
4.7 KiB
Plaintext

{
parms {
}
state {
blend GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA
depthFunc GL_GREATER // we are also relying on the stencil buffer already being set
depthMask
alphaMask
stencilFunc EQUAL 1 255 // only draw on stencil = STENCIL_SHADOW
stencilop KEEP KEEP KEEP
}
hlsl_vp {
float4 pos = vertex.position;
float3 normal = vertex.normal.xyz * 2.0 - 1.0;
if ( dot3( normal, $dimShadowExtrude ) > 0.0 ) {
float dist = dot4( pos, $dimShadowClipPlane );
float closing = dot3( $dimShadowExtrude.xyz, $dimShadowClipPlane.xyz );
pos.xyz -= $dimShadowExtrude.xyz * ( dist / closing );
}
result.position.x = dot4( pos, $mvpMatrixX );
result.position.y = dot4( pos, $mvpMatrixY );
result.position.z = dot4( pos, $mvpMatrixZ );
result.position.w = dot4( pos, $mvpMatrixW );
}
hlsl_fp {
// this is normalized window space, not strict openGL window space
// that uses integer viewport values.
float3 window;
window.xy = screenPosToTexcoord( fragment.position.xy, $renderPositionToViewTexture );
// fetch the window space depth value
window.z = tex2Ddepth( $viewDepthMap, window.xy );
float4 wclip = float4( window.xyz, 1.0f );
// now transform to the light clip space
float4 light;
light.x = dot4( wclip, $windowPosToDimShadowBlurS );
light.y = dot4( wclip, $windowPosToDimShadowBlurT );
light.z = dot4( wclip, $windowPosToDimShadowBlurR );
light.w = dot4( wclip, $windowPosToDimShadowBlurQ );
// divide by w to get to light device coordinates
light.xyz /= light.w;
// move the -1.0 - 1.0 light device st to the 0.0 - 1.0 texture range
#if defined( XBOX )
light.xy = ( light.xy * 0.5 ) + 0.5; // don't adjust z, it is already 0 - 1
#else
light = ( light * 0.5 ) + 0.5;
#endif
#if defined( XBOX ) || defined( PS3 )
light.y = 1.0 - light.y; // image y origin adjust
#endif
// Make sure that the cleared z = 1.0 in the shadow buffer
// will always be farther away than any world surface. This is necessary
// because the extruded box can contain areas that are outside the actual
// projection.
light.z = min( light.z, 0.9999999 );
float2 tc = fragment.position.xy * float2( 1.0/128, 1.0/128 ) + $viewRandom.xy;
float2 dither = tex2D( $dither256map, tc ).xw;
const float step = 1.0 / 768.0;
float3 center;
// this biases by +1.5 on average, so we can test -3, -2, -1, 0 offsets
center.xy = light.xy + step + dither * step;
center.z = light.z;
#if defined( XBOX )
float shadow;
shadow = shadow2Ddepth( $dimShadowDepthMap, center + float3( -2*step, -2*step, 0 ) );
shadow += shadow2Ddepth( $dimShadowDepthMap, center + float3( -1*step, -2*step, 0 ) );
shadow += shadow2Ddepth( $dimShadowDepthMap, center + float3( 0*step, -2*step, 0 ) );
shadow += shadow2Ddepth( $dimShadowDepthMap, center + float3( -3*step, -2*step, 0 ) );
shadow += shadow2Ddepth( $dimShadowDepthMap, center + float3( -2*step, -1*step, 0 ) );
shadow += shadow2Ddepth( $dimShadowDepthMap, center + float3( -1*step, -1*step, 0 ) );
shadow += shadow2Ddepth( $dimShadowDepthMap, center + float3( 0*step, -1*step, 0 ) );
shadow += shadow2Ddepth( $dimShadowDepthMap, center + float3( -3*step, -1*step, 0 ) );
shadow += shadow2Ddepth( $dimShadowDepthMap, center + float3( -2*step, 0*step, 0 ) );
shadow += shadow2Ddepth( $dimShadowDepthMap, center + float3( -1*step, 0*step, 0 ) );
shadow += shadow2Ddepth( $dimShadowDepthMap, center + float3( 0*step, 0*step, 0 ) );
shadow += shadow2Ddepth( $dimShadowDepthMap, center + float3( -3*step, 0*step, 0 ) );
shadow += shadow2Ddepth( $dimShadowDepthMap, center + float3( -2*step, -3*step, 0 ) );
shadow += shadow2Ddepth( $dimShadowDepthMap, center + float3( -1*step, -3*step, 0 ) );
shadow += shadow2Ddepth( $dimShadowDepthMap, center + float3( 0*step, -3*step, 0 ) );
shadow += shadow2Ddepth( $dimShadowDepthMap, center + float3( -3*step, -3*step, 0 ) );
shadow *= 0.0625;
#else
// the PC and PS3 takes advantage of hardware PCF
float shadow;
shadow = shadow2Ddepth( $dimShadowDepthMap, center + float3( -2*step, -2*step, 0 ) );
shadow += shadow2Ddepth( $dimShadowDepthMap, center + float3( -1*step, -2*step, 0 ) );
shadow += shadow2Ddepth( $dimShadowDepthMap, center + float3( -2*step, -1*step, 0 ) );
shadow += shadow2Ddepth( $dimShadowDepthMap, center + float3( -1*step, -1*step, 0 ) );
shadow *= 0.25;
#endif
// get the amount of shadow accepted by the surface from the alpha channel
float acceptShadow = tex2D( $viewColorMap, window.xy ).w;
// only use a fraction of the dimshadow value, since we can't separate the
// contribution along the shadow from the remainder
shadow = ( 1.0 - shadow ) * acceptShadow * $dimshadowfade.x;
result.color = float4( 0.0, 0.0, 0.0, shadow );
}
}