Mesh Distance Fields

Unreal Engine 4 (UE4) leverages the power of Distance Fields to have dynamic ambient occlusion and shadowing for Static Mesh Actors in your games. In addition to that, the Mesh Distance Field representation of an Actor can be used for other features like GPU particle collision or even with the Material Editor to create dynamic flow maps and much more.

Continue reading below to learn how Mesh Distance Fields work in UE4 and some of the ways you can use it in your games.

How does it work?

To represent a Static Mesh's surfaces, a Signed Distance Field (SDF) is used. It works by storing the distance to the nearest surface in a volume texture. For every point on the exterior of the mesh is considered positive distance and any point inside the mesh stores a negative distance. In the example below, the positive distances are being traced and stored to represent the tree later on.

DistanceField.jpg

The first property of SDF that make them useful is that when tracing a ray, you can safely skip through empty space as the distance to the nearest surface is already known (this is sometimes called Sphere Tracing). This allows the intersections to be determined with a small number steps. By ray tracing a distance field, a visibility result is produced, meaning that if the ray intersects the mesh, the light will then be shadowed.

RayTrace.jpg

The second property that makes SDF useful is that when you trace a ray, by tracking the closest distance a ray passed by an occluding object, an approximate cone intersection can be computed with no extra cost. This approximation makes it possible to do very soft area shadows and sky occlusion using distance fields. This property is key to features like Distance Field Ambient Occlusion as a small number of cones can compute a soft visibility for the entire hemisphere of a receiver point.

ConeTrace.jpg

You can read further about using Distance Fields for Lighting here.

Scene Representation

Each level that you create is made up of all these Mesh Distance Fields for your placed Actors. When Mesh Distance Fields are generate, they are done so "offline" using triangle raytracing that stores the results in a volume texture. Because of this, mesh distance field generation cannot be done at runtime. This method computes the Signed Distance Field rays in all directions to find the nearest surface and stores that information.

You can visualize the Mesh Distance Fields that represent your scene by using the viewport and selecting Show > Visualize > Mesh Distance Fields.

Menu to Enable Visualization

Mesh Distance Field Visualization

Click image for full size.

Click image for full size.

When you see areas that are more white than gray, it means that many steps were needed to find the intersection of the mesh surface. Rays at grazing angles to surfaces took many more steps to intersect than would have for a simpler mesh.

Quality

The quality of a Mesh Distance Field representation is controlled by its volume texture resolution. This can be modified using Distance Field Resolution Scale in the Build Settingsof the Static Mesh Editor.

BuildSettings.png

The Mesh Distance Field quality will be best for levels that are built out of meshes with similar size, as large meshes tend to create a lot of errors. For example, meshes in Fortnite either conform to a grid or are props placed around parts of the level, which gives the best results with few errors. Landscapes are handled separately by heightfields and are not affected by Distance Field resolution.

Original Mesh

Resolution is too low, important features are lost.

Resolution has been increased, important features represented

Click image for full size.

Click image for full size.

Click image for full size.

The resolution of your Mesh Distance Field should be adjusted enough to capture the important features. As you increase the resolution of the mesh, the memory footprint of the Mesh Distance Field will increase as well. In the Static Mesh Editor, you can see the Mesh Distance Field size listed on the top left of the viewport.

Click image for full size.

When the Mesh Distance Field is generated, corners are rounded off based on resolution. This can be offset by increasing its resolution, but in most cases, should not be an issue depending on the complexity of the mesh. The maximum size volume texture any single mesh can have is 8 megabytes with a resolution of 128x128x128.

QualityCorners1.png QualityCorners2.png QualityCorners4.png

For thin surfaces, they can only be represented with a negative texel inside the mesh, which is necessary for finding its root. Increasing the resolution can capture the larger detail more accurately here, but in cases where you're only using Distance Field Ambient Occlusion and the surfaces aren't represented properly. Occlusion further from the surface will be accurate, so it's often not noticeable with sky occlusion.

QualityCorners3.png

Global Distance Field

The Global Distance Field is a low-resolution Distance Field that uses Signed Distance Fields occlusion in your levels while following the camera. It creates a cache of the per-object Mesh Distance Fields and composites them into a few volume textures centered around the camera, called clipmaps. Only newly visible areas or those affected by the scene modification need to be updated, so composition doesn't cost much.

The lower resolution of the object Distance Field means that it can be used for everything, but when computing cone traces for sky occlusion, they are sampled near the point of being shaded while the Global Distance Field is sampled further away.

You can visualize the Global Distance Field in the viewport by clicking Show > Visualize > Global Distance Field.

