struct PixelToFrame { float4 Color : COLOR0; }; float4x4 xWorldViewProjection; float4x4 xLightWorldViewProjection; float4x4 xWorld; float4 xLightPos; float xLightPower = 1; float xMaxDepth = 300; bool xUseBrownInsteadOfTextures = false; Texture xColoredTexture; sampler ColoredTextureSampler = sampler_state { texture = ; magfilter = LINEAR; minfilter = LINEAR; mipfilter=LINEAR; AddressU = mirror; AddressV = mirror;}; Texture xShadowMap; sampler ShadowMapSampler = sampler_state { texture = ; magfilter = LINEAR; minfilter = LINEAR; mipfilter=LINEAR; AddressU = clamp; AddressV = clamp;}; //------- Technique: ShadowMap -------- struct SMapVertexToPixel { float4 Position : POSITION; float3 Position2D : TEXCOORD0; }; struct SMapPixelToFrame { float4 Color : COLOR0; }; SMapVertexToPixel ShadowMapVertexShader( float4 inPos : POSITION) { SMapVertexToPixel Output = (SMapVertexToPixel)0; Output.Position = mul(inPos, xLightWorldViewProjection); Output.Position2D = Output.Position; return Output; } SMapPixelToFrame ShadowMapPixelShader(SMapVertexToPixel PSIn) { SMapPixelToFrame Output = (SMapPixelToFrame)0; Output.Color = PSIn.Position2D.z/xMaxDepth; return Output; } technique ShadowMap { pass Pass0 { VertexShader = compile vs_2_0 ShadowMapVertexShader(); PixelShader = compile ps_2_0 ShadowMapPixelShader(); } } //------- Technique: ShadowedScene -------- struct SSceneVertexToPixel { float4 Position : POSITION; float4 ShadowMapSamplingPos : TEXCOORD0; float4 RealDistance : TEXCOORD1; float2 TexCoords : TEXCOORD2; float3 Normal : TEXCOORD3; float3 Position3D : TEXCOORD4; }; struct SScenePixelToFrame { float4 Color : COLOR0; }; SSceneVertexToPixel ShadowedSceneVertexShader( float4 inPos : POSITION, float2 inTexCoords : TEXCOORD0, float3 inNormal : NORMAL) { SSceneVertexToPixel Output = (SSceneVertexToPixel)0; Output.Position = mul(inPos, xWorldViewProjection); Output.ShadowMapSamplingPos = mul(inPos, xLightWorldViewProjection); Output.RealDistance = Output.ShadowMapSamplingPos.z/xMaxDepth; Output.Normal = normalize(mul(inNormal, (float3x3)xWorld)); Output.Position3D = mul(inPos, xWorld); Output.TexCoords = inTexCoords; return Output; } float DotProduct(float4 LightPos, float3 Pos3D, float3 Normal) { float3 LightDir = normalize(LightPos - Pos3D); return dot(LightDir, Normal); } SScenePixelToFrame ShadowedScenePixelShader(SSceneVertexToPixel PSIn) { SScenePixelToFrame Output = (SScenePixelToFrame)0; float2 ProjectedTexCoords; ProjectedTexCoords[0] = PSIn.ShadowMapSamplingPos.x/PSIn.ShadowMapSamplingPos.w/2.0f +0.5f; ProjectedTexCoords[1] = -PSIn.ShadowMapSamplingPos.y/PSIn.ShadowMapSamplingPos.w/2.0f +0.5f; if ((saturate(ProjectedTexCoords.x) == ProjectedTexCoords.x) && (saturate(ProjectedTexCoords.y) == ProjectedTexCoords.y)) { float StoredDepthInShadowMap = tex2D(ShadowMapSampler, ProjectedTexCoords).x; float DiffuseLightingFactor = DotProduct(xLightPos, PSIn.Position3D, PSIn.Normal); float4 ColorComponent = tex2D(ColoredTextureSampler, PSIn.TexCoords); if ((PSIn.RealDistance.x - 1.0f/100.0f) <= StoredDepthInShadowMap) { Output.Color += ColorComponent; } else { Output.Color = ColorComponent * 0.5; } } return Output; } technique ShadowedScene { pass Pass0 { VertexShader = compile vs_2_0 ShadowedSceneVertexShader(); PixelShader = compile ps_2_0 ShadowedScenePixelShader(); } }