Shadow mapping thoughts [Screenshots inside]
Hi,
Yesterday I added shadows to my homebrew hobby-engine but I'm having some doubts and I would like to know how people here would solve it.
I'm looking for ways to allow one light-source (or at least fake it), like the the sun, to render shadows over a large area but still keep the projected shadows fairly detailed.
I'm using shadow mapping and, due to the nature of the technique, I'm loosing detail very fast when the light-frustum gets large or the light is placed further away from the scene. The problem is that the detail degenerates extremely quick so using one light for a whole scene seems out of the question.
I'm using a 512x512 shadowtexture but I've been told that's a good standard size.
Here are some screenshots:
The light close to the scene (The white lines form the light-frustum I use to render the shadows):
The light further away from the scene (the aliasing in the shadows gets very noticable):
First of all I tried this solution:
1) Instead of using a "standard" projection frustum (a pyramid without the "top") as the light-frustum I used an Ortho projectionMatrix to eliminate the perspective distortion for a light that is close to the shadow-casting objects. That way I could place the light closer to the scene (to keep the shadows detailed) and still have shadows that are parallel to each other.
Though this is only a partial solution cause also here the light-frustum needs to be small.
Some screenshots:
Not good:
Good:
2) Link the "sun" position to the camera, but this has some serious draw-backs:
- shadows get more detailed if the camera is close to the scene
- Only works well for "top-down" views.
3) Use more "suns" but this gets expensive very fast as you have to render the complete scene twice per light-source.
I've seen games doing detailed textured shadows over large distances (Half Life2 comes to mind) so it should be possible and I'm wondering where the secret lies. Perhaps the more experience programmers here have an idea?
Thanks!
You should look into Trapezoidal Shadow Maps
http://www.comp.nus.edu.sg/~tants/tsm.html
Do NOT look into Perspective Shadow Maps or Light Space Shadow Maps. Both of these have problems that TSMs do not.
http://www.comp.nus.edu.sg/~tants/tsm.html
Do NOT look into Perspective Shadow Maps or Light Space Shadow Maps. Both of these have problems that TSMs do not.
TSM has its own set of issues, they're just different than that of Perspective or Light-space Shadow Maps. There will always be issues in some light orientation or another using a single shadow map for a whole large-scale scene.
And as for Half-Life 2, its lighting is not dynamic. It's the oldschool technique of lightmaps, kicked up a notch with the addition of bump-mapping (Valve termed the overall technique "Radiosity Mapping").
The best technique that I've heard of (so-far) has split the frustum up into chunks and mapped each chunk with its own standard shadow map (i.e. Z range 1-50 gets one 1024x1024 map, 50-150 gets one, etc). I just picked those values out of thin air, but you get the idea. Bonus points for adding some overlap and blending between the map results to make the detail level transition a bit smoother. Though the fillrate requirement for the shadowing increases a bit, the memory requirement doesn't, as you can render each segment of the frustum independently, and use the same shadow map over and over (Though there'd be a performance hit, I'm sure).
There are alot of good reasons to use such a technique:
First, it's simple to code. None of the oddities that PSMs, for instance, have. Simple and easy techniques that have good results are always a plus.
Second, the best-case and worst-case qualities of the map are identical. Perspective Shadow mapping has a great best case (light is perpendicular to the camera direction), but the worst case (camera looking directly at or away from the light) is much worse than normal shadow mapping. Since this IS normal shadow mapping (only with more shadow maps), the best and worst cases don't change - it's all one case.
The downsides:
Fill/transform rate requirements increase because of rendering multiple shadow maps
Transitions between the different levels of shadow detail can be noticeable without an overlap area with some blending, to soften the transition.
I'm sure there are more items in both categories, but that's my take.
Hope that helps!
Josh
And as for Half-Life 2, its lighting is not dynamic. It's the oldschool technique of lightmaps, kicked up a notch with the addition of bump-mapping (Valve termed the overall technique "Radiosity Mapping").
The best technique that I've heard of (so-far) has split the frustum up into chunks and mapped each chunk with its own standard shadow map (i.e. Z range 1-50 gets one 1024x1024 map, 50-150 gets one, etc). I just picked those values out of thin air, but you get the idea. Bonus points for adding some overlap and blending between the map results to make the detail level transition a bit smoother. Though the fillrate requirement for the shadowing increases a bit, the memory requirement doesn't, as you can render each segment of the frustum independently, and use the same shadow map over and over (Though there'd be a performance hit, I'm sure).
There are alot of good reasons to use such a technique:
First, it's simple to code. None of the oddities that PSMs, for instance, have. Simple and easy techniques that have good results are always a plus.
Second, the best-case and worst-case qualities of the map are identical. Perspective Shadow mapping has a great best case (light is perpendicular to the camera direction), but the worst case (camera looking directly at or away from the light) is much worse than normal shadow mapping. Since this IS normal shadow mapping (only with more shadow maps), the best and worst cases don't change - it's all one case.
The downsides:
Fill/transform rate requirements increase because of rendering multiple shadow maps
Transitions between the different levels of shadow detail can be noticeable without an overlap area with some blending, to soften the transition.
I'm sure there are more items in both categories, but that's my take.
Hope that helps!
Josh
I have been implementing shadow maps recently too, using shader model 1.0 and 2.0. The goals of my work include implementing shadows for the main light types found in programs such as Max and lightwave. These include Directional Lights, Point lights (Omni lights), Spotlights and maybe even area-lights.
I have not got much time so I'll quickly label the pro's and cons of the above.
1) Directional Lights
- these are easy to implement since they use an orthagonal projection.
- The TSM sample from the NVidia 8.0 SDK uses a directional light
2) Point Lights
- these are difficult to implement since graphical libraries do not seem to have such a thing as a cubic depth stencil.
- can be implemented using a fake depth buffer/rendertarget with distance encoded in
- some people have implemented these as a render-to-lightmap effect.
3) Spotlights
- arguably the easiest since there are loads of NVidia demos of this effect.
- has problems with an inverse square law - shadow map resolution is poor when the character/object is a long distance from the light.
4) Area lights
- no solution to arbitrarily shaped area lights in real-time.
- small circular area lights and spotlights can be approximated using shadow map blurring.
Overall I have noticed that each method of shadow mapping has it's pros and cons. For a good implemetation of Omni directional shadow mapping check http://www.humus.ca/
At the moment I really need a solution to the spotlight shadow resolution problem and a graphical flaw involved with Pixel shader 2.0 code from Nvidia which prevents my spotlight shadow map sample from having lightmap texture coords - I can use them in the Pixel shader 1_0 sample but the version with pixel shader 2_0 bugs when I try to spotlight onto the shadow map - the shadow simple ceases to exist even if I don't sample the lightmap Quite weird really.
If anyone has any advice I'd be very grateful - as I am pulling out my own hair in frustration atm.
I have not got much time so I'll quickly label the pro's and cons of the above.
1) Directional Lights
- these are easy to implement since they use an orthagonal projection.
- The TSM sample from the NVidia 8.0 SDK uses a directional light
2) Point Lights
- these are difficult to implement since graphical libraries do not seem to have such a thing as a cubic depth stencil.
- can be implemented using a fake depth buffer/rendertarget with distance encoded in
- some people have implemented these as a render-to-lightmap effect.
3) Spotlights
- arguably the easiest since there are loads of NVidia demos of this effect.
- has problems with an inverse square law - shadow map resolution is poor when the character/object is a long distance from the light.
4) Area lights
- no solution to arbitrarily shaped area lights in real-time.
- small circular area lights and spotlights can be approximated using shadow map blurring.
Overall I have noticed that each method of shadow mapping has it's pros and cons. For a good implemetation of Omni directional shadow mapping check http://www.humus.ca/
At the moment I really need a solution to the spotlight shadow resolution problem and a graphical flaw involved with Pixel shader 2.0 code from Nvidia which prevents my spotlight shadow map sample from having lightmap texture coords - I can use them in the Pixel shader 1_0 sample but the version with pixel shader 2_0 bugs when I try to spotlight onto the shadow map - the shadow simple ceases to exist even if I don't sample the lightmap Quite weird really.
If anyone has any advice I'd be very grateful - as I am pulling out my own hair in frustration atm.
Correct me if i'm wrong (and slightly off-topic), but is there a released game out there that uses shadow mapping to great effect? I know BattleField2 uses it, but it suffers from many artifacts.
To be honest I don't think shadow mapping is a robust shadow solution. It's great for the tech demos, but in a full blown game it does seem to break down quite badly.
Stencil shadowing is most robust I think (the only other solution?) but it does have it's own problems...
To be honest I don't think shadow mapping is a robust shadow solution. It's great for the tech demos, but in a full blown game it does seem to break down quite badly.
Stencil shadowing is most robust I think (the only other solution?) but it does have it's own problems...
Quote:Original post by Jimfing
Correct me if i'm wrong (and slightly off-topic), but is there a released game out there that uses shadow mapping to great effect? I know BattleField2 uses it, but it suffers from many artifacts.
To be honest I don't think shadow mapping is a robust shadow solution. It's great for the tech demos, but in a full blown game it does seem to break down quite badly.
Stencil shadowing is most robust I think (the only other solution?) but it does have it's own problems...
Yes several games use shadow mapping to great effect. One noteworthy title is splinter cell :chaos theory. I found an article on google about it here:-
http://www.extremetech.com/article2/0,1697,1839383,00.asp
I have played the game and it uses a lot of spotlight effects with projective texturing. The game does suffer slightly from the inverse square law resolution problem but overall it works quite well. I noticed that the engine seems to use a combination of shadow mapping and static lightmaps but I am not sure. Overall it's a great game and the shadow maps seem great and work seamlessly with the environment shadows.
I do agree that stencil shadows are a robust solution, since they cast accurate shadow volumes and allow multiple render passes to use additive blending.
The one problem I noticed is that it is difficult to cast stencil shadows from skinned meshes, so I assume I would have to update the skinned mesh in software and then use a software algorithm to generate the shadow volume. This would obviously be slower than a hardware implementation. I have never seen or heard of a hardware skinned shadow model.
Another problem with stencils is that the meshes have to be "closed 2-manifold" which means that a) the mesh surface is closed - eg a cube and
b )num_edges = 3*num_faces / 2 .
Hope this clarifies. I definately found an ATI demo which casts shadows from a skinned mesh - although there was no source so I can't be sure if it was in hardware.
Quote:Original post by Jimfing
Another problem with stencils is that the meshes have to be "closed 2-manifold" which means that a) the mesh surface is closed - eg a cube and
b )num_edges = 3*num_faces / 2 .
It's amazing that stencil shadows still have the reputation that they work only for 2-manifold objects, which simply isn't true. One solution is presented here: http://www.hitlabnz.org/fileman_store/2004-Graphite-ShadowVols-Aldridge.pdf
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement