Real-time shadows

I need to use a shadow algorithm to achieve real-time performance. The scene is composed of multiple (2-4) light sources (mostly static) (may be inside the viewing frustrum too) and a few dynamic occluders (ex. humans, cars…). The background may be complex and the camera is dynamic.

I’m inexperienced, but I have read a lot about the subject. My problem is to choose between the shadow volume- and the shadow map-approach. Is my goal even possible to achieve in real-time using one of these methods? Will the shadow map method be too slow with multiple light sources? Are humans
too complex occluders for shadow volumes? Can fill-rate be a big problem? Unfortunately I don’t have time to implement them both and try.

I’m also interested in the possibility of combining the shadow volume approach with multi-texturing. Will this be too slow?

Anyone have any experience/suggestions?

Thanks,
Monica

My vote goes on shadow maps as they are much more general and easy to code and will most likely be faster. It also scales well, you can use lower res shadow maps for lower end machines for a quality/performance tradeoff.

Will the shadow map method be faster than shadow volumes with multiple lights (inside the view frustum too)?
I’ve read that the shadow map method may generate inaccurate results when the view and a light source have very different view angles - how serious is this?

Shadow volumes are better at point lights, since you don’t have to do a cubemap depth texture, and therefore 6 passes of the scene.

However, one question you might want to ask is, “Do you really need each light to cast a global shadow?” If you really do, and if these are point lights, I would have to go with volumes over maps. Maybe.

Originally posted by Monica:
I’ve read that the shadow map method may generate inaccurate results when the view and a light source have very different view angles - how serious is this?

Very serious. Shadow maps work in image space and will only be as good as the resolution of the shadow map. Worst case is when the viewer(camera) is facing a lightsource. NVIDIA’s dev site has some papers on shadow mapping that you might want to look at.

