Jump to content
  • Advertisement
Sign in to follow this  
xytor

Shadow mapping problem

This topic is 2828 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

Hello,
I am attempting to implement shadow mapping, but am failing pretty horribly.

For some reason, the shadows are in a completely wrong place, and not even oriented correctly:

http://imgur.com/ROEgP

What could cause this?

Share this post


Link to post
Share on other sites
Advertisement
Looks like you're using the wrong view matrix when rendering the shadow, or when projecting the shadow-map.

How do you calculate your matrices?

Share this post


Link to post
Share on other sites
Quote:
Original post by Hodgman
Looks like you're using the wrong view matrix when rendering the shadow, or when projecting the shadow-map.

How do you calculate your matrices?


I calculate the view matrix in c++ and pass it to the shader:


D3DXMatrixLookAtLH(&worldToLight,&(light.pos),&(light.dir),&(Vec3(0,1,0)));

Share this post


Link to post
Share on other sites
that is your lookat, but you need to create your projection matrix too and combine them. Usually, you create an orthographic projection. Good luck..

http://www.d3dcoder.net/d3d10.aspx

For some good information and code on how to do shadow mapping, download part III, unzip it, and check the folder chapter 13. It is about shadow mapping.

Share this post


Link to post
Share on other sites
Quote:
Original post by smasherprog
that is your lookat, but you need to create your projection matrix too and combine them. Usually, you create an orthographic projection.


Hmm, yes, I have that, too:


D3DXMatrixPerspectiveFovLH(&lightProjection,
D3DXToRadian(90),
(FLOAT)resX / (FLOAT)resY,
NEAR_PLANE,
FAR_PLANE);



Share this post


Link to post
Share on other sites
Your view matrix is wrong. The LookAt parameter isn't a direction vector, it's a point at which the camera looks. So you want to do this:

D3DXVECTOR3 lookAt = light.pos + light.dir;
D3DXMatrixLookAtLH(&worldToLight,&(light.pos),&lookAt,&(Vec3(0,1,0)));





Share this post


Link to post
Share on other sites
Quote:
Original post by MJP
Your view matrix is wrong. The LookAt parameter isn't a direction vector, it's a point at which the camera looks. So you want to do this:

D3DXVECTOR3 lookAt = light.pos + light.dir;
D3DXMatrixLookAtLH(&worldToLight,&(light.pos),&lookAt,&(Vec3(0,1,0)));


Wow, good call. But it doesn't change the incorrect shadows...
Is there anything wrong with my shader code?

Here is the code for rendering the shadow map (which looks correct):

/* posView is the pixel in light space, because the view matrix is temporarily using the light as a "camera"*/
return float4(IN.posView.z,IN.posView.z,IN.posView.z,1.0);





Here is where I use the shadow map texture:

float Shadow = 1.0;
if(shadowMapExists)
{
/*convert pixel position in light space to NDC, then to the
range [0,1]*/

float4 posTex = mul(IN.posLight,lightProjection);
posTex += float4(1,1,1,0);
posTex *= 0.5;

/*use converted pixel position to index into the texture*/
/*sampled values should be between the near plane and far plane;
[1.0,10000]*/

float D = tex2D(shadowSampler,float2(posTex.x,posTex.y)).z;
/* if the pixel value is smaller than the sampled value, it
means there is something in front of the pixel, in light space;
the pixel is in shadow*/

if( IN.posLight.z < D )
Shadow -= 1.0;

}



Share this post


Link to post
Share on other sites
If you're using a perspective projection you need to perform homogeneous divide-by-w before you can use X and Y as a texture coordinate. This brings the coordinates into the [-1, 1] range which you can then convert to [0, 1] range (which you're already doing).

After that, you also need to flip the y coordinate around. After divide-by-w, y is -1 at the bottom and 1 at the top. This is the opposite of texture coordinates, where 0 is the top and -1 is the bottom. Try this:

float4 posTex = mul(IN.posLight,lightProjection);
posTex /= posTex.w;
posTex += float4(1,1,1,0);
posTex *= 0.5;
posTex.y = 1.0f - posTex.y;

Share this post


Link to post
Share on other sites
Quote:
Original post by MJP
If you're using a perspective projection you need to perform homogeneous divide-by-w before you can use X and Y as a texture coordinate. This brings the coordinates into the [-1, 1] range which you can then convert to [0, 1] range (which you're already doing).

After that, you also need to flip the y coordinate around. After divide-by-w, y is -1 at the bottom and 1 at the top. This is the opposite of texture coordinates, where 0 is the top and -1 is the bottom. Try this:

float4 posTex = mul(IN.posLight,lightProjection);
posTex /= posTex.w;
posTex += float4(1,1,1,0);
posTex *= 0.5;
posTex.y = 1.0f - posTex.y;


Cool, I did not know that.

The shadows actually look decent now, but there are a lot of problems with them. The biggest problem are the z-values.

Currently, I use 1/pixelInLightSpace.z for both the shadow map and testing against the shadow map. This is because the biggest differences are now in the [0,1] range. However, it is still non-linear and causes problems.

Some other problems are:
-Small bands of light between an object and its shadow
-Occasional shadow-light stripes
-Weird behavior when the light is far away from the object

Does anybody know any solutions to these problems?

[Edited by - xytor on October 16, 2010 10:57:42 PM]

Share this post


Link to post
Share on other sites
1.The small bands of light you are seeing is the inaccuracy in float. This is totally normal.

2.This is also a problem with inaccuracy with float, try adding more bias (might make small bands of light bigger).

http://developer.nvidia.com/object/hwshadowmap_paper.html shows you how to solve this.

3.The further the light is away the higher your shadow Map resolution need to be for you to get better results.If I understand you correctly.

Hope this helps.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!