Skip to main content
GameDev.net gamedev.net
🔒 Locked

Question on my shadow mapping technique

Started by Corillian Sep 5, 2006 at 2:25 AM 2 replies 1k views
Original Post
Corillian
Corillian
Hello I have a question about whether or not I am going about shadow maps properly. My engine is using deferred shading to do the lighting as a post process. I am using the following render targets color: r32g32b32a32f normal: r32g32b32a32f position: r32g32b32a32f depth r32f The first pass renders the world space depth of all objects in relation to the position of the light source to the depth texture (r32f):

VS_DEPTH_OUT vs_depth(VS_INPUT In)
{
	VS_DEPTH_OUT Out;
	
	float4 pos = float4(In.ObjectPos, 1.0f);
	Out.Position = mul(pos, worldViewProjection);
	Out.Depth = mul(pos, matWorld).xyz;
	
	return Out;
}

float4 ps_depth(float3 depth : TEXCOORD0) : COLOR0
{
	return length(lightPos - depth);
}
The second pass renders the normals, colors, and position in world space using multiple render targets. The combine pass reads in the normal, position, and color for every pixel and then performs the lighting equation on it. At the moment I am projecting the world position of the pixel into light space using the light's view * projection matrix and then using that to do a tex2Dproj() lookup into the depth/shadow map. The distance from the light source is then compared to see if it's in the shadow:

float4 ps_combine(float2 texCoord : TEXCOORD0) : COLOR
{
	float4 pos    = tex2D(positionMapSampler, texCoord);
	float4 color = float4(tex2D(colorMapSampler, texCoord).xyz, 1.0f);
	
	//put the position in light space
	float4 vPosLight = mul(pos, matViewToLightProj);

	float shadow = tex2Dproj(depthMapSampler, vPosLight).x;
	float distance = length(lightPos - pos.xyz);
	float isShadowed = distance - 2.0001 > shadow ? 0.0f : 1.0f;
I am currently having some fairly heavy issues with z-fighting requiring me to offset the depth by a fairly large number (2.0001). There are also horrendous aliasing artifacts. I understand I am not doing any form of filtering and the depth texture is the same size as the backbuffer but it's still much worse than many of the demo's i've seen that don't do filtering. Any and all ideas will be most appreciated. P.S. Here's a screen shot of what I currently have. The red pixels are a plane that intersects with the light frustum and is occluded by the teapot's shadow: Screen Shot
Thergothon
Thergothon
Are you using an offset matrix to move the point in light space to a point in texture space? If you are not, you need to use this matrix:

offset = 0.5 + 0.5/shadowMapSize;

0.5, 0.0, 0.0, 0.0
0.0, -0.5, 0.0, 0.0
0.0, 0.0, 0.0, 0.0
offset, offset, 0.01, 1.0

You need to do this because when you move the world position into the light clip space its x/y coordinates are in the rang -1..1, and to get a correct texture coordinate, it needs to be in the range 0..1. The offset also corrects the sampling point to be the centre of the pixel and not the top left corner.
Corillian
Corillian
Yes I am. The offset texture matrix (this is using XNA):

float offsetX = 0.5f + (0.5f / (float)graphics.BackBufferWidth);            float offsetY = 0.5f + (0.5f / (float)graphics.BackBufferHeight);            float bias = 0.0001f;            m_matTexOffset = new Matrix(0.5f, 0.0f, 0.0f, 0.0f,                                    0.0f, -0.5f, 0.0f, 0.0f,                                    0.0f, 0.0f, 1.0f, 0.0f,                                    offsetX, offsetY, -bias, 1.0f);


And the matViewToLightProj matrix calculation (though it's actually world space to light space, i just never changed the variable names):

m_deferredShader.ViewToLightProjectionMatrix = m_lightCamera.ViewProjectionMatrix * m_matTexOffset;


Thanks for the reply.
Corillian
Corillian
One quick question. XNA uses right handed matrices (though I believe they're still row major). Could this be a problem since i'm hand coding the texture matrix?

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.