Skip to main content
gamedev.net
🔒 Locked

Shadow mapping artifacts

Started by sorairo2 Jun 18, 2005 at 2:30 PM 7 replies 900+ views
Original Post
sorairo2
sorairo2
Hi there - I've implemented shadow mapping using the method in Game Programming Gems 1 and am having a problem with the texture tiling. I generate texture coordinates myself (by choice) and for the most part, the shadow projects nicely (I'd love to make them perspective correct but have no clue how). I'm having a problem with texture tiling artifacts. They appear to come up where the generated texture coordinates go from positive to negative and vice versa. This must be a common problem with texture coordinate generation, so I was hoping someone knew of a solution or could point me to a thread covering this issue. I've read many places to set the coordinates to (-1, -1) if the point lies behind the light, or if the receiving face is back-facing, etc., etc.. but they never talk about the fact that by doing so, you're going to be moving from positive to negative coordinates at some point, causing the visible shadow texture to draw. Here's a screenshot of 2 artifacts: 1) Shadow lines on the ground caused by small tiling going from positive to negative coordinates. 2) Shadow projected behind the light. Image hosted by Photobucket.com
superpig
superpig
The shadow being projected behind the light is an unfortunate side effect of the standard technique (which is basically a dynamic projected texture). You could fix it by using something like depth shadow maps to prevent geometry behind the shadow-caster being shadowed, or you could try to avoid rendering things behind the light for your shadow pass.
Richard "Superpig" Fine - saving pigs from untimely fates - Microsoft DirectX MVP 2006/2007/2008/2009
"Shaders are not meant to do everything. Of course you can try to use it for everything, but it's like playing football using cabbage." - MickeyMouse
Cypher19
Cypher19
One thing you could try is enclosing the shadowcaster inside a frustum/cone/pyramid with the point being at the light's position, and when rendering the scene, mask part of the image by rendering the shape with the stencil buffer set a certain way (like a shadow volume), then invert the mask and render the object and scene while adding the results. Sorry if that isn't very clear, but if I had more experience with stencil buffers it would be.

Alternatively, you could just spit out a shadow result of 1 behind the light.
SimmerD
SimmerD
The most general solution, as superpig suggests, is to introduce depth into the shadow calculation.

The easiest solution is simply to make a 2x1 texture with white in the left texel and black in the right one. Map your light space Z direction to this texture coordinate, and add the value from the texture to your existing texture map. This way anything behind the light won't receive a shadow.

Bonus points if you move the clamping texture coordinates to just before the caster's bounding sphere in light space.

You will still have artifacts if there is an object really close to the caster, but there's no solution to that other than using depth or id-based shadows.
Promit
Promit
Wouldn't simply clamping the texture Q coordinate to [0,1] in the pixel shader be sufficient? AFAIK, all hardware that supports the OGL shadow mapping extension also has pixel shader support.
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
Sunray
Sunray
Ignore pixels with negative w, clip planes..
[size="1"]Perl - Made by Idiots, Java - Made for Idiots, C++ - Envied by Idiots | http://sunray.cplusplus.se
sorairo2
sorairo2
Thanks for the helpful replies! I've tried a few techniques since then, based on what many of you have recommended, but if it's not one artifact, it's another.

Clipping negative W values has eliminated full shadows behind the light, but it also causes transitions from positive to negative shadow texture coordinates to occur in different areas.

A few questions:

- What is depth or ID-based shadow mapping? I've seen it mentioned elsewhere too but I can't find any info on it.

- Would using the 2-texel shadow mask be the equivalent to modulating with the vertex diffuse alpha yield the same effect? I've done the latter so that textures behind the light are faded out. This works fine except where a triangle moves from positive to negative space, in which case the shadow artifact gradually fades out as it reaches behind the light. I'm guessing I'd get a very similar effect with a 2 texel shadow mask, except that the transition would be more abrupt... which can be good in some cases and bad in others.


Note that I'm deliberately limiting myself to the DX7-era mainstream hardware (and pre-era in some cases). I'm also keeping stencil buffers out of the equation to ensure maximum compatibility and performance with older hardware, hence the choice for shadow mapping instead of volumetric shadows. I'm surprised that the former is so much more complicated.

Thanks!
Promit
Promit
Quote:
Original post by sorairo2
I'm also keeping stencil buffers out of the equation to ensure maximum compatibility and performance with older hardware, hence the choice for shadow mapping instead of volumetric shadows.


Odd, since hardware stencil buffers are far more widely supported than per pixel depth compares.

Unless, of course, you are not actually doing shadow maps but instead texture shadows.
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
SimmerD
SimmerD
Quote:
Original post by sorairo2
Thanks for the helpful replies! I've tried a few techniques since then, based on what many of you have recommended, but if it's not one artifact, it's another.

Clipping negative W values has eliminated full shadows behind the light, but it also causes transitions from positive to negative shadow texture coordinates to occur in different areas.

A few questions:

- What is depth or ID-based shadow mapping? I've seen it mentioned elsewhere too but I can't find any info on it.

Depth shadows are real shadow maps. They can be implemented in several ways, from hw z buffer shadow maps, to alpha test or pixel shader shadow maps.
I am using alpha-test based depth shadows, which work on dx6 hw and above.

ID-based shadows work by drawing each object with a different color in the shadow map, and then for each shadow receiver, check if its color is in the shadow map at that pixel or not. These don't have problems with limited depth range, but they are bad for small objects.

These can be implemented with alpha test as well, again on older hw.

Quote:

- Would using the 2-texel shadow mask be the equivalent to modulating with the vertex diffuse alpha yield the same effect? I've done the latter so that textures behind the light are faded out. This works fine except where a triangle moves from positive to negative space, in which case the shadow artifact gradually fades out as it reaches behind the light. I'm guessing I'd get a very similar effect with a 2 texel shadow mask, except that the transition would be more abrupt... which can be good in some cases and bad in others.


As you say, vertex attributes do not clamp properly, so a texture or shader approach is preferred when it really is a sharp transition. Clearly an object can't shadow something on the other side of light that it is on, so a sharp transition is required. You can use bilinear filtering to soften the transition slightly, but point sampling should work fine as well.

Quote:


Note that I'm deliberately limiting myself to the DX7-era mainstream hardware (and pre-era in some cases). I'm also keeping stencil buffers out of the equation to ensure maximum compatibility and performance with older hardware, hence the choice for shadow mapping instead of volumetric shadows. I'm surprised that the former is so much more complicated.

Thanks!


Topic Locked

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

Sign in to reply to this topic.