//direction of the light float3 lightDirection; //color of the light float3 Color; //position of the camera, for specular light float3 cameraPosition; float3 lightPosition; float4x4 LightViewProjection; //this is used to compute the world-position float4x4 InvertViewProjection; // diffuse color, and specularIntensity in the alpha channel texture colorMap; // normals, and specularPower in the alpha channel texture normalMap; //depth texture depthMap; // shadow texture shadowMap; sampler shadowSampler = sampler_state { Texture = (shadowMap); AddressU = CLAMP; AddressV = CLAMP; MagFilter = LINEAR; MinFilter = LINEAR; Mipfilter = LINEAR; }; sampler colorSampler = sampler_state { Texture = (colorMap); AddressU = CLAMP; AddressV = CLAMP; MagFilter = LINEAR; MinFilter = LINEAR; Mipfilter = LINEAR; }; sampler depthSampler = sampler_state { Texture = (depthMap); AddressU = CLAMP; AddressV = CLAMP; MagFilter = POINT; MinFilter = POINT; Mipfilter = POINT; }; sampler normalSampler = sampler_state { Texture = (normalMap); AddressU = CLAMP; AddressV = CLAMP; MagFilter = POINT; MinFilter = POINT; Mipfilter = POINT; }; struct VertexShaderInput { float3 Position : POSITION0; float2 TexCoord : TEXCOORD0; }; struct VertexShaderOutput { float4 Position : POSITION0; float2 TexCoord : TEXCOORD0; }; float2 halfPixel; VertexShaderOutput VertexShaderFunction(VertexShaderInput input) { VertexShaderOutput output; output.Position = float4(input.Position,1); //align texture coordinates output.TexCoord = input.TexCoord - halfPixel; return output; } float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0 { //get normal data from the normalMap float4 normalData = tex2D(normalSampler,input.TexCoord); //tranform normal back into [-1,1] range float3 normal = 2.0f * normalData.xyz - 1.0f; //read depth float depthVal = tex2D(depthSampler,input.TexCoord).r; //compute screen-space position float4 position; position.x = input.TexCoord.x * 2.0f - 1.0f; position.y = -(input.TexCoord.y * 2.0f - 1.0f); position.z = depthVal; position.w = 1.0f; //transform to world space position = mul(position, InvertViewProjection); float4 projection = mul(position, LightViewProjection); float2 projectedTexCoords; projectedTexCoords[0] = projection.x / projection.w / 2.0f + 0.5f; projectedTexCoords[1] = -projection.y / projection.w / 2.0f + 0.5f; float4 moments = tex2D(shadowSampler, projectedTexCoords); float len = length(lightPosition - position) / 10000; float depthBias = (1.0f / 200.0f); float4 color = 1; if(len - depthBias > moments.r) { color = 0; } return color; } technique Technique0 { pass Pass0 { VertexShader = compile vs_2_0 VertexShaderFunction(); PixelShader = compile ps_2_0 PixelShaderFunction(); } }