Sign in to follow this  

[HLSL] Shadowmapping Problem

This topic is 3668 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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();
   }
}

Share this post


Link to post
Share on other sites
This part right here jumps out at me...


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

}


You want to divide the z component by the w component, not by the farPlane. Since you're working with the result of of perspective projection, doing this automatically gives you a depth value of the range 0.0-1.0, scaled to the distance between your near and far clip planes.

Also just curious...why are you using vs_1_1 and ps_1_1?

Share this post


Link to post
Share on other sites
It's already been suggested to me that I should write to the depth map differently, but there's no point in improving it until it's actually working. I'm writing the depth map out to disk as and when I want to verify that the image is correct and visible, and the image is fine. I can deal with improving the depth writing when it's actually working. Clearly I'm doing something wrong with the projection at the moment, so I need to fix that first.

There's no particular reason I'm compiling to 1.1. Just force of habit to use the lowest version I can get away with I guess. It doesn't work any differently compiled to other version targets anyway.

Share this post


Link to post
Share on other sites
I'm not sure if this helps any, but I can't think of any more information that I can provide, so here's the LightWVP matrix, which is passed automatically by the engine to the depth shader and then copied by me to the project shader.


[0.200000003, 0.000000000, 0.000000000, 0.000000000]
[0.000000000, 1.19209318e-008,-0.333333403, 0.000000000]
[0.000000000, 0.200000033, 1.98682226e-008, 0.000000000]
[0.339280903, 0.0987815559, 1.00000012, 1.00000000]

That's for an isometric camera with a farplane of 20, facing directly downwards and positioned at 2,4,0.

As I say, the engine does that for me automatically, so it didn't ought to have any problems, but I thought I should probably post it so that you can be sure.

Share this post


Link to post
Share on other sites

This topic is 3668 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this