Your world streams now — that was last week. Time to put something in it. You press Shift+3, drag a tree into the palette, paint a forest, and your frame rate falls off a cliff.

Foliage Mode has a lot of settings. Six of them decide whether your forest ships.

Cull Distance, and the fade you're missing

End Cull Distance is the one everyone finds: past this distance, foliage isn't drawn. Set it too low and trees pop out at 20 metres. Set it to 0 (never cull) and you're rendering the entire forest, always.

What most people miss is Start Cull Distance. Foliage is drawn in clusters, and hitting End Cull makes a whole cluster vanish at once — a visible chunk of forest blinking out. Set Start below End, then use the PerInstanceFadeAmount node in your material: it goes from 1.0 at Start to 0.0 at End. Feed it into opacity or a masked value and instances fade instead of blinking.

Two settings and one material node. It's the difference between "looks like a game" and "looks like a build".

Collision: the free 40%

Every grass instance with collision is a collision primitive the physics scene has to care about. Ten thousand blades of grass, ten thousand primitives, and nothing in your game will ever touch them.

Set grass, flowers and small ground clutter to NoCollision in the foliage type. Trees keep collision — and even then, use a simple capsule, not per-poly.

There's a second lever: LOD For Collision on the static mesh. Default is 0, meaning collision comes from your highest-detail LOD. Push it to a cheaper LOD and you save memory. Push it too far and you get invisible holes and things falling through. Worth setting deliberately, not blindly.

LODs and the single-element rule

Foliage instances render as clusters in one draw call, which is where the performance comes from. That has requirements:

  • Your static mesh should have one entry in the Elements array under LOD0. Multiple materials on a foliage mesh multiplies your draw calls.
  • The whole cluster changes LOD at once, not per-instance. So LOD distances that look fine on a single mesh can look wrong on a painted field.
  • If you bake lighting: light and shadow maps are shared across LOD levels, so all LODs need the same UV unwrapping. Get this wrong and you get black meshes after a light build.

Density and Radius, honestly

The Density slider is a paint parameter, not a performance setting — but it's where beginners burn their budget. A dense grass field at density 400 is not four times as convincing as one at 100; it's four times the instances for a visual difference the player can't name.

Radius prevents instances from spawning on top of each other. Set it to roughly the mesh's footprint. Zero radius plus high density is how you get 3000 flowers occupying the same square metre.

What changes with Nanite

This is where 2022 tutorials mislead you. Two things you need to know:

Nanite-enabled foliage meshes are not affected by cull distance or instance fading. All that careful Start/End Cull work does nothing for them. Nanite runs its own culling and LOD.

Nanite shifts your bottleneck to materials. Nanite eliminates overdraw for material cost by only shading visible pixels — but every masked leaf card still costs clusters, and a dense forest blows through a cluster budget fast. Nanite trees also compress worse than solid meshes like rocks with the same triangle count, so memory goes up.

If you're on UE 5.7 or later, Nanite Foliage is worth a look: it replaces alpha-masked leaf cards with actual geometry, voxelises distant foliage instead of billboarding it, and does wind through Nanite Skinning (per-bone) rather than per-vertex WPO. It was still experimental in 5.7 preview, so check its current status before building a forest on it.


Plugin tip
Painting is great for organic scatter and terrible for anything with intent — a treeline along a road, hedgerows, a lane of markers. That's manual placement or a hand-built spline Blueprint every time. FoxSpline handles distribution along splines as nodes: spacing, offsets, alignment, lanes. Optional, but it's the part of your world that painting genuinely can't do.

Common pitfalls

  • Collision on grass. Free performance, always. NoCollision.
  • End Cull without Start Cull. Clusters blink out. Add the fade.
  • Multiple material elements on a foliage mesh. Kills the single-draw-call win.
  • Following cull-distance advice on Nanite meshes. It does nothing. Different system.
  • Cranking density instead of adding variation. Three mesh variants at density 100 beat one at density 400, cheaper.
  • Profiling foliage in the editor. Editor and packaged performance differ significantly. Always test the build.
  • Not using stat Nanite / the Nanite overdraw view. You're guessing otherwise. The overdraw visualiser accounts for masked materials — use it on your forest before you blame the GPU.

30-second recap

  • Start Cull + End Cull + PerInstanceFadeAmount — fade, don't blink.
  • Grass and clutter: NoCollision. Trees: simple collision only.
  • One material element per foliage mesh, or you lose the draw-call batching.
  • Radius stops overlap; density is not a substitute for variation.
  • Nanite foliage ignores cull distance and fading entirely — and moves your cost to materials and memory.
  • UE 5.7+ has Nanite Foliage with voxel LODs and skinned wind. Check its stability before committing.
  • Profile packaged, not PIE.

Next Sunday: Runtime Virtual Textures — blending meshes into your landscape so rocks stop looking like they're standing on it.

— Marco