ShintTools

How to Optimize Trees & Foliage in Unreal Engine 5

A field guide to optimizing trees, foliage and vegetation in UE5 — LODs, Nanite, HISM, billboards, shadow cost and how to automate the audit.

·9 min read

Trees are the most expensive asset on any outdoor level in Unreal Engine 5. A single badly authored conifer — 80k triangles, no LODs, dynamic shadows on — can cost you 3 ms of GPU per instance. Multiply by 800 trees in a biome and you understand why your open world crawls at 22 fps on an RTX 3070.

A realistic vegetation budget

Reference numbers for a 60 fps game on current console hardware (PS5 / Series X):

  • Hero tree: 8–15k triangles at LOD0, 4 LOD steps, last one ~200 tris + billboard.
  • Background tree: 3–6k tris at LOD0, 3 LODs.
  • Bush: 500–2k tris, 2 LODs + billboard.
  • Grass: 30–80 tris per cluster, instanced, no dynamic shadows.

If your LOD0 is above double those numbers, you don't need more engine optimization — you need to go back to Speedtree or Blender and rebuild the asset.

LODs, transitions and dithering

UE5 picks LODs based on screen size. Two common mistakes:

  • Visible pops. Enable Dithered LOD Transition on the material so steps blend instead of snapping.
  • Different screens, same thresholds. Screen-size LOD selection means PS5 at 4K and a Steam Deck at 800p resolve differently. Set Min LOD per platform on the Static Mesh so a mobile target doesn't load your 80k-tri LOD0.

Nanite for trees: when yes, when no

Since UE 5.3, Nanite supports opaque foliage, and since 5.5 it also supports masked materials. But "supports" doesn't mean "always wins":

  • Trunks and large opaque branches → Nanite usually wins above ~5k triangles. Forget manual LODs.
  • Leaves (masked) → Nanite works, but overdraw cost on dense trees can exceed a traditional mesh with proper LODs. Compare in your scene, not in a synthetic benchmark.
  • Grass and instances in the thousands → stay on HierarchicalInstancedStaticMesh with LODs. Nanite has a fixed per-instance cost that doesn't scale well under a certain screen size.

HISM, Foliage Type and culling

The Foliage Tool paints instances into an HierarchicalInstancedStaticMeshComponent. It culls per-cluster by frustum and distance. Configure:

  • Cull Distance by type: large trees at 8–15k units, bushes at 3–5k, grass at 1.5–3k.
  • Start Cull Distance at ~80% of the end value for a soft fade.
  • Cast Shadow off for grass and tiny detail. Each dynamic blade shadow costs more than the actual render.
  • Affect Distance Field Lighting off for any masked material — it has no useful distance-field representation.

Shadows: the invisible cost

A 12k-tri conifer with dynamic shadows is re-rendered another 1–4 times for cascade shadow maps + virtual shadow maps. Rules:

  • Use Virtual Shadow Maps (UE 5.x) — more expensive per frame but amortize better than CSM in scenes with thousands of instances.
  • Use a simplified shadow mesh (Static Mesh → LODForShadows) with half the triangles.
  • Turn off dynamic shadows for any foliage past LOD2.

Auditing the drift

The problem isn't getting the prototype's 12 trees right. It's that six months in, you have 240 SpeedTrees from the marketplace, 80 built in-house and 30 one-off imports — and nobody remembers which ones meet budget.

ShintTools' LOD Auditor scans your project locally and emits a report listing every Static Mesh and Foliage Type out of budget: triangles per LOD, LOD0/LOD3 ratio, shadow casting on grass-tier instances, distance field on masked materials, estimated draw calls per biome. No cloud, no upload — it parses your .uasset files directly.

{
  "asset": "/Game/Foliage/SM_Pine_Large.uasset",
  "issues": [
    { "rule": "lod0_triangle_budget", "expected": "<=15000", "actual": 41200 },
    { "rule": "lod_count", "expected": ">=4", "actual": 2 },
    { "rule": "cast_shadow_on_grass_tier", "expected": false, "actual": true }
  ],
  "estimated_gpu_ms_per_instance": 2.8
}

Combined with the Code Validator, the plugin also flags foliage Blueprints that spawn instances without going through HISM, or that enable per-instance tick — the two most expensive mistakes we see when auditing studios.

Final checklist before locking a biome

  • Do all trees have at least 3 LODs plus a billboard?
  • Is grass on HISM, with shadows off and cull distance <3000?
  • Do masked materials disable Affect Distance Field?
  • Does the per-biome budget fit your target (PS5 / Steam Deck / Quest 3)?
  • Is there a CI or pre-commit check that fails when someone imports a tree over budget?

If the answer to the last one is no, the biome will degrade. Every new asset added by art without a tech pass pushes the frame budget the wrong way.