mrdoob/three.js · error

THREE.Matrix4.makePerspective(): Invalid coordinate system:

Error message

THREE.Matrix4.makePerspective(): Invalid coordinate system: ${coordinateSystem}

What it means

Thrown by Matrix4.makePerspective() when the coordinateSystem argument is neither WebGLCoordinateSystem nor WebGPUCoordinateSystem. The depth coefficients c and d differ between the two (WebGL uses a symmetric -1..1 z remap, WebGPU uses a 0..1 z remap); an unrecognized system has no valid projection formula, so building the matrix is aborted.

Source

Thrown at src/math/Matrix4.js:1178

			c = near / ( far - near );
			d = ( far * near ) / ( far - near );

		} else {

			if ( coordinateSystem === WebGLCoordinateSystem ) {

				c = - ( far + near ) / ( far - near );
				d = ( - 2 * far * near ) / ( far - near );

			} else if ( coordinateSystem === WebGPUCoordinateSystem ) {

				c = - far / ( far - near );
				d = ( - far * near ) / ( far - near );

			} else {

				throw new Error( 'THREE.Matrix4.makePerspective(): Invalid coordinate system: ' + coordinateSystem );

			}

		}

		te[ 0 ] = x;	te[ 4 ] = 0;	te[ 8 ] = a; 	te[ 12 ] = 0;
		te[ 1 ] = 0;	te[ 5 ] = y;	te[ 9 ] = b; 	te[ 13 ] = 0;
		te[ 2 ] = 0;	te[ 6 ] = 0;	te[ 10 ] = c; 	te[ 14 ] = d;
		te[ 3 ] = 0;	te[ 7 ] = 0;	te[ 11 ] = - 1;	te[ 15 ] = 0;

		return this;

	}

	/**
	 * Creates a orthographic projection matrix. This is used internally by
	 * {@link OrthographicCamera#updateProjectionMatrix}.

View on GitHub (pinned to da05705fa3)

Solutions

  1. Pass a valid coordinate system as the last argument: THREE.WebGLCoordinateSystem or THREE.WebGPUCoordinateSystem.
  2. Derive it from the active renderer: renderer.coordinateSystem.
  3. Ensure the referenced constant is imported and defined (not undefined).
  4. Match the system to the renderer that will consume the projection matrix.

Example fix

// before: coordinateSystem omitted/undefined
proj.makePerspective(-1, 1, 1, -1, 0.1, 100, undefined);

// after: explicit valid system
proj.makePerspective(-1, 1, 1, -1, 0.1, 100, THREE.WebGLCoordinateSystem);
Defensive patterns

Strategy: validation

Validate before calling

import { WebGLCoordinateSystem, WebGPUCoordinateSystem } from 'three';

function makePerspectiveSafe(m, l, r, t, b, near, far, coordinateSystem) {
  if (coordinateSystem !== WebGLCoordinateSystem && coordinateSystem !== WebGPUCoordinateSystem) {
    throw new Error('coordinateSystem must be WebGL or WebGPU');
  }
  return m.makePerspective(l, r, t, b, near, far, coordinateSystem);
}

Type guard

function isValidCoordinateSystem(cs) {
  return cs === THREE.WebGLCoordinateSystem || cs === THREE.WebGPUCoordinateSystem;
}

Prevention

When it happens

Trigger: Calling matrix.makePerspective(left, right, top, bottom, near, far, coordinateSystem) with a missing/null/custom coordinateSystem. Also when camera internals build a perspective matrix from a non-standard coordinateSystem field.

Common situations: Constructing a custom perspective matrix without specifying the coordinate system. Passing the renderer's coordinateSystem before it is initialized. Mixing a WebGPU depth convention with a WebGL-flagged matrix build. Typo'd or undefined constant reference.

Related errors


AI-assisted analysis of mrdoob/three.js@da05705fa3 (2026-08-12). Data as JSON: /api/errors/ddaf89d9ffbe2900. Report an issue: GitHub.