How to Use Matrix4 for Complex Transformations in Three.js

In Three.js, while basic translations, rotations, and scaling can be achieved using standard object properties, complex and nested transformations are best handled using the Matrix4 class. This article provides a clear, step-by-step guide on how to instantiate, manipulate, and apply a 4x4 transformation matrix directly to Three.js 3D objects, allowing you to combine multiple spatial operations into a single, efficient mathematical matrix.

Understanding Matrix4 in Three.js

A Matrix4 is a 4x4 matrix that represents a 3D transformation. It encodes three primary spatial transformations in a single entity: 1. Translation (position in 3D space) 2. Rotation (orientation) 3. Scale (size)

Using a matrix is highly efficient because multiple transformations can be combined (multiplied) together into a single matrix. This combined matrix can then be applied to an object or vertex in a single GPU operation.


Method 1: Applying Transformations via applyMatrix4

The simplest way to apply a Matrix4 to an object is using the Object3D.applyMatrix4() method. This method multiplies the object’s current transformation matrix with the new matrix, instantly updating the object’s position, rotation, and scale properties.

import * as THREE from 'three';

// Create a 3D object
const mesh = new THREE.Mesh(
  new THREE.BoxGeometry(1, 1, 1),
  new THREE.MeshBasicMaterial({ color: 0x00ff00 })
);

// Instantiate a new Matrix4
const matrix = new THREE.Matrix4();

// Define individual transformations
const translation = new THREE.Vector3(2, 0, 0);
const rotation = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI / 4);
const scale = new THREE.Vector3(1.5, 1.5, 1.5);

// Compose the transformations into the matrix
matrix.compose(translation, rotation, scale);

// Apply the matrix to the mesh
mesh.applyMatrix4(matrix);

Method 2: Manual Matrix Control (Disabling Auto-Updates)

By default, Three.js automatically recalculates an object’s local transformation matrix in every frame based on its position, rotation, and scale properties. If you want to define and animate an object purely using custom matrices, you must disable this automatic behavior by setting matrixAutoUpdate to false.

// Disable automatic matrix updates
mesh.matrixAutoUpdate = false;

// Create a custom transformation matrix
const customMatrix = new THREE.Matrix4();

// Example: Translate and Rotate manually
const translationMatrix = new THREE.Matrix4().makeTranslation(0, 5, 0);
const rotationMatrix = new THREE.Matrix4().makeRotationZ(Math.PI / 2);

// Combine matrices (order matters: Translation * Rotation)
customMatrix.multiplyMatrices(translationMatrix, rotationMatrix);

// Copy the custom matrix directly to the object's matrix
mesh.matrix.copy(customMatrix);

// Force Three.js to update the object's world matrix
mesh.updateMatrixWorld(true);

Combining Multiple Matrices (Matrix Multiplication)

When combining transformations, the order of multiplication is critical. Multiplying Matrix A by Matrix B (A.multiply(B)) yields a different result than multiplying Matrix B by Matrix A.

const finalMatrix = new THREE.Matrix4();

const stepOne = new THREE.Matrix4().makeRotationX(Math.PI / 4);
const stepTwo = new THREE.Matrix4().makeTranslation(0, 3, 0);

// stepTwo is applied relative to stepOne's local coordinate system
finalMatrix.multiplyMatrices(stepOne, stepTwo);

When to Use Matrix4

Using Matrix4 is ideal for: * Custom Pivots: Rotating an object around a specific point in space rather than its center. * Physics Engines: Syncing complex physics simulation matrices directly with Three.js visuals. * Hierarchical Systems: Creating complex robotic arms, solar systems, or joint structures where transformations depend on parent coordinates.