Levels of detail in Godot 4
Part of LODs and billboards for low poly models
Godot 4 has two ways to do levels of detail, and most projects use both without noticing. The importer makes simplified versions of every mesh, and the engine swaps between them on its own. You can also give any node a distance range over which it's visible, which is how you use levels you made yourself. This is the Godot half of LODs and billboards for low poly models. The Unity half is the LOD Group, the models come in through the Godot import article, and the MultiMesh article builds a forest that uses these levels.
Automatic mesh LODs
When Godot imports a mesh, it generates a chain of lower-detail versions and stores them in the mesh resource. At runtime the renderer picks a level from the mesh's size on screen, with no setup. This is on by default for every imported mesh.
The controls are in the Import dock, on the mesh or scene file, under Meshes. Generate LODs turns them on or off, and LOD Normal Merge Angle and LOD Normal Split Angle decide how aggressively the simplifier merges faces. On a low poly model the simplifier removes the facets that are the style, so the automatic levels are right for the far distance and rough for the middle distance. The project setting rendering/mesh_lod/lod_change/threshold_pixels sets how eagerly the engine drops a level, and each GeometryInstance3D has an LOD Bias to scale it per node. An OBJ imported as a single mesh has only a Generate LODs checkbox. Older Godot 4 releases didn't generate LODs for a mesh import at all, so if the option isn't there, set Import As to Scene and reimport.
Visibility ranges
To control what each level looks like, make each level its own node. Every VisualInstance3D, which includes MeshInstance3D, has Visibility Range Begin and End, and the node is visible only when its distance from the camera is between them. Three MeshInstance3D nodes under one parent, with ranges of 0 to 40, 40 to 120 and 120 to 400 meters, make a hand-made LOD set, and the far one can be a billboard quad.
Visibility Range Begin Margin and End Margin add hysteresis, so a node doesn't flicker at the boundary. Visibility Range Fade Mode decides what happens in the margin. Disabled is a hard swap and Self fades the node itself. Dependencies fades in the nodes that name this one as their Visibility Parent, which is how a hierarchical LOD swaps a group of objects for one stand-in. A fade across a few meters hides the pop.
The ranges are in world meters, not screen size, so a big tree and a small one with the same ranges swap at the same distance whatever their size on screen. Set them per model.
Which to use
Automatic LODs cost nothing to set up and are enough for props and rocks, where nobody looks closely at the far level. Visibility ranges are for trees and anything whose far level should be a particular shape, or a billboard. The two work together, because each node in a visibility range set still gets its automatic mesh LODs within its range.
Fading between levels
Only one of the two can fade. Automatic mesh LODs switch instantly, and there's no fade setting for them. Visibility ranges fade when you set a fade mode and give them a margin. For a hand-made set, a margin of a few meters with Self fading is the equivalent of Unity's cross fade.
With a MultiMesh
A MultiMeshInstance3D draws thousands of copies of one mesh in one draw call. All the copies share one automatic LOD level at a time. Godot picks it from the point on the MultiMesh's bounding box nearest the camera, so a MultiMesh that covers a whole forest stays at full detail whenever the camera is inside it. Visibility ranges work the same way and apply to the whole node. To get real LOD in a forest, split it into several MultiMeshes by area, so the far ones drop a level while the near one stays detailed. For hand-made levels, give each area one MultiMesh per level, each with its range, and put that area's instance transforms in each. The forest article does this.
What PolyMason exports
The tree builder writes LOD0, LOD1 and LOD2 as separate files with the same bounds and the same palette, so a visibility range set is three MeshInstance3D nodes under an empty. You can also import LOD0 alone and let Godot's automatic LODs handle the rest. For a low poly tree that's acceptable at a distance and not any closer.
More in this guide
- LODs and billboards for low poly modelsHow levels of detail work, what triangle counts are reasonable for low poly trees, rocks, buildings and characters, how to make the levels so the swap doesn't pop, billboards and impostors for the far distance, and the LOD setup in Unity, Godot and Unreal.
- Unity's LOD Group from separate model filesHow to build a LOD Group in Unity from three separate model files, what the screen-height thresholds mean, the naming convention that makes the importer build the group for you, fade modes, LOD Bias, and how LOD Groups work with batching and instancing.
- Billboard trees in Unity for the far distanceWhat a tree billboard is, how to make the picture, the two ways to show one in Unity (a quad with a cutout material, or a Billboard Renderer), how terrain trees do it for you, and the settings that keep it from looking flat.
- Tree colliders in Unity: a capsule on the trunkWhy a tree's collider should be a capsule around the trunk with nothing around the canopy, how to set it up on a placed tree and on a terrain tree, what Generate Colliders on the importer gets wrong, and the same setup in Godot and Unreal.
Or build a tree and see what comes out.