← Back to Blog 3d-modeling

GPU Instancing in Unity, Unreal Engine 5, and Godot: Render Hundreds of Free 3D Assets Without Killing Performance

By BitSoul Team7/30/2026Updated 8/7/20265 min read49 views
GPU Instancing in Unity, Unreal Engine 5, and Godot: Render Hundreds of Free 3D Assets Without Killing Performance

You've done the fun part: downloaded a dozen free GLB environment props, scattered them across your scene—trees, barrels, rocks, crates—and hit Play. Then your frame rate collapses to 12 fps. This is the wall every indie dev hits when building a populated game world. GPU instancing is the fix, and it works in Unity, Unreal Engine 5, and Godot 4 with almost no code changes to your assets. Here's how to set it up in each engine and which asset properties to look for before you import.

What Is GPU Instancing and Why Your Scene Needs It

Without instancing, every object in your scene sends its own draw call to the GPU. Place 200 trees and you get 200 draw calls—each one carrying the full overhead of setting render state, uploading a transform matrix, and issuing the command. CPUs can't issue draw calls fast enough to keep up, so your GPU sits idle while the CPU scrambles. This CPU-side bottleneck is what tanks performance in densely populated scenes, not the polygon count itself.

GPU instancing solves this by batching all instances of the same mesh into a single draw call. You pass an array of transform matrices to the GPU in one shot. The GPU draws every instance in parallel, exactly what it's designed for. The result: 200 trees rendered from 1 draw call instead of 200. Combined with frustum culling (which most engines apply automatically), you can populate large environments with hundreds of props while keeping draw calls in the double digits.

For instancing to work, all instances must share the same mesh and the same material. That's why GLB files with a single mesh and a single PBR material are ideal candidates—they need zero preprocessing before instancing them. If an asset has separate mesh parts using different materials, each part still gets its own draw call per instance, which limits the gains.

What Is GPU Instancing and Why Your Scene Needs It — illustrated

GPU Instancing in Unity (URP and HDRP)

Unity enables GPU instancing per material. Open any material in the Inspector and check the Enable GPU Instancing checkbox. That's it for static meshes—Unity handles the rest when you place duplicates in the scene.

For runtime spawning (procedural environments, dungeon generators, scatter systems), use Graphics.DrawMeshInstanced or the newer Graphics.RenderMeshInstanced from the Unity 2022+ API:

```csharp
// Cache these outside the loop
Mesh mesh;
Material mat; // must have GPU Instancing enabled
Matrix4x4[] matrices = new Matrix4x4[instanceCount];

void Update()
{
// Populate matrices array with your transforms
Graphics.DrawMeshInstanced(mesh, 0, mat, matrices, instanceCount);
}
```

For large counts (over 1023 per batch), DrawMeshInstanced caps out. Switch to DrawMeshInstancedIndirect with a ComputeBuffer to handle unlimited counts—this is the right path for open-world scatter. Unity's SRP Batcher and GPU instancing are separate but complementary: the SRP Batcher handles materials sharing the same shader variant with different property values; GPU instancing handles truly identical materials on identical meshes. Enable both in URP Project Settings.

GPU Instancing in Unreal Engine 5: HISM and Nanite

UE5 gives you two instancing paths depending on asset complexity.

Hierarchical Instanced Static Mesh (HISM) is the classic approach. Add a HierarchicalInstancedStaticMeshComponent to any Actor, assign your Static Mesh asset, and call AddInstance() for each placement in the world:

```cpp
HISMComponent->AddInstance(FTransform(Rotation, Location, Scale));
```

HISM manages LOD switching per instance automatically—lower-poly versions swap in as the camera pulls back—so it pairs naturally with GLB files that include multiple LOD levels.

Nanite is UE5's virtual geometry system. Enable it per mesh in the Static Mesh Editor under Nanite Settings. Once enabled, the engine handles batching and level-of-detail automatically at the driver level, with no per-Actor instancing code required. Nanite works best for high-detail hero props and dense environment pieces where traditional LOD budgets fall short. For simple low-poly fill props, HISM is lighter and easier to control; for detailed hero assets, Nanite removes the need to manage LODs entirely.

GPU Instancing in Godot 4: MultiMeshInstance3D

Godot 4 uses the MultiMeshInstance3D node for instancing—a dedicated scene node rather than a material property. This keeps instancing explicit and easy to profile:

```gdscript
var mm = MultiMesh.new()
mm.transform_format = MultiMesh.TRANSFORM_3D
mm.mesh = preload("res://assets/my_prop.glb")
mm.instance_count = 500

for i in range(500):
var t = Transform3D()
t.origin = Vector3(randf_range(-50, 50), 0, randf_range(-50, 50))
mm.set_instance_transform(i, t)

$MultiMeshInstance3D.multimesh = mm
```

GPU Instancing in Godot 4: MultiMeshInstance3D — illustrated

MultiMeshInstance3D also supports per-instance color data via set_instance_color(). Randomizing the tint on rocks, barrels, or grass clumps adds enough visual variation that players won't notice repetition—and all 500 instances still share a single draw call. For scenes with very large instance counts (10,000+), pair MultiMesh with Godot's VisibilityNotifier3D or a custom frustum check to avoid processing off-screen instances.

Which Assets Instance Well? What to Look for in Free GLB Files

Not every free 3D model is instancing-friendly. Here's what to check before importing:

| Asset Property | Instancing-Friendly | Notes |
|---|---|---|
| Single mesh, single material | Yes | Ideal—one draw call when instanced |
| Multi-part mesh, shared material | Partial | Merge parts in Blender with Ctrl+J |
| Unique texture per instance | No | Breaks instancing entirely |
| LODs included | Yes | Pairs with HISM in UE5 automatically |
| Animated mesh | No | Needs GPU skinning or a custom shader |
| GLB with embedded textures | Yes | Self-contained, no path issues on import |

The best candidates are environment fill props: rocks, trees, grass clumps, barrels, crates, fence posts, and floor tiles—objects placed in bulk that don't need to differ individually. BitSoul's marketplace has 747 free GLB models focused exactly on this category. Download a rock scatter set or a barrel pack, check the submesh count in your engine's import inspector after loading (one submesh is what you want), and merge any multi-material meshes in Blender with Ctrl+J before final export.

Engine Comparison: GPU Instancing at a Glance

| Feature | Unity URP/HDRP | Unreal Engine 5 | Godot 4 |
|---|---|---|---|
| Setup complexity | Low (checkbox + API) | Low (HISM component) | Medium (MultiMesh API) |
| Max per batch | 1023 (standard API) | Unlimited (HISM) | Unlimited |
| LOD integration | Manual | Automatic (HISM) | Manual |
| High-poly path | LOD Groups | Nanite | LOD Groups |
| Per-instance variation | MaterialPropertyBlock | Custom data layers | Color + transform |
| Native GLB import | Unity 2022+ | Via plugin | Native |

GPU instancing is one of the highest-leverage performance improvements available for a populated game scene—and it costs almost nothing when your assets are already structured for it. Pick up a set of environment props from BitSoul's free GLB marketplace, drop them into a MultiMeshInstance3D, HISM component, or instanced material in Unity, then open your engine's profiler and watch the draw call count collapse. That's your 60 fps back.

Tags: unity unreal-engine-5 godot gpu-instancing 3d-performance game-development

Skip the modelling — download it instead

A free BitSoul account gets you 2 game-ready models every month plus 25 AI Engine credits to generate one of your own, no card required. Clean topology, PBR textures, and GLB downloads that drop straight into Unreal, Unity, Godot or Blender — plus OBJ and 3D-printable STL export.

Create a free account → Browse 846 models