I'm having problems with writing a shadowmapping system. I've included the source to both shaders below. The depth shader renders the depth map to a camera which is positioned and rotated, FOV, etc set up in code. The shadow shader *should* project the depth map onto the level geometry. ( Yes, I know that's not shadowmapping, it's a test to make sure my projection is right and it's not. )
The texture is projected offset from the geometry. Actually moving the geometry gets the shadowmap closer to the correct position, which I hope is indicative of where the problem lies to someone smarter than me. In reality of course, moving the receiving geometry shouldn't make any difference since the camera will move with it. So my guess is that I have a matrix transform ( or several ) incorrect, but I'm damned if I can see anything wrong.
In the depth shader, the WorldViewProjection matrix is passed automatically by the engine, so that's definitely right. In the shadow shader, I copy the matrix from the depth shader and set it in the shadow shader. I know there are better ways, but again this is a test, to eliminate errors in calculations.
It's an isometric camera. I don't think that is pertinent to the problem, but I'll mention it in case it might be. Don't be afraid to address me as though I were a thick ox with very limited grasp of 3d maths, for that is indeed the case.
Depth Shader:
// SHADOWMAPPING SHADER
float4x4 WVPMatrix : WorldViewProjection;
float farPlane; // THE Z DIMENSION OF THE CAMERA FRUSTUM
struct VS_OUTPUT
{
float4 Position : POSITION0;
float3 Position2D : TEXCOORD0;
};
struct VS_INPUT
{
float4 Position : POSITION0;
};
VS_OUTPUT vs_depth( VS_INPUT Input )
{
VS_OUTPUT Output;
Output.Position = mul( Input.Position,WVPMatrix );
Output.Position2D = Output.Position;
return Output;
}
float4 ps_depth( VS_OUTPUT Input) : COLOR0
{
// WEB
return Input.Position2D.z/farPlane; // DIVIDE BY THE FARPLANE TO GET A VALUE BETWEEN 0 AND 1
}
technique DepthMap
{
pass Pass_0
{
VertexShader = compile vs_1_1 vs_depth();
PixelShader = compile ps_1_1 ps_depth();
}
}
Shadow Shader:
// SHADOWMAPPING SHADER
float4x4 WVPMatrix : WorldViewProjection;
float4x4 LightWVPMatrix;
float3 lightPos;
float3 lightXDir;
float3 lightYDir;
float3 lightZDir;
// SHADOW MAP AND SAMPLER
Texture ShadowMap : TEXTURE2;
sampler2D ShadowMapSampler = sampler_state
{
Texture = <ShadowMap>;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = LINEAR;
AddressU = CLAMP;
AddressV = CLAMP;
};
float farPlane; // THE Z DIMENSION OF THE CAMERA FRUSTUM
struct VS_INPUT
{
float4 Position : POSITION0;
};
struct VS_OUTPUT
{
float4 Position : POSITION0;
float4 Position2D : TEXCOORD0;
};
VS_OUTPUT vs_shadow( VS_INPUT Input )
{
VS_OUTPUT Output;
// OLD
Output.Position = mul(Input.Position,WVPMatrix);
Output.Position2D = mul(Input.Position,LightWVPMatrix);
return Output;
}
float4 ps_shadow(VS_OUTPUT Output) : COLOR0
{
float2 ProjectedTexCoords;
ProjectedTexCoords[0] = Output.Position2D.x/Output.Position2D.w/2.0f +0.5f;
ProjectedTexCoords[1] = -Output.Position2D.y/Output.Position2D.w/2.0f +0.5f;
return tex2D(ShadowMapSampler, ProjectedTexCoords);
}
technique ShadowMap
{
pass Pass_0
{
VertexShader = compile vs_1_1 vs_shadow();
PixelShader = compile ps_2_0 ps_shadow();
}
}