Files
2026-08-09 04:23:10 -07:00

77 lines
2.6 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
// clamp before sampling, because the shadow depth map may have
// only been updated in a restricted viewport
light.xy = min( light.xy, 0.99 );
light.xy = max( light.xy, 0.01 );
// make sure that the cleared z = 1.0 in the shadow buffer
// will always be farther away than any world surface
light.z = min( light.z, 0.9999999 );
float shadow = shadow2Ddepth( $dimShadowDepthMap, light.xyz );
// 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 );
}
}