A forest in Godot 4 with MultiMeshInstance3D
Part of Free low poly assets for Godot
A forest of a thousand MeshInstance3D nodes works, slowly. The same forest as one MultiMeshInstance3D is one node, one draw call per level of detail, and it renders at the speed of a single tree. This is how to make one from a low poly tree, vary the trees, and keep the far ones cheap. It follows on from free low poly assets for Godot, which is where the tree comes from, and the packs compared, which is where the alternatives are; the levels the forest uses are in the Godot LOD article.
What a MultiMesh is
A MultiMesh resource holds one mesh and an array of instance transforms, and optionally a colour and some custom data per instance. A MultiMeshInstance3D node draws it: every instance in one call, with the GPU doing the placement. The instances share the mesh and the material, which is why one material per tree, a palette texture, is the right export for this.
Setting one up in the editor
- Add a MultiMeshInstance3D to the scene.
- In the Inspector, give it a new MultiMesh resource. Set Transform Format to 3D, Mesh to the tree mesh, and Instance Count to how many trees.
- Each instance now needs a transform. The editor's Populate Surface tool, in the MultiMeshInstance3D's menu in the viewport toolbar, scatters instances over a target mesh such as your terrain, with random rotation and scale within ranges you set. For a hand-placed forest, set transforms from code instead.
Populating from code
A script on the MultiMeshInstance3D that scatters trees over a rectangle, with a random turn and a little variation in size:
extends MultiMeshInstance3D
@export var count := 800
@export var area := Vector2(200, 200)
func _ready() -> void:
multimesh.instance_count = count
var rng := RandomNumberGenerator.new()
rng.seed = 7
for i in count:
var t := Transform3D.IDENTITY
t = t.rotated(Vector3.UP, rng.randf() * TAU)
t = t.scaled(Vector3.ONE * rng.randf_range(0.85, 1.15))
t.origin = Vector3(rng.randf_range(-area.x, area.x) / 2, 0, rng.randf_range(-area.y, area.y) / 2)
multimesh.set_instance_transform(i, t)
Set the height of each origin from your terrain, by raycast or by sampling the heightmap, so the trees stand on it. The scale variation is what stops a forest looking like a grid; a turn about Y does the rest.
Colour per instance
Turn on Use Colors on the MultiMesh and call set_instance_color(i, colour) per tree. With a material that has Vertex Color Use as Albedo on, the colour multiplies the palette, so a range of slightly different greens comes free. This is the cheapest variety a forest can have.
Levels of detail
Each instance uses the mesh's automatic LODs, chosen per instance by distance, with nothing to set. For hand-made levels, make one MultiMeshInstance3D per level with the same transforms, and give each a Visibility Range so only one draws at a given distance; the Godot LOD article covers the ranges. A billboard level is a MultiMesh of quads with a billboard material.
Collision
A MultiMesh has no collision. For a forest the player walks through, add a CollisionShape3D per tree under one StaticBody3D, a capsule at each instance's origin, from the same loop that placed the trees; capsules are cheap enough for thousands. Or skip collision for the far forest and give it only to the trees near the path.
Where the add-ons take over
Painting trees onto terrain, thinning them along roads, following slopes: the scatter add-ons in the Asset Library do all of this on top of MultiMesh, and a terrain add-on usually comes with its own. Use them once the forest needs a brush; the code above is enough while it needs a loop.
What PolyMason exports
The tree builder writes one mesh with one material per tree, in metres, standing at the origin, which is exactly what a MultiMesh wants, and its levels of detail as separate files for a per-level MultiMesh set.
More in this guide
- Free low poly assets for GodotWhere to get free low poly models that work in Godot 4, what each source's licence allows, which formats to prefer, how to import an OBJ or GLB with its colours and flat shading intact, how to add a collider, and how to scatter a forest. The complete guide.
- Free low poly asset packs compared: Kenney, Quaternius, KayKit, Poly Pizza and the restThe free sources of low poly 3D models compared on licence, formats, style, size and what each is best for, with the paid ones for context, and where a builder fits beside them.
Or build a tree and see what comes out.