Game AI needs to answer spatial questions constantly. Where is the nearest cover? How far can this unit move before hitting an obstacle? What direction should a strafing enemy take to maintain a given distance from the player? SDFs turn every one of those questions into a field evaluation: one number gives clearance, and one gradient gives direction. This article covers the three main navigation workloads, environmental distance fields for clearance and placement queries, gradient-based steering for obstacle avoidance, and flow fields for crowd movement, and compares the whole approach against traditional navigation meshes.
For the basics of how sign and gradient work, start with the Signed Distance Fields overview . For the engine-wide context, see SDFs in game development .
Environmental Distance Fields as Navigation Data
A traditional navigation mesh stores walkable polygon regions with connectivity information. A distance field stores, at every point in space, the distance to the nearest obstacle. That additional information enables queries that a navmesh cannot answer efficiently.
The most useful field for navigation is the unsigned distance field of obstacle geometry, the environmental distance field (EDF). At any world position, the EDF returns how far away the nearest wall or obstacle is. A value of 2.0 means the agent has 2 meters of clearance in all directions. Note that the field is unsigned here: navigation only needs to know how far a point is from the nearest obstacle, not whether it is inside one, because walkable space is defined by being outside all obstacles.
This directly supports:
- Clearance queries: can a unit of radius occupy a position without intersecting any obstacle? Check whether .
- Cover selection: sample candidate positions and pick the one with the best combination of distance to enemy, distance to nearest cover surface, and line-of-sight properties.
- Flanking paths: compute a path that maintains a minimum distance from an obstacle rather than hugging its boundary.
Each of these would require repeated closest-point searches against a mesh. Against an EDF they are single evaluations, which is why baking an EDF for static level geometry and querying it per agent is the standard pattern.
Gradient-Based Steering
The gradient of the environmental distance field points toward the nearest obstacle. For a unit that wants to stay a fixed distance from a wall, the steering force can combine attraction along the navigation path with repulsion from obstacle surfaces:
vec3 obstacleSteering(vec3 position, SDF environment, float preferredDistance) {
float d = evaluateSDF(position, environment);
if (d > preferredDistance * 2.0) return vec3(0.0); // Too far to care
vec3 gradient = normalize(gradientSDF(position, environment));
// Push away if too close, pull toward if too far
float error = d - preferredDistance;
float strength = clamp(abs(error) / preferredDistance, 0.0, 1.0);
return strength * sign(error) * gradient;
}
When the unit is closer than the preferred distance, the error is negative and the force pushes it away from the obstacle. When it is farther, the force pulls it toward the obstacle. The magnitude ramps linearly from zero at the preferred distance up to full strength when the distance error equals the preferred distance. This creates smooth, natural-looking wall-following behavior without explicit path segments.
A worked example: preferred distance 1.0. At a position where the EDF reads 0.7, the unit is 0.3 closer than preferred, the error is -0.3, strength is 0.3, and the force is 0.3 units along the direction away from the obstacle. At an EDF reading of 1.4, the unit is 0.4 too far, the error is +0.4, and the force pulls it 0.4 units back toward the obstacle. Between the two extremes the force passes through zero exactly at the preferred distance, so the unit settles into a stable offset: no oscillation, because the force magnitude shrinks as the error shrinks.
Gradient-based steering composes with path following: the path provides a direction, the EDF steering provides the obstacle offset, and the two vectors are blended with weights. Units following a corridor wall simply steer along it, and the preferred distance parameter doubles as a crowd spacing control when units share the same value.
Flow Fields for Crowd Movement
For large numbers of agents, computing individual paths becomes expensive. A flow field replaces per-agent pathfinding with a single global vector field that every agent follows. The flow field is built by solving the Eikonal equation outward from goal locations, which produces a distance field from the goal. On a grid this is computed with Dijkstra’s algorithm or a fast marching method: each cell stores the accumulated travel cost to the goal, and the flow direction at a cell points toward the lowest-cost neighbor, toward the goal.
Agents simply read the flow direction at their current position and move. Distance checks at the goal stop them when they arrive. The field is recomputed only when obstacles or goals change, which makes it far cheaper than running individual A* searches for hundreds of units.
This technique is used in real-time strategy games, tower defense games, and any scenario with dense crowds of independently moving units. The common thread is that the distance field does double duty: its values encode path length to the goal, and its gradient encodes the next step direction.
Distance Fields vs Navigation Meshes for Pathfinding
| Property | Navigation Mesh | Distance Field |
|---|---|---|
| Nearest-obstacle distance query | Closest-point search on polygons | Single field evaluation |
| Clearance at a point | Approximate or per-polygon | Exact from the field |
| Pathfinding | A* over polygon graph | Dijkstra or A* over grid, or flow field |
| Memory | Compact polygon data | Grid samples, resolution-dependent |
| Dynamic obstacles | Rebuild regions | Recompute or locally update field |
| Wall-following behavior | Path smoothing tricks | Natural gradient steering |
The two representations are complementary in practice. Navmeshes excel at long-horizon pathfinding with sparse, efficient graphs, and they are the standard choice when agents need exact walkable regions with links, doors, and stairs. Distance fields excel at local decisions: clearance checks, obstacle offset, and dense crowd routing. A production AI system often uses both, a navmesh for global routes and a baked EDF for local steering and placement.
The main limitation of the distance-field approach is memory and update cost. A 3D EDF over a large level consumes grid-resolution-dependent memory, and baking it is a pre-processing step that must be repeated when the level changes. These are the same tradeoffs covered in baked signed distance fields , applied here to navigation data instead of rendering data.
Summary
Navigation converts the SDF contract into three AI workloads:
- Clearance and placement queries read EDF values directly: is this spot safe for a unit of radius ?
- Gradient-based steering uses the EDF gradient as a signed error signal that pushes too-close units away and pulls too-far units toward the preferred offset.
- Flow fields turn the Eikonal equation into a single global vector field that routes entire crowds.
The same baked field representation feeds the collision queries that run on the same static level geometry, so one bake serves both the AI system and the physics system.