Depending on how serious your project is(how much time you got ,you might want look into deep shadow maps. It addresses some of the problems with normal shadow maps. The authors use it to cast shadows of very complex objects though, such has clouds and hair etc. If your occulders are mostly bulky blocks, you might be better of with shadow volumes, or even planar shadows.
http://graphics.stanford.edu/papers/deepshadows/

I’d say the forward looking way to do shadows is shadow maps, but stencil shadows are probably better on older hardware. You can get rid of a lot of the aliasing with shadow maps using perspective shadow maps and second depth shadow mapping . One problem you might run into is that even a fairly new card like the Radeon 8500 doesn’t support ARB_shadow AFAIK, so you’d have to do a special approach using ATI’s frsgment shader extension. This might give you lower precision depth buffers for your shadow maps but you could control the percentage closer filtering better at the expense of a few texture units. At least I think so, I haven’t done any work with ATI’s fragment shaders. You might also want to look into Tom’s demo of dual paraboliod shadow mapping here .

[This message has been edited by harsman (edited 02-01-2003).]

[This message has been edited by harsman (edited 02-01-2003).]

Thanks for all useful tips

I’ve started thinking about implementing with shadow maps. However, in the scenes my implementation will be used, static objects already has a shadow. My task is to add shadows only for the dynamic objects. Is there any way I can find only the shadows of these objects (and not the static) with shadow mapping? (Or should I go back to the shadow volume method???)

It seems to me that the shadow map method will make things more complicated than they need to be. (Unless anyone has a good solution to this problem… )

Hi,

In that case, just use projected shadow textures. They are fast and look good. The idea is to render each object from the light’s point of view so that the background is white and the object is black. Then project this texture on the enviroment with multiplicative blending.

If you want the enviroment to cast shadows on the objects, you can render the enviroment with white color into your shadow texture, and modulate object lighting with 1-shadowtexture. This will take care of double shadows too.

With this method the objects don’t self-shadow themselves, but for cars and humans self-shadowing is visually a minor feature and causes problems with polygon models. In return you can get soft-edged, semi-transparent shadows, which sounds like a fair trade to me.

-Ilkka

Do you need o write the shadow code yourself ?

Otherwise there are some APIs that makes this for you, and you can concentrate on building the app…

Yes, I have to make the code myself.

As the situation is now, it seems like the shadow volume approach is best fitted for my problem (since static objects already has shadows). (Does projection work (fast) on complex receivers?) But I hope this approach doesn’t get too slow because of my complex (humans) occluders! Any more thougths or experiences?

Ok. If you go for shadow volumes, it is sometimes neat to create the shadow volume out of a shadow map. On complex objects you can get a good approx by ucreating the geometry out of the shadow map, with much less geometry.

But often you will get fill rate limited. Check out the two pass stencil for this effect…

Humans shouldn’t be too slow if they’re reasonably tesselated. If you would extrude shadow volumes from your buildings you would get into trouble because of fillrate issues.

Projection is fast too, it’s propably the fastest method. But that is assuming you can do some high-level frustum culling for your scene so you don’t have to draw everything once for each shadow.

-Ilkka

Originally posted by ToolTech:
But often you will get fill rate limited. Check out the two pass stencil for this effect…

two pass stencil ? do you mean two sided stencil ? that does not improve fill rate. only less vertex setup, see here

[This message has been edited by valoh (edited 02-03-2003).]

please also see the following answer from cass that I got on another thread…

ToolTech
Frequent Contributor posted 01-17-2003 03:26 AM

I also beleive that I will not gain from using two sided stencil test because i think my volumes are just fill rate limited. i have no advanced vertex programs etc…

PH
Frequent Contributor posted 01-17-2003 07:41 AM

I see what you mean now. Maybe you could use INCR_WRAP and DECR_WRAP. I couldn’t find anything in the spec about whether front or back faces are processed first. However, you might be able to simply define front faces as being CW instead of CCW and then reverse the usage of the front/back tests ( just a quick idea, I haven’t really thought this through ).

cass
Frequent Contributor posted 01-17-2003 08:46 AM

Yes, please use INCR_WRAP and DECR_WRAP, that eliminates order dependence and saturation problems.

Two-sided stencil still saves because it keeps the fill hardware busy all the time.
If you get too many discarded triangles in a row (it happens), the rasterizer can run out of triangles to process.

Thanks -
Cass

Thanks again for many useful ideas!

I’ve seriously considered the shadow volume approach now. But I have problems with understanding how to make shadow textures from the result, with OpenGL. Does anyone know if (and how) this is possible?

Thanks

If you use a card with a lot of bandwidth, you might consider using the ATI (don’t know if it’s originally ATI’s) approach for closed shadow volumes. That is, creating a geometry of degenerate quads and face normals and project them if needed. It saves you from silhouette finding but consumes a lot of bandwidth due to the fact that all the triangles have their own vertices and that extra index information needs to be sent due to the degenerate quads and that this may result in the need for 32-bit indices on high-poly-count models.

Originally posted by Monica:
I’ve seriously considered the shadow volume approach now. But I have problems with understanding how to make shadow textures from the result, with OpenGL.

Shadow volumes don’t require any kind of “shadow textures”. The stencil buffer indicates which pixels are shadowed and which ones are not.

If you haven’t read them already, two very good tutorial on shadow volumes are http://www.gamasutra.com/features/20021011/lengyel_01.htm and http://developer.nvidia.com/view.asp?IO=robust_shadow_volumes

– Tom

Thank you, but I have already read them

One of my tasks is to get the shadows represented as textures - to integrate them with the rest of the model - by multitexturing. I’m not very experienced with this kind of work - that’s why I thought it might be possible to map the result from the stencil buffer into textures in some way. Isn’t that possible (or is it too slow to do?)

Maybe I should try to adjust the shadow map-method instead (to apply only for dynamic objects)… Have any of you had a similar problem before? I really need some advice!

[This message has been edited by Monica (edited 02-04-2003).]

Yep, shadow volumes don’t have much to do with textures. If you manage to somehow use texturing for that, you’re most likely just making things complicated for no reason.

Shadow maps can be easily made to work for the dynamic objects alone. Render only the dynamic objects into the shadow map, and then use that shadow map on the enviroment to get the shadows there. You will lose the effect of the enviroment casting shadows on the objects though.

I still think that projected shadow textures are the best option for this situation, they’ll give you better quality shadows and work fine with omnidirectional lights. For some reason I can’t find any good tutorial on it, anybody know one?

Anyway, do what you like. If this is for some school assignment or something, maybe you could post us a link to the assignment, so we could see, what they really want you to do. Then we could maybe help you better.

-Ilkka

Originally posted by JustHanging:
Shadow maps can be easily made to work for the dynamic objects alone. Render only the dynamic objects into the shadow map, and then use that shadow map on the enviroment to get the shadows there. You will lose the effect of the enviroment casting shadows on the objects though.

If you really wanted that to work, you could use two shadow maps – one that contains only the static scenery, and one that only contains the moving objects. You can then apply both shadow maps to the moving object, and only the dynamic one to the static objects. A bit fiddly, but it should work. The static shadow map can be precomputed, of course, so all you need is one spare texture unit for the moving objects.

– Tom