So I've been working this week trying to do shadow mapping for the very first time. I've gone over a lot of different papers, tutorials, and examples but I seem to be a little stumped now with tracking down the solution to my current issue.
As you can see the shadows are getting cut off near the shadow casting objects. So it seems that the bias value is too large.
As I lower the bias value, it starts to choke the outer part of the spot light. However the shadows do start to get closer to the base of the casters.
I've left the area of the spot light that are completely shaded a value of 0.3 so you can see where the light should be but it really starts to have issues.
I was really worried that my shadow map projection was the cause for this oddness. I went and just made shadow map texture project into the scene.
The projected texture looks absolutely perfect and I can visual see the depth values projecting into the areas that were getting cut off so I am confident that it is not because of a loss of precision in the shadow map (using R32F format).
It seems there is just something wrong with how I have current scene fragment's distance to the light and corresponding depth value stored in the shadow map.
Here is my shadow map depth shader:
Depth_vs:
float4x4 gLightWorldViewProjectionMatrix;
struct VS_INPUT
{
float4 Position : POSITION0;
};
struct VS_OUTPUT
{
float4 Position : POSITION0;
float3 DepthPosition : TEXCOORD0;
};
VS_OUTPUT main( VS_INPUT IN )
{
VS_OUTPUT OUT;
OUT.Position = mul(IN.Position, gLightWorldViewProjectionMatrix);
OUT.DepthPosition = OUT.Position;
return( OUT );
}
Depth_ps:
float gFar;
struct PS_INPUT
{
float3 DepthPosition : TEXCOORD0;
};
float4 main( PS_INPUT IN ) : COLOR0
{
float depth = (IN.DepthPosition.z/gFar);
return float4(depth, depth, depth, 1.0f);
}
Then a dissected look at the scene's shaders
Lighting_vs:
//Transformation matrices
float4x4 gWorldMatrix;
float4x4 gWorldViewProjectionMatrix;
...
struct VS_INPUT
{
float4 Position : POSITION0;
...
};
struct VS_OUTPUT
{
float4 Position : POSITION0;
...
float4 WorldPosition : TEXCOORD5;
float4 LocalPosition : TEXCOORD6;
};
VS_OUTPUT vs_main( VS_INPUT IN )
{
VS_OUTPUT OUT;
OUT.Position = mul(IN.Position, gWorldViewProjectionMatrix);
OUT.LocalPosition = IN.Position;
OUT.WorldPosition = mul(IN.Position, gWorldMatrix);
...
return( OUT );
}
lighting_ps:
...
//Shadows
...
sampler gShadowMap1_2d;
float4x4 gShadowMapMatrix1;
...
//Lights
float4x4 gLightPositions;
...
float4 gLightRanges;
struct PS_INPUT
{
...
float4 WorldPosition : TEXCOORD5;
float4 LocalPosition : TEXCOORD6;
};
...
float4 ps_main( PS_INPUT IN ) : COLOR0
{
IN.WorldPosition.xyz /= IN.WorldPosition.w;
IN.LocalPosition.xyz /= IN.LocalPosition.w;
...
//Prep spot shadows
float4 shadowLit = float4(1,1,1,1);
float3 L[4];
float dist[4];
...
L[1] = gLightPositions[1] - IN.WorldPosition;
...
dist[1] = (length(L[1]))/(gLightRanges[1]);
...
float4 shadowCoords = mul(IN.LocalPosition, gShadowMapMatrix1);
float A = tex2Dproj(gShadowMap1_2d, shadowCoords).r;
float B = dist[1] - 0.07f; //bias
shadowLit[1] = (A < B ? 0.3f : 1.0f);
...
}
Has anyone run across this issue before, or notice something funky with my shader code to compare the distance to see if it should be shadowed?
Much thanks for any help!