77 lines
2.6 KiB
Plaintext
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 );
|
|
}
|
|
} |