Jump to content
  • Advertisement
Sign in to follow this  
JustChris

Shadow mapping problems for individual objects

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

So I have been trying out this new method (new to me) to generate shadow maps, by giving each object their own shadow map rendered to a texture atlas and then projecting each portion of the map to the scene. The shadows look right, in that they are where they are supposed to be for each object, but a lot of them have dark boxes that take over part or all of the shadow's shape. This is something that I haven't encountered before in other methods I've used in shadow mapping. I have a feeling that the depth comparison is not sitting in well with the way I render each individual object.

For each shadow caster that is lit by a directional light, I create a tightly fitting bounding frustum that encloses the bounding box for that object. Long or skinny objects have the dark box problem the worst, their shadow shapes are covered more by it.

I noticed that scaling up the size of the bounding frustum remedies the problem somewhat, but it's not a consistent solution for all shadow casters. Plus, scaling up makes the object render smaller in the shadow map, and the shadows more low-res quality which goes against the purpose of using this shadow mapping technique.

Here is a video showing the problem, this time with just one object as a shadow caster (I cut back from texture atlases to isolate the problem). The light is rotating and with it the dark box stretches and rotates with it. The shadows *are* supposed to be off the pillars, since the pillars are ignored as shadow casters.

This is what my shader code for projecting shadow maps looks like. I'm sampling from depth G-Buffer to compare depths, not the depth from actual geometry.

[source lang="cpp"]

float depthVal = tex2D(depthSampler, input.TexCoord).r;

// Convert position to world space
float4 position;

position.xy = input.TexCoord.x * 2.0f - 1.0f;
position.y = -(input.TexCoord.y * 2.0f - 1.0f);
position.z = depthVal;
position.w = 1.0f;

position = mul(position, invertViewProj);
position /= position.w;

// Get shadow map position projected in light view
float4 shadowMapPos = mul(position, lightViewProj);

// Find the position in the shadow map for this pixel
float2 shadowTexCoord = shadowMapPos.xy / shadowMapPos.w / 2.0f + float2(0.5, 0.5);
shadowTexCoord.y = 1 - shadowTexCoord.y;

float shadowdepth = 0;
float3 shadow = 1;

// Calculate the current pixel depth
float ourdepth = (shadowMapPos.z / shadowMapPos.w) - DepthBias;

if ((shadowTexCoord.x <= 1 && shadowTexCoord.y <= 1) &&
(shadowTexCoord.x >= 0 && shadowTexCoord.y >= 0))
{
shadowdepth = tex2D(shadowMapSampler, shadowTexCoord).r;
shadow = shadowdepth > ourdepth;
}[/source]

Share this post


Link to post
Share on other sites
Advertisement
I might have found the cause of my shadow mapping problem. (Edit: I tried it out and this was in fact the problem.) Basically, with most objects the mini-frustum (the light blue diamond in the diagram) that encloses its bounding box is so small that part or all of the shadow falls outside of it.

That is, the shadow receiver isn't completely in front of the far plane of the mini-frustum from the light's POV, so it has no depth information to compare it against, making it always zero and so this portion is completely dark. The red portion in the diagram is likely the part of the shadow that gets cut away. Being that the frustum is box shaped, the projection in the red area appears as a dark box on the surface that it hits.

HZaKq.png

This is a non-issue for most shadow mapping techniques because the bounding volume used to create the frustum is usually the camera view's frustum which contains everything that's visible, so you won't see this box artifact as it falls beyond the clipping range of the camera.


So from this, I can assume that the longer shadows and shadows that are projected farther away in relation to the casting object will have a larger darkened area like this. That definitely seems to be the case when I tested shadows with various objects, as pillars have more of their shadows obscured. Objects that will have more problems are taller, skinny objects and surfaces receiving shadows that are almost parallel to the angle of the light.

This is probably why enlarging the frustum reduced the problem, because it puts more of the projected shadow in the frustum's view. It was a solution, but not the best one. All that's needed to do is to push the far clipping plane of the mini-frustum much farther away. The good news is that this won't reduce the shadow map quality in resolution.

Also, I know this post feels like an article, responding to myself, but someone else might be wondering how to solve this as well.

Share this post


Link to post
Share on other sites
Hidden
I might have found the cause of my shadow mapping problem. I don't have access to my programming projects right now, so I'm just speculating this. Basically, with most objects the mini-frustum (the light blue diamond in the diagram) that encloses its bounding box is so small that part or all of the shadow falls outside of it.

That is, the shadow receiver isn't completely in front of the far plane of the mini-frustum from the light's POV, so it has no depth information to compare it against, making it always zero and so this portion is completely dark. The red portion in the diagram is likely the part of the shadow that gets cut away. Being that the frustum is box shaped, the projection in the red area appears as a dark box on the surface that it hits.

HZaKq.png

This is a non-issue for most shadow mapping techniques because the bounding volume used to create the frustum is usually the camera view's frustum which contains everything that's visible, so you won't see this box artifact as it falls beyond the clipping range of the camera.


So from this, I can assume that the longer shadows and shadows that are projected farther away in relation to the casting object will have a larger darkened area like this. That definitely seems to be the case when I tested shadows with various objects, as pillars have more of their shadows obscured. Objects that will have more problems are taller, skinny objects and surfaces receiving shadows that are almost parallel to the angle of the light.

This is probably why enlarging the frustum reduced the problem, because it puts more of the projected shadow in the frustum's view. It was a solution, but not the best one. All that's needed to do is to push the far clipping plane of the mini-frustum much farther away. The good news is that this won't reduce the shadow map quality in resolution.

I still have to test this out to confirm my conclusion. Also, I know this post feels like an article, responding to myself, but I think someone else may be trying to figure out the cause of this problem too.

Share this post


Link to post
Sign in to follow this  

  • Advertisement
×

Important Information

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

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!