7.2 Shadows
3Delight has an extensive support of shadow rendering methods. It is up to you to choose the algorithm that suits you best.
7.2.1 Raytraced Shadows | ||
7.2.2 Standard Shadow Maps | ||
7.2.3 Deep Shadow Maps | ||
7.2.4 Aggregated Shadow Maps |
7.2.1 Raytraced Shadows
Tracing shadow rays is an easy way for rendering shadows that requires very little setup. This technique has the advantage of being convenient and efficient in the case of complex scenes. Ray traced shadows are further described in Ray Traced Shadows.
7.2.2 Standard Shadow Maps
These are normal shadow maps that are widely used in the industry. Generating such shadow maps implies placing the camera at the position of the light source and rendering the scene from that view point (`zfile' or `shadowmap' display driver has to be selected, see The zfile display driver and The shadowmap display driver for information about file formats used and options). The shadow map is then used from inside a light source shader to cast shadows on objects. Shadow maps have a number of advantages:
- They are fast to generate. Indeed, shadow maps can be generated much faster than a normal "color" image, mainly because only depth information is needed. When rendering a shadow map, one could remove all surface and light shaders, even displacement shaders can be removed if they do not affect the geometry too much. Also, filtering (using
PixelFilter
command) can be lowered (even to 1x1) andShadingRate
increased (up to 10 or more). - They can be reused in more than one render. If the scene is static and only the camera moves, a generated shadow map can be used for all subsequent renders. This often happens in the lighting stage of a production pipeline.
- They can be used to generate low cost penumbra. Specifying an appropriate blur to the
shadow()
call, one can simulate penumbra effects (see shadow shadeop). - They provide fairly good results when used carefully. Many of the recent CG productions use normal shadow maps and obtain excellent results.
Now, the drawbacks:
- Self shadowing. This is the most common problem encountered when using shadow maps. It appears as dark artifacts in areas that should appear completely lit. This problem can be resolved by using an appropriate shadow bias, either via an option (see section Rendering Options) or through the `bias' parameter when calling
shadow()
(see shadow shadeop). - Nearly impossible to generate high quality area shadows. Even if tweaking with shadow blur can give a nice penumbra effect, it is impossible to generate a true area shadow.
- Expensive to generate really sharp shadows. This is because high resolution shadow maps are needed which often leads to longer render times and memory/disk usage.
- No motion blur in shadows. Moving geometry still casts shadows. It is wise to remove motion blur when rendering shadow maps.
- No colored shadows. Translucent surfaces cast opaque shadows.
- Only objects that are in the shadow map cast shadows. That is why shadow maps work so well with spot lights: they light only a limited field of view. Point lights are more tricky to handle (need six shadow maps) and distant lights are difficult to setup with shadow maps.
When creating shadow maps, make sure that shadow casting objects are framed correctly (and tightly) in the camera view that is used to render the shadow map. If objects are too far (small in shadow map view), precision problems may arise and high resolution shadow maps are needed. If objects are too close and parts of them are clipped, shadows might be missed. 3Delight supports the `midpoint' (Options) algorithm for normal shadow maps. This should help to get rid of shadow bias problems in most cases.
7.2.3 Deep Shadow Maps
Deep shadow maps retain many of the features found in normal shadow maps and provide some more goodies:
- Translucent shadows. Translucent surfaces cast correct shadows.
- Shadows in participating media. It is possible to render volumetric shadows using DSMs (the display driver has a flag to account for this feature, see The DSM display driver).
- Supports mipmapping. DSMs are mipmapped, which means that they exhibit much less aliasing artifacts than normal shadow maps.
- Needs lower resolution. Instead of generating large shadow maps to boost quality, one can generate a smaller DSM by using higher
PixelSample
values when creating the DSM. - Copes well with fine geometric details. Fine details such as hair and particles can be handled without increasing the shadow maps resolution too much.
- Render time shadow lookups are faster. Since DSMs are prefiltered, render time lookups are faster (in general) than with normal shadow maps since the signal reconstruction step is more efficient. In addition, DSMs are more texture cache friendly than shadow maps.
- Easily included in a rendering pipeline that already uses shadow maps. No modifications are necessary in shaders when changing shadow map format (normal or deep), the
shadow()
shadeop works with both formats.
Before throwing DSMs into the production pipeline, consider the following facts:
- More expensive to compute. Generating good DSMs is generally slower than shadow maps. This is often the case when many
PixelSample
s are used during the generation step. - Needs more disk space. DSMs can grow quite large, mainly for two reasons:
- DSMs are mipmapped by default.
- More data is stored per texel.
Using the "midpoint" option to produce deep shadow maps can lead to unpredictable results!
For deep shadow map creation please refer to The DSM display driver.
7.2.4 Aggregated Shadow Maps
Aggregated shadow maps are a collection of standard shadow maps concatenated into one single file. A good example of the usefullness of this feature is to generate shadow maps for point light sources, in which case six shadow maps are needed per light source (one for each cordinal direction). In this case, having six shadow maps to deal with creates at least two "problems":
- Pipeline wise, managing six shadow maps is more complicated than managing just one.
- Shaders (most commonly light source shaders) need to accept six shadow map string parameters, which is tedious.
The aggregation operation is performed by passing the aggregate
parameter to the shadowmap display driver, as explained in The shadowmap display driver. For example, to aggregate a shadow map to the already existing `shadow_point.shd' file, one would issue:
Display "shadow_point.shd" "shadowmap" "z" "integer aggregate" [1]
There is no limit on the number of shadow maps that can be aggregated together and the resulting shadow map can be queried from inside shaders using a single shadow()
call. The resulting operation of this single call is the accumulation of the opacities of all shadow maps present in the agregated file.
Parameters passed to shadow()
, such as `blur' and `samples', will be used on all the shadow maps in the aggregated file.
NoteAggregated shadow maps do not need to be rendered from the same point of view, as in the point light example.
3Delight 10.0. Copyright 2000-2011 The 3Delight Team. All Rights Reserved.