ShadowMaps in the rendering pipeline

Started by
2 comments, last by Lord_Evil 15 years, 1 month ago
Hi all I wondered if someone could shed some light (no pun intended) on the delicate art of shadowing for me. I understand the principles behind shadowmaps and even cascaded shadowmaps, but what I'm having problems understanding is the integration of shadowmaps (and CSM) into the rendering pipeline. Imagine a flat terrain. Sitting on top of the terrain are two geometrically different objects, a cube and a prism. There is a directional light in the scene which we'll call the sun. The cube is casting a partial shadow over the prism (and the terrain) and the prism is casting a shadow over the terrain, so effectively we have prism on the left, cube to the right slightly further away and the sun way off in the distance and to the right - as per the diagram:

                O

       -----
       |   |
  /\   |   |
----------------------

In this example, each object has the same material and because of my (intended) shader architecture, they both get batched and rendered within the same state. So let's assume the prism is to be rendered first... At this point, we somehow need a pre-baked shadowmap to have been created which actually contains the 'light imprint' of the cube (in order to determine that the prism is [partially] in shadow). So does that mean that the shadowmap for ALL objects in the current viewport needs to be created prior to ANY frame rendering? My intended shader integration will allow for pre-render steps like shadowmaps or reflection maps but I'm confused as to whether this stage will be carried out prior to: a) the entire scene, b) per material-batched objects or c) per object. I'm assuming it should get created prior to the entire scene, otherwise if the prism gets rendered first, it won't have the shadowmap info from the cube. I guess I could intiate the shadowmap creation when any object is encountered that has the 'can receive shadow' attribute. That being true, does that mean the same shadowmap is passed on and used for every single object in the entire viewport frustum? From the terrain point of view - do we have to include the terrain in the shadowmap creation pass? I assume we do in order to cope with objects that are in shadow from the terrain (including itself). Apologies if this is difficult to unravel or if there are too many intertwined questions - it's a tricky issue to describe. Thanks in advance for any advice
Advertisement
In general yes, you'll want to fully render all shadow-casting geometry to your shadow map before rendering your material pass where you actually utilize the shadow maps. This makes sense logicially (since, as you said, proper shadowing requires other other objects to have rendered themselves to the shadow map already) but also from a performance point of view. In general switching render targets is a slow operation, and so it's common to sort first by render target and then within those sort by shader/texture/material/etc.
Thanks, Matt. With regards to the terrain shadowing - i.e. how the prism casts a shadow on the terrain. I see three ways of doings this, both with trade-offs:

1) When rendering the shadowmap for the scene, do not render the terrain. So from the light's point of view, anything that casts a shadow will show up in the shadowmap (e.g. the prism). Not rendering the terrain means that the terrain area will remain black in the shadow map.

Then when rendering the terrain; for each pixel, check the value in the shadow map to see if it's in shadow, i.e. if there is something at that point, then it is because nothing can exist under the terrain. This would work quite well and give faster frame rates because I wouldn't need to render the terrain twice. The only issue I can see is that an object would not be in shadow from the terrain - imagine a player stood by a hilly area and the sun behind the hill.

2) When rendering the shadowmap, render everything including the terrain. This would give the best results but would render slower. I would get terrain shadowing for free with this method (with a relevant shadow cascading technique to avoid blockiness at distance).

3) When rendering the shadowmap, don't render the terrain. When each object is properly rendered that can have terrain shadowing casted upon it, carry out a ray intersection between the bounding box of the object, the terrain and the lightsource. If the terrain is blocking it, shadow the object otherwise don't. I use this method for my terrain occlusion culling which works pretty well (and quick), but there's no fine shadow granularity for big objects (like buildings) - they're either in full shadow or they're not.

Anyone know how this might be approached commercially? I'm assuming option 2 would be the best way to do it visually. As an afterthought to option 2, you could just render the shadowmap to include only the objects in the immediate to near viewing distance and only the terrain within that distance. Then anything outside the viewing distance could use option 3 to calculate whether it's fully in shadow or not....?

Thanks in advance

[Edited by - RobMaddison on March 17, 2009 9:48:25 AM]
When rendering to your shadow maps you'll want to disable everything that's not needed, like in a depth pre-pass, i.e. no color (except if you're planning to use translucent objects), no textures (except for translucency and/or alpha-testing), no pixel shaders etc.

If you're doing it correctly the GPU can render that at much higher rates, possibly at twice the speed as with color writes turned on.

Rendering only what is relevant to shadowing also will improve performance. However, you should consider including everything that can be "seen" by your light (for finite range lights) or at least everything that would cast a shadow into the visible portion of the scene.

Otherwise you could stand in front of a hill and look away from it. The hill would be outside the view frustum and thus not be included in the shadow map creation. As a consequence the ground below you would be lit instead of lying in the shadow.
If I was helpful, feel free to rate me up ;)If I wasn't and you feel to rate me down, please let me know why!

This topic is closed to new replies.

Advertisement