Indirect Lighting Cache

Lightmass generates lightmaps for indirect lighting on static objects, but dynamic objects like characters need a method of receiving indirect lighting as well. This is solved by the Indirect Lighting Cache, which uses samples generated by Lightmass at build-time to calculate the indirect lighting for dynamic objects at runtime.

In the images below, you can see the difference between the dynamic objects rendered with and without the contribution from the indirect lighting cache:


Diffuse lighting in the Elemental level without the Indirect Lighting Cache.


Diffuse lighting with the Indirect Lighting Cache.

How it works

From a high level point of view:

  • Lightmass places lighting samples throughout the level and computes indirect lighting for them during a lighting build.

  • When it comes time to render a dynamic object, the Indirect Lighting Cache checks to see if it already has available lighting for that object and uses it if so.

  • If no lighting was available (the object is new or moved too much), the Indirect Lighting Cache interpolates lighting from the precomputed lighting samples.

Lightmass places the lighting samples on top of upward facing surfaces with high density, and everywhere else with low density. The samples are limited to being within the LightmassImportanceVolume, and they are only placed on static surfaces.


Using Show->Visualize->Volume Lighting Samples to visualize the lighting samples generated by Lightmass.

The goal with this workflow is to require as little content setup as possible. However, sometimes this placement heuristic gives insufficient detail in areas that are floating in space, for example an elevator that characters ride on or a flying section. You can place LightmassCharacterIndirectDetailVolumes around those areas to get more detail.

At runtime, the Indirect Lighting Cache will interpolate the lighting samples to positions around each movable object. A movable object is any component with Mobility set to Movable.

Here the torus is a movable Static Mesh and the 5x5x5 interpolation positions are shown.


This interpolation only happens when the object moves enough to invalidate it, hence the cache naming. Note that the positions are quite far from the object's bounds. This is to provide continuous and stable lighting as the object moves through the world. Most objects will effectively get 3x3x3 interpolation resolution. The volume lighting samples store directional indirect lighting which allows normal maps to work.

Previewing Unbuilt Lighting

The Indirect Lighting Cache also allows previewing of objects with unbuilt lighting. It works pretty well for smaller objects, but not very well for large meshes like buildings or floors. When you move a Static Mesh that had lighting built, it will automatically switch to the Indirect Lighting Cache until the next lighting build.

Here one of the pillars has been duplicated and it gets indirect lighting for previewing instead of being black.