UDN
Search public documentation
ShadowingReference
Shadowing Reference
Document Summary: A reference detailing the shadowing methods used in Unreal Engine 3.Overview
Unreal Engine 3 uses three distinct shadowing solutions. Briefly, they are as follows:- Shadow Volumes - The most general solution, they are hard-edged but fully dynamic and 100% accurate.
- Shadow Buffer Shadows - Also dynamic, but with nice soft edges, they are used for shadowing characters and dynamic geometry.
- Precomputed Shadows - Static lights illuminating static geometry, they affect both BSP and static meshes and can be saved out as shadow maps.
Shadow Factors
Although there are three very distinct shadowing methods they work seamlessly together. They assign to each pixel a shadow factor from 0.0 to 1.0. The rest of the lighting pipeline, including bump mapping, diffuse texturing, specularity map, self-illumination map, and user-created material parameters, operates independently of the current light's shadowing technique. So when you mix and match lights with different shadowing techniques, the only difference in appearance is in the degree of fuzziness of the shadows.Shadow Volumes
Shadow volumes are the engine's most general and accurate shadowing solution. They are created exclusively by dynamic lights, whether those lights are illuminating dynamic geometry (characters, movers, etc...) or static geometry (static meshes, BSP, etc...). They draw correctly no matter the distances between the light, occluder (object casting the shadow), and receiver, which is a limitation of shadow buffer shadows. Occluders casting shadow volumes also use them for self-shadowing.
Characters normally use shadow buffer shadows but will use shadow volumes (both for self-shadowing and shadows cast on the world) when illuminated by dynamic lights, as illustrated in the following image:
Shadow Volumes and Alpha
Shadow volumes do not take any alpha channel transparency into account. In the following example, a static mesh is illuminated by a dynamic light. As illustrated in wireframe view, the mesh is a subdivided plane. Its material's Opacity Mask is a texture with alternating black and white vertical bars. The material is set to BLEND_Mask. To learn more about materials check out the instructive MaterialsTutorial and the handy MaterialBrowserReference?.
Notice that while parts of the mesh are invisible, its shadow is a solid rectangle. Therefore if you want an object to cast a detailed shadow volume, consider building the detail geometrically.
Shadow Volumes in UnrealEd
Shadow volumes are used in the editor when you move lights around, to help illustrate light placement. Once you Build Lighting, the lights will cast the correct type of shadows. If the light moved is a dynamic light then it will continue to cast shadow volumes, but if it is static, shadow buffer or precomputed shadows will take over. Moving a light will snap the shadow volumes back on.Shadow Volumes and Open Edges
Since changelist 142881, both static and skeletal meshes may have open edges without affecting shadow volume performance. Prior to that, open edges made shadow volume extrusion more expensive.Shadow Buffer Shadows
Shadows produced with the engine's shadow buffer solution are fully dynamic like shadow volumes. They have the added benefit of blurred soft edges. See ShadowBufferFilteringOptions for applicable settings, and ShadowBufferFilteringTech for technical details. In UnrealEngine3, these shadows are used exclusively when static lights illuminate dynamic geometry, be it characters, movers, etc. They are used for both self-shadowing and for casting shadows on the world.
Note that the casting geometry must be enclosed by a collision volume to properly generate a shadow buffer shadow. For skeletal meshes this means that a PhAT asset? should be created and referenced by the SkeletalMeshComponent. Use the "show collision" console command to verify your collision volume while running the engine.
Shadow Buffer Shadows and Alpha
Casting Shadows with Alpha
Shadow buffer shadows have an added advantage over shadow volumes in that they take alpha channels into account.
In the above example, our occluder is a mover (dynamic geometry). The occluder's material has an Opacity Mask and its blend mode is set to BLEND_Masked. Again, to learn more about materials try the MaterialsTutorial and the MaterialBrowserReference?.
Note: Shadow Buffer shadows will take the occluder's opacity into account only if the material's blend mode is BLEND_Masked. They will ignore the opacity of a BLEND_Translucent material.
Receiving Shadows with Alpha
So as we've seen, a static light illuminating a dynamic mesh casts a shadow buffer shadow on the world. However, to ensure consistent shadowing on all objects, dynamic geometry will receive buffer shadows from static geometry occluders.
Above we have two grates. Grate A is our mover grate from before. Grate B is a new static mesh. As it is static, it uses precomputed shadows. The precomputed shadow uses the geometry only and ignores the opacity of the material. Note: that this is currently an unimplemented feature--precomputed shadows will take occluder opacity into account as well.
When the player walks behind Grate A, the shadow draws on the player as expected.
However, when the player walks behind Grate B, the player receives a shadow buffer shadow as well. This is handy if you want a static object to cast a shadow buffer shadow while using a precomputed shadow solution, such as a lightmap. Also it ensures that characters (and other dynamic geometry) are affected by environmental shadows, keeping their shadowing consistent.
Additional Overhead with Point Lights
In UnrealEngine3, a separate shadow is calculated per dynamic object per light. This results in much higher resolution shadows and normally does not introduce much additional rendering overhead. However, there is overhead to be aware of when dealing with point lights. When the shadow of a dynamic object would require a field of view of greater than 90 degrees to fit the whole object in view from the light, the engine switches to a cubemap of shadow depth buffers, which is significantly slower to render. (NB: The above information is out of date. Cubemap shadow buffers are no longer supported in UE3. Shadow buffers cannot be used correctly with point lights.)Precomputed Shadows
Precomputed shadows are the engine's nondynamic shadowing solution, used when static lights illuminate static geometry. The shadows are raytraced and therefore extremely accurate. As they are computed beforehand, they can be as high-resolution and as detailed as desired. Precomputed shadows work on both BSP and static meshes.
The engine precomputes shadow factors for each object (per texel or vertex) per light. This is an improvement over traditional light maps in two ways:
- Precomputed shadowing can be used for a light which changes color or brightness, as long as it's position remains static.
- Precomputed shadowing works correctly with view-angle and light-angle dependent per-pixel lighting (specular lighting, cubemaps, etc). Below: Red cube has specular highlight, Gold cube has cubemap. Both interact correctly with shadow maps.
UnrealEngine3 shadow maps also allow for interaction with dynamic lights, as illustrated below:
Precomputed Shadows and BSP
Whenever BSP geometry is illuminated by a static light it is shadow-mapped. To change the resolution of the shadows, select your surface or surfaces, and hit F5. This will bring up the Surface Properties menu.
Under Pan/Rot/Scale you will find a Light map value. The lower the value, the higher resolution the resulting shadows will be, as illustrated in the image below:
Precomputed Shadows and Static Meshes
Precomputed shadows are cast on static mesh geometry as well. By default, shadow factors are calculated per vertex. For more shadow resolution, a shadow map can be generated for each static mesh. A shadow map requires that all UV data be unique. No mirroring or tiling is allowed. If your static mesh's UVs have mirroring, stacking, or tiling, then you will need to create a second set of new unique UVs. For more information about how to set up multiple sets of UVs see the VertexBlendingTutorial. Open your static mesh in the Static Mesh Editor (double click it in the Generic Browser window). Fill the desired value into LightMapResolution. The default value of 0 means no shadow map will be created. Keep in mind that an independent shadow map will be generated for each instance of your mesh in the level file, which could potentially have dramatic memory ramifications.
If your mesh has multiple UVs, select the set you want to use for the shadow map in LightMapCoordinateIndex. The default is 0, which is the original set of UVs.
Notice that the number of UV channels is listed in the top left of the render window.
Below is an illustration of per-vertex shadowing vs. shadow maps.
Precomputed Shadows and Alpha
Although precomputed shadows don't currently take alpha opacity into account (as of this writing), this is a feature to be implemented in the future.Shadowing Options
LightComponent.CastDynamicShadows
If CastDynamicShadows=False, dynamic primitives will not cast shadows from the light. The default is true.
LightComponent.CastStaticShadows
If CastStaticShadows=False, static primitives will not cast shadows from the light. The default is true.
LightComponent.CastShadows
If CastShadows=False, the light will not cast any shadows. The default is true.
LightComponent.bForceDynamicLight
If bForceDynamicLight=True, the light will use shadow-volumes for all shadows. The default is false.
