1 | // Soft shadow with shadow accumulation |
---|
2 | |
---|
3 | |
---|
4 | // SHADOWMAP generation |
---|
5 | |
---|
6 | //----------------------------------------------------------------------------- |
---|
7 | // Vertex Shader: RenderShadowMap_07_VS |
---|
8 | // Desc: Process vertex for the shadow map |
---|
9 | //----------------------------------------------------------------------------- |
---|
10 | void RenderShadowMap_07_VS( |
---|
11 | float4 Position : POSITION, |
---|
12 | out float4 ldPosition : POSITION, |
---|
13 | out float zcam : TEXCOORD0 ) |
---|
14 | { |
---|
15 | ldPosition = mul( Position, WorldLightProj ); // Compute the projected coordinates |
---|
16 | zcam = ldPosition.w; // Store light's camera z |
---|
17 | } |
---|
18 | |
---|
19 | //----------------------------------------------------------------------------- |
---|
20 | // Pixel Shader: RenderShadowMap_07_PS |
---|
21 | // Desc: Process pixel for the shadow map |
---|
22 | //----------------------------------------------------------------------------- |
---|
23 | float4 RenderShadowMap_07_PS( float zcam : TEXCOORD0 ):COLOR |
---|
24 | { |
---|
25 | return float4(zcam,0,0,0); |
---|
26 | } |
---|
27 | |
---|
28 | |
---|
29 | // SCENE RENDERING |
---|
30 | |
---|
31 | //----------------------------------------------------------------------------- |
---|
32 | // Vertex Shader: RenderSceneWithTechnique_07_VS |
---|
33 | // Desc: Process vertex for scene |
---|
34 | //----------------------------------------------------------------------------- |
---|
35 | VS_OUTPUT RenderSceneWithTechnique_07_VS( VS_INPUT IN ) |
---|
36 | { |
---|
37 | VS_OUTPUT OUT = (VS_OUTPUT)0; |
---|
38 | OUT.Color = IN.Color; |
---|
39 | OUT.Tex = IN.Tex; |
---|
40 | |
---|
41 | // transform model-space vertex position to light's camera space: |
---|
42 | OUT.ldPosition = mul(IN.Position, WorldLightProj); |
---|
43 | OUT.lcPosition = mul(IN.Position, WorldLight); |
---|
44 | |
---|
45 | // transform model-space vertex position to normalized screen space: |
---|
46 | OUT.hPosition = mul(IN.Position, WorldViewProj); |
---|
47 | return OUT; |
---|
48 | } |
---|
49 | |
---|
50 | |
---|
51 | //----------------------------------------------------------------------------- |
---|
52 | // Pixel Shader: RenderSceneWithTechnique_07_PS |
---|
53 | // Desc: shadow accumulation |
---|
54 | //----------------------------------------------------------------------------- |
---|
55 | float4 RenderSceneWithTechnique_07_PS( VS_OUTPUT IN) : COLOR |
---|
56 | { |
---|
57 | half R = max( g_fLightSize, 0.1h ); |
---|
58 | g_fBiasSlope = max( g_fBiasSlope, 0.1h ); |
---|
59 | half m = R; |
---|
60 | half mapsize = 2 * m * tan( g_fFov / 2.0h ); // size of half shadow map in world space |
---|
61 | half Deltal = mapsize / SHADOWMAP_SIZE; // size of a lexel edge in world space |
---|
62 | half step = R / g_iKernelSize; |
---|
63 | |
---|
64 | half3 r = IN.lcPosition; // shaded point in light's camera space |
---|
65 | half RR = R * (r.z-m)/r.z; // directional set in which the light is seen from the shaded point |
---|
66 | half RR2 = RR * RR; |
---|
67 | half2 q = r.xy / r.z * m; // projection of r onto the shadow plane |
---|
68 | half2 quv = q / mapsize; |
---|
69 | quv = half2( ( 0.5 + quv.x ), ( 0.5 - quv.y ) ); // r in texture coordinates |
---|
70 | half shadow = 0; |
---|
71 | for ( int i = 0; i < g_iKernelSize; i++ ) |
---|
72 | { |
---|
73 | for ( int j = 0; j < g_iKernelSize; j++ ) |
---|
74 | { |
---|
75 | half2 uvoffset = half2( i - g_iKernelSize / 2.0f, j - g_iKernelSize / 2.0f ) / SHADOWMAP_SIZE * step; |
---|
76 | half2 l = q + half2( uvoffset.x, -uvoffset.y ) * mapsize; |
---|
77 | half cz = tex2D( g_ShadowMapColorSampler, quv + uvoffset ).x; |
---|
78 | half size = (r.z - m)/(r.z - cz) * cz / m; |
---|
79 | |
---|
80 | half2 lc = (m - cz)/(r.z - cz) * r.xy + size * l.xy; |
---|
81 | if( cz < r.z - g_fShadowBias * 10.0f && dot(lc - q, lc - q) < RR2 + g_fBiasSlope ) |
---|
82 | { |
---|
83 | shadow += size * size; |
---|
84 | } |
---|
85 | } |
---|
86 | } |
---|
87 | shadow *= Deltal * Deltal * step * step / RR2; |
---|
88 | return tex2D( g_samScene, IN.Tex ) * ( 1 - shadow * g_fIntensity * g_fIntensity ) * g_vMaterial; |
---|
89 | } |
---|
90 | |
---|
91 | |
---|
92 | // TECHNIQUE |
---|
93 | |
---|
94 | //----------------------------------------------------------------------------- |
---|
95 | // Techniques: RenderShadowMap |
---|
96 | // Desc: Render the shadow map |
---|
97 | //----------------------------------------------------------------------------- |
---|
98 | |
---|
99 | technique RenderShadowMap_7 |
---|
100 | { |
---|
101 | pass p0 |
---|
102 | { |
---|
103 | VertexShader = compile vs_2_0 RenderShadowMap_07_VS(); |
---|
104 | PixelShader = compile ps_2_0 RenderShadowMap_07_PS(); |
---|
105 | } |
---|
106 | } |
---|
107 | |
---|
108 | |
---|
109 | technique RenderSceneWithTechnique_7 |
---|
110 | { |
---|
111 | pass p0 |
---|
112 | { |
---|
113 | VertexShader = compile vs_2_0 RenderSceneWithTechnique_07_VS(); |
---|
114 | PixelShader = compile ps_3_0 RenderSceneWithTechnique_07_PS(); |
---|
115 | } |
---|
116 | } |
---|