How to Update InstancedMesh Instance Matrix in Three.js
Working with InstancedMesh in Three.js allows you to
render thousands of identical geometries efficiently, but updating
individual instances requires a specific workflow. This article explains
how to safely modify the transformation matrix (position, rotation, and
scale) of a specific instance within an InstancedMesh and
ensure the changes render correctly on the GPU.
The Core Workflow
To modify the transformation matrix of a specific instance, you must
use the setMatrixAt method of the
InstancedMesh and then flag the instance matrix attribute
as needing an update.
The most reliable and performance-friendly way to generate a new
matrix is by using a temporary THREE.Object3D helper. This
avoids writing manual 4x4 matrix calculations.
Step 1: Create a Helper Object
Instantiate a single THREE.Object3D outside of your
render loop to act as a dummy. You will reuse this single object to
calculate matrices for all instances.
const dummy = new THREE.Object3D();Step 2: Apply Transformations and Set the Matrix
To update an instance at a specific index, set the position,
rotation, or scale on the dummy object, update its matrix, and pass it
to the InstancedMesh.
// Define the index of the instance you want to modify
const instanceId = 5;
// 1. Set the desired transformations on the dummy
dummy.position.set(10, 5, 0);
dummy.rotation.set(0, Math.PI / 4, 0);
dummy.scale.set(2, 2, 2);
// 2. Force the dummy to calculate its local transformation matrix
dummy.updateMatrix();
// 3. Apply the dummy's matrix to the specific instance
myInstancedMesh.setMatrixAt(instanceId, dummy.matrix);Step 3: Flag the Matrix for GPU Upload
Three.js does not automatically upload matrix changes to the GPU because doing so for every frame is computationally expensive. You must explicitly tell Three.js that the instance matrices have changed:
myInstancedMesh.instanceMatrix.needsUpdate = true;Note: You only need to set needsUpdate = true once
per frame, even if you modify multiple instances in that frame.
How to Modify an Existing Instance Matrix
If you need to adjust an existing instance’s current position (e.g., moving it slightly on the X-axis) rather than setting an absolute new position, you must retrieve, decompose, modify, and reapply the matrix.
const instanceId = 5;
const tempMatrix = new THREE.Matrix4();
// 1. Retrieve the current matrix of the instance
myInstancedMesh.getMatrixAt(instanceId, tempMatrix);
// 2. Decompose the matrix into position, quaternion, and scale
tempMatrix.decompose(dummy.position, dummy.quaternion, dummy.scale);
// 3. Modify the desired properties
dummy.position.x += 1.5; // Translate on the X axis
// 4. Recompose and apply the matrix
dummy.updateMatrix();
myInstancedMesh.setMatrixAt(instanceId, dummy.matrix);
// 5. Notify the renderer
myInstancedMesh.instanceMatrix.needsUpdate = true;Following this approach prevents memory leaks, avoids manually calculating matrix math, and ensures your CPU-side matrix modifications are correctly synchronized with the GPU.