#define BiasSlope 2.0 #define LightSize 2.0 #define Bias 0.05 #define KernelSize 4.0 #define LightFov 3.14 * 0.5 #define ShadowIntensity 3.0 #define SHADOWMAP_SIZE 1024.0f #define shadowColor float4(0.2,0.2,0.2,1) uniform sampler2D ShadowMap: register(s0); struct LightCPos_OUT { float4 VPos : POSITION; float4 LightVPos : TEXCOORD0; float4 LightCPos : TEXCOORD1; }; float4 ShadowAccum_PS( LightCPos_OUT IN) : COLOR { IN.LightCPos.z *= -1; //return float4(IN.LightCPos.xyz,1); float R = max( LightSize, 0.1h ); //BiasSlope = max( BiasSlope, 0.1h ); float n = R; float mapsize = 2 * n * tan( LightFov / 2.0f ); // size of shadow map in world space float Deltal = mapsize / SHADOWMAP_SIZE; // size of a lexel edge in world space float3 r = IN.LightCPos.xyz; // shaded point in light's camera space float RR = R * (r.z - n) / r.z; // directional set in which the light is seen from the shaded point float step = RR / KernelSize; float RR2 = RR * RR; float2 q = r.xy * n / r.z; // projection of r onto the shadow plane float2 quv = q / mapsize; quv = float2( ( 0.5 + quv.x ), ( 0.5 - quv.y ) ); // r in texture coordinates //return (r.z - tex2D( ShadowMap, quv).r); float shadow = 0; for ( int i = 0; i < KernelSize; i++ ) { for ( int j = 0; j < KernelSize; j++ ) { float2 uvoffset = float2( i - KernelSize / 2.0f, j - KernelSize / 2.0f ) * step / SHADOWMAP_SIZE; float2 l = q + float2( uvoffset.x, -uvoffset.y ) * mapsize; float cz = tex2D( ShadowMap, quv + uvoffset ).x; float size = (r.z - n)/(r.z - cz) * cz / n; float2 lc = (n - cz)/(r.z - cz) * r.xy + size * l.xy; if( cz < r.z - Bias && dot(lc - q, lc - q) < RR2 + BiasSlope ) shadow += size * size; /* if( cz < r.z - Bias) shadow=1;*/ } } //return step; shadow *= Deltal * Deltal * step * step / RR2 * ShadowIntensity * ShadowIntensity; return shadowColor + (1 - shadowColor) * (1 - shadow); }