Click image for full size.

Below is a comparison of the per-object Mesh Distance Field visualization in comparison to the Global Distance Field visualization that combines them into clipmaps based on the camera view and distance.

Mesh Distance Fields Visualization

Global Distance Fields Visualization

For more information, visit the Distance Field Ambient Occlusion page.

Foliage

Foliage assets can also leverage the Distance Fields making it possible to have dynamic occlusion or even have distance shadowing beyond what Cascaded Shadow Maps can shadow.

Below are some options you should consider when using any foliage assets in your games to get the most out of performance and quality.

Two-Sided Distance Field

For high-density meshes (like trees) where you have surface that are usually made up of a masked material that represents many holes for leaves or branches, these cannot adquately be represented as a solid surface. For this reason, you can enable the Build Setting for Two-Sided Distance Field Generation in the Static Mesh Editor. This option will work well for foliage but does come at a higher ray marching cost.

Opaque Mesh Distance Field

Two-Sided Mesh Distance Field

In this example, the tree on the left is using a default opaque Mesh Distance Field representation. The one on the right has Two-Sided Distance Field Generation enabled. You'll notices that the two-sided mesh distance field is more white than it is gray and the surfaces are now translucent. This means that many more steps were needed to find the intersection of the mesh when generating the volume texture than the opaque one and will come at a higher cost.

Foliage Tool Settings

In the Foliage Tool, you must enable each foliage type that you want to use Distance Field lighting features for ambient occlusion and shadowing. By default, this setting is disabled because some foliage assets (like grass) where you would have thousands or tens of thousands of instances would overflow the tile culling buffer. When this happens, you can unsightly artifacts. So, only enable Affect Distance Field Lighting for the foliage assets that you need.

Enabling Distance Fields

To enable Mesh Distance Fields for your project, use the file menu to open the Project Settings window by going to Edit > Project Settings, then select the Rendering section.

Click image for full size.

Under the Lighting category, toggle the checkbox next to Generate Mesh Distance Fields.

GeneratedMeshDF.png

When you enable this, you will be prompted to restart your project.

RestartEditorButton.png

The next time you load the project, you will see the following pop-up in the lower corner indicating that Mesh Distance Fields are being generated.

BuildingMeshDFs.png

Once completed, you can visualize the Mesh Distance Fields in the viewport by clicking Show > Visualize > Mesh DistanceFields. You should see a similar view to this.

Scene View

Mesh Distance Fields Visualization

The entirety of this level is represented by instanced Distance Fields that are stored in volume textures.

Memory Usage and Optimizations

  • r.AOListMeshDistanceFields which dumps out the Mesh Distance Fields sorted by memory size to the Output Log. This can be useful for optimizing content.

  • Enable these from the Project Settings > Rendering:

    Click image for full size.

    • Compress Mesh Distance Fields can be enabled to store the Distance Fields volume texture compressed in memory. It will reduce how much memory they use, however, if you're using level streaming, they will cause hitches in your gameplay when these levels are streamed in.

    • Eight Bit Mesh Distance Fields can be enabled to store the Distance Fields volume texture in an 8-bit fixed point format instead of the default 16-bit floating point. It will only use half the memory previously used but can introduce some artifacts when you have a large or thin mesh.

  • Global Distance Field caches mostly static primitives with their mobility set to Static or Stationary. The full Global Distance Field inherits from mostly static cache, so when a Movable primitive is modified only other Movable primitives in the vicinity need to be recomposited into the Global Distance Field.

Limitations

Limitations of the Distance Fields technique:

  • Support for feature level 5 platforms only (DX-11 and above)

  • Only casts shadows from rigid meshes. For Skeletal Meshes, you can use Capsule Shadows for indirectly lit areas with Distance Field Ambient Occlusion (DFAO) and soft direct shadowing.

  • Materials that deform the mesh through World Position Offset or displacement may cause self-shadowing artifacts, as the Distance Field representation is generated offline and does not know about these deformations.

Limitations of the current implementation but can be improved in the future:

  • Non-uniform scaling cannot be handled correctly (although, mirroring is ok). Scaling the mesh by two times or less is not generally noticeable.

  • Only supports Static Mesh, Instances Static Mesh, Foliage, and Landscape (Heightfield). Foliage must be enabled with Affect Distance Field Lighting from the Foliage Tool settings.

Hardware Limitations:

  • All Mesh Distance Field features have been disabled on Intel cards because the HD 4000 hangs in the RHICreateTexture3D call to allocate the large atlas.

Essentials