Why Nanite Changes Everything for Foliage
Before Nanite, foliage was one of the hardest things to optimize in any game engine. You'd manually author 4-6 LOD levels per tree, tweak transition distances, fight pop-in artifacts, and still end up with forests that tanked your frame rate or looked flat at a distance.
Nanite eliminates this entire workflow. It virtualizes geometry, streaming only the triangles visible at the current pixel resolution. A tree with 500,000 triangles at close range might render as 200 triangles from 500 meters away — automatically, with no LOD authoring required.
With recent UE5 updates, Nanite foliage support has reached production maturity. Here's everything you need to know to use it effectively.
Enabling Nanite on Foliage Assets
Preparing Your Meshes
Not every foliage mesh is a good Nanite candidate. Here's the decision framework:
Good candidates for Nanite:
- Tree trunks and branches (opaque geometry)
- Rock formations and boulders
- Large bushes with solid geometry
- Ground cover with opaque materials
Keep as traditional meshes:
- Grass cards with alpha masking (Nanite handles masked materials but at a performance cost)
- Very small instances where traditional LODs are already efficient
- Assets that need custom LOD behavior (like billboards at extreme distance)
Enabling Nanite
For each static mesh:
- Open the Static Mesh editor
- In the Details panel, find Nanite Settings
- Check Enable Nanite Support
- Click Apply Changes
The mesh will be processed into Nanite's internal format. This increases the asset's disk size but dramatically reduces runtime memory per-instance.
Foliage Painter Settings
When using the Foliage painting tool with Nanite meshes:
- The foliage system automatically uses Nanite rendering for enabled meshes
- Cull Distance still matters — set it to control the maximum render distance
- Collision settings remain separate from rendering
- Instance count limits per component help with streaming
Material Considerations
Nanite's relationship with materials has evolved significantly. Here's the current state:
Opaque Materials
Fully supported with no limitations. Opaque foliage materials (bark, solid leaves, rocks) render at full Nanite performance.
Masked Materials
Nanite now supports masked materials, which is critical for foliage. Leaves, ferns, and grass typically use alpha masking for their silhouette shape.
Performance considerations with masked Nanite materials:
- Masked materials are slower than opaque in Nanite (roughly 2x the cost per triangle)
- Use Opacity Mask Clip Value of 0.333 or higher for cleaner results
- Minimize the number of unique masked materials — material switches add overhead
- Consider using opaque geometry for distant LODs where leaf shape isn't visible
Two-Sided Materials
For leaves that need to be visible from both sides:
- Enable Two Sided in the material settings
- Nanite handles two-sided rendering efficiently
- Use Two Sided Sign in your material graph to darken the backface slightly for natural lighting
World Position Offset (Wind)
This is the big caveat. Nanite does not support World Position Offset for vertex animation. This means:
- No vertex-based wind animation on Nanite foliage
- Use Pivot Painter 2 baked textures with the Nanite-compatible wind system
- Alternatively, animate at the instance level using Per-Instance Custom Data for subtle sway
- For hero trees near the camera, consider a non-Nanite LOD0 with full wind animation
Performance Profiling
Key Metrics to Monitor
Open Unreal Insights or use console commands to track:
stat Nanite // Nanite-specific rendering stats
stat RHI // GPU memory and draw call overview
stat FoliageOverview // Foliage instance counts and culling
profilegpu // Per-pass GPU timing breakdown
The metrics that matter most for Nanite foliage:
- Nanite Triangle Count: How many triangles Nanite is actually rasterizing (should be far less than total mesh triangles)
- Nanite Instance Count: Total visible Nanite instances
- GPU Scene Update Time: Time spent updating instance transforms (relevant for animated foliage)
Budgeting for Target Platforms
Rough performance budgets for Nanite foliage:
| Platform | Max Visible Nanite Instances | Target Triangle Budget |
|---|---|---|
| High-end PC (RTX 4080+) | 500,000+ | 100M+ triangles |
| Mid-range PC (RTX 3060) | 200,000 | 50M triangles |
| Current-gen Console | 150,000 | 40M triangles |
| Steam Deck | 50,000 | 15M triangles |
These are guidelines — always profile on actual hardware.
Optimization Strategies
Hierarchical Instance Management
For massive forests, organize your foliage into spatial partitions:
- Use World Partition to divide your world into cells
- Each cell loads only its local foliage instances
- Set Loading Range based on foliage type (large trees: far, ground cover: near)
- Use HLOD (Hierarchical Level of Detail) for distant foliage clusters
Nanite Fallback Meshes
Configure fallback meshes for platforms that don't support Nanite:
- In the Static Mesh editor, set Fallback Relative Error to control quality vs. triangle count
- Test fallbacks on target platforms — they should look acceptable at the distances where they'll be used
- Set per-platform Nanite enable/disable in your scalability settings
Density Scaling
Implement density scaling through your scalability profiles:
// In DefaultScalability.ini
[FoliageQuality@0] // Low
foliage.DensityScale=0.4
[FoliageQuality@1] // Medium
foliage.DensityScale=0.7
[FoliageQuality@2] // High
foliage.DensityScale=1.0
[FoliageQuality@3] // Epic
foliage.DensityScale=1.0
Culling Distance by Foliage Type
Not all foliage needs the same draw distance:
- Canopy trees: 50,000+ units (visible from far away)
- Medium trees: 30,000 units
- Shrubs: 15,000 units
- Ground cover: 5,000-8,000 units
- Grass: 3,000-5,000 units
Set these in the Foliage Type settings, not on the mesh itself, so you can tune per-usage.
Wind Animation Workarounds
Since Nanite doesn't support WPO, here are production-proven wind solutions:
Pivot Painter 2 + Nanite Wind
The recommended approach for Nanite foliage:
- Set up Pivot Painter 2 in your DCC (Maya, Blender, Houdini)
- Bake pivot points and hierarchy data into UV channels and vertex colors
- In UE5, use the Nanite-compatible wind material function
- Wind animation runs on the GPU without WPO
Instance-Level Animation
For subtle sway without per-vertex animation:
- Use Per-Instance Custom Data to pass wind parameters
- Animate the instance transform slightly (rotation around base)
- This is cheaper than vertex animation and works with Nanite
- Best for distant trees where vertex-level detail isn't visible
Hybrid LOD Approach
For hero vegetation near the camera:
- LOD0: Traditional mesh with full WPO wind animation (non-Nanite)
- LOD1+: Nanite mesh with instance-level sway only
- Set the LOD transition distance to where WPO detail becomes imperceptible (usually 20-50 meters)
This gives you the best of both worlds — detailed wind animation up close and Nanite efficiency at distance.
Common Pitfalls
Enabling Nanite on everything: Not every foliage asset benefits. Small grass patches with simple geometry may actually perform better as traditional instanced meshes.
Ignoring masked material cost: A forest of Nanite trees with masked leaf materials can be significantly slower than the same forest with opaque materials. Profile both approaches.
Forgetting about shadows: Nanite shadow rendering has its own performance characteristics. Virtual Shadow Maps work well with Nanite foliage but need proper cascade settings.
Not testing on target hardware: Nanite performance varies dramatically across GPU architectures. What runs fine on your RTX 4090 might struggle on a GTX 1660.
Skipping fallback configuration: If you ship on platforms without Nanite support (older hardware, some mobile), poorly configured fallbacks will look terrible.
Nanite Foliage in Production: A Checklist
Before shipping your Nanite foliage:
- All foliage meshes have appropriate Nanite enable/disable decisions
- Masked materials are optimized with proper clip values
- Wind animation solution is implemented and tested
- Cull distances are set per foliage type
- Density scaling is configured in scalability settings
- Fallback meshes are tested on minimum spec hardware
- Virtual Shadow Maps are configured for foliage
- HLOD is set up for distant foliage clusters
- Performance profiled on all target platforms
- World Partition streaming is configured for foliage cells
Nanite foliage is one of UE5's most impactful features for open-world games. The days of manual LOD authoring and constant performance battles with vegetation are behind us — but only if you set it up correctly.