Shadow mapping depth issues

Started by
-1 comments, last by ImpulseOverload 15 years, 10 months ago
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!

This topic is closed to new replies.

Advertisement