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
- Pass a valid coordinate system as the last argument: THREE.WebGLCoordinateSystem or THREE.WebGPUCoordinateSystem.
- Derive it from the active renderer: renderer.coordinateSystem.
- Ensure the referenced constant is imported and defined (not undefined).
- 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
- Always pass the coordinateSystem argument; do not rely on a default.
- Source it from renderer.coordinateSystem to match the depth convention.
- Confirm the constant import resolves to a number (not undefined).
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
- THREE.Matrix4.makeOrthographic(): Invalid coordinate system:
- THREE.CubeCamera.updateCoordinateSystem(): Invalid coordinat
- THREE.CameraHelper.update(): Invalid coordinate system: ${th
- THREE.Frustum.setFromProjectionMatrix(): Invalid coordinate
- THREE.BufferAttribute: array should be a Typed Array.
AI-assisted analysis of mrdoob/three.js@da05705fa3 (2026-08-12).
Data as JSON: /api/errors/ddaf89d9ffbe2900.
Report an issue: GitHub.