InstancedBufferGeometry vs InstancedMesh in Three.js

This article explains the differences between InstancedBufferGeometry and InstancedMesh in Three.js, helping you understand when and how to use each approach. While both techniques are designed to optimize performance by rendering thousands of similar objects in a single draw call, they operate at different levels of abstraction and offer different degrees of control over your 3D scenes.

Understanding GPU Instancing

In 3D graphics, rendering thousands of individual objects (like grass blades, trees, or particles) individually can quickly bottleneck the CPU due to excessive draw calls. GPU instancing solves this by sending the geometry data to the GPU once and then drawing it multiple times with different parameters in a single draw call.

Three.js provides two primary ways to achieve this: InstancedMesh and InstancedBufferGeometry.

What is InstancedMesh?

InstancedMesh is a high-level, user-friendly class introduced in Three.js to make instancing easy to implement. It is a direct extension of the standard Mesh class.

With InstancedMesh, you define a single base geometry and a single material. You then define the number of instances you want. To manipulate individual instances, you use helper methods to modify their transformation matrices (position, rotation, and scale) and colors.

Key Features of InstancedMesh:

What is InstancedBufferGeometry?

InstancedBufferGeometry is a low-level API that extends BufferGeometry. It allows you to define custom instanced attributes using InstancedBufferAttribute.

Unlike InstancedMesh, which handles the transformation math behind the scenes, InstancedBufferGeometry requires you to write custom shaders (GLSL) using ShaderMaterial or customize existing materials using onBeforeCompile. You must manually write the vertex shader code to read your custom attributes and position each instance on the screen.

Key Features of InstancedBufferGeometry:

Key Differences

Feature InstancedMesh InstancedBufferGeometry
Level of Abstraction High-level (Easy to use) Low-level (Complex)
Material Support Works with all default materials Usually requires custom ShaderMaterial
Custom Attributes Limited to transform matrices and colors Unlimited custom attributes
Raycasting Support Built-in Requires manual implementation
Learning Curve Low High (requires GLSL knowledge)

When to Use Which?

Use InstancedMesh when:

Use InstancedBufferGeometry when: