Flow Field

Compute a navigation vector field from obstacles and goal positions. A sample of the field returns a steering direction in constant time.

What it does

Builds a navigation vector field through a volume. The space inside Bounds Min and Bounds Max is divided into cells, and every cell stores a direction pointing toward the nearest goal along the shortest open path around the obstacles. Cost is flooded outward from the goal, cheaper near the goal and more expensive the further an agent has to travel around obstacles, and the downhill direction is read at each cell.

Because the field fills a volume rather than a plane, agents steer in all three dimensions: birds flocking through a canyon, fish around a reef, drones between buildings.

The whole field is precomputed once, so any number of agents can sample it at their position for steering with no per-agent pathfinding search. Obstacles come from a field (anywhere darker than the threshold is blocked, so a volume, an image or a procedural field all work) or from geometry, where shapes fill the cells they occupy. Goals can be a single point or many at once.

When to use it

ParameterTypeDefault
obstaclesOneOf([FieldOf(Color), Collection])
goalOneOf([Vec3, Vec3Array, Collection])
bounds_minOneOf([Vec3])
bounds_maxOneOf([Vec3])
resolutionNumber64
diagonalBooleantrue
thresholdNumber0.500
resampleBooleanfalse
output_resolutionNumber32
opacityNumber1

Gotchas

Resolution is cells per axis, and the grid is three-dimensional, so it covers resolution × resolution × resolution cells. Doubling it multiplies the work by eight, not four. The default of 64 is 262,144 cells and solves in a fraction of a second; 128 is two million. Start low and raise it only if agents cut corners through obstacles.

Diagonal lets agents move through cell edges and corners rather than only through faces, giving smoother paths at some extra cost. Movement never squeezes diagonally between two blocked cells, so smoother paths never become paths through walls.

Resample stores the field at a different resolution than it was solved at. The useful direction is down: solve finely so routes stay correct around thin obstacles, then store a coarser grid that is cheaper to keep and sample. Setting it higher than Resolution does not add detail, because the field is smoothly interpolated when sampled either way. It only uses more memory.

cost_field is a secondary, hidden output: the raw distance-to-goal grid behind the flow direction. It is there for diagnostics or a custom gradient read, and does not appear automatically. Use field for steering.

Obstacles treat dark as blocked, so a bright or white obstacle image reads as open space. Invert it first if the obstacle shapes are painted light on dark. Threshold sets where the cut falls.

Cells the flood never reaches, whether sealed off behind obstacles or outside every route, report no steering direction at all rather than a guess. An agent sitting in one will not be pushed anywhere, which is the honest answer when there is no way through.

Worked example

  1. Add a Flow Field. Wire the obstacle layout into Obstacles: geometry that fills the blocked cells, or a field where dark means blocked.

  2. Wire a point (or an array of points) into Goal.

  3. Set Bounds Min / Bounds Max to the world-space box the grid should fill. Anything outside it has no field, so make it cover where agents will travel.

  4. Wire the field output into a Particle or boids node's steering input so agents sample it for direction each step.

  5. Raise Resolution if agents are cutting through obstacles; enable Diagonal for smoother flow instead of blocky face-to-face turns.

See also

Particle Sim · Pathfind · NavMesh Build · Vector fields