@pixi/3d
    Preparing search index...

    Class Matrix4

    A 4x4 matrix for 3D transforms and projections

    Matrix4#elements holds the sixteen values column by column, the order shaders use, and a Matrix4 can be the value of a mat4x4<f32> uniform as it is. Points are columns, so in a * b the matrix b applies to a point first: projection * view * world takes a point on a model to clip space.

    Methods that change the matrix do so in place, or write into an out matrix when you pass one and leave this matrix as it is.

    const cameraWorld = new Matrix4().lookAt(eye, target, { x: 0, y: 1, z: 0 }).setPosition(eye);
    const view = new Matrix4().getInverse(cameraWorld);
    const projection = new Matrix4().makePerspective(Math.PI / 3, width / height, 0.1, 500);
    const viewProjection = new Matrix4().multiplyMatrices(projection, view);

    Vector3#applyMatrix4 For applying this matrix to a point

    Index
    • Creates a new Matrix4, defaulting to the identity matrix

      Parameters

      • Optionalelements: TypedFixedArray<16>

        Optional column-major Float32Array of 16 floats, used as is rather than copied. Its byte offset must be a multiple of 8, or this throws, since Matrix4#elements64 views the same memory.

      Returns Matrix4

    array: Float32Array<ArrayBufferLike> | null = null

    The array Matrix4#toArray writes into when given no out; null until its first call

    worldMatrix.toArray(true);
    const rowMajor = worldMatrix.array!;
    null
    @advanced
    elements: TypedFixedArray<16>

    The sixteen values, column by column: the translation sits at indices 12, 13 and 14

    const worldHeight = mesh.worldTransform.elements[13];
    
    elements64: Float64Array

    A Float64Array over the same memory as Matrix4#elements, for copying the matrix as eight 64-bit moves instead of sixteen 32-bit ones

    Important

    Each entry is two of the matrix's floats read as one 64-bit number, which means nothing on its own. Use it only to copy into another Float64Array view of float data.

    const instanceData = new Float32Array(instanceCount * 16);
    const instanceData64 = new Float64Array(instanceData.buffer);

    instanceData64.set(mesh.worldTransform.elements64, index * 8);
    • get IDENTITY(): Readonly<Matrix4>

      A read-only identity matrix

      Important

      This is a shared instance; do not mutate it. Use Matrix4.shared when you need a writable temporary.

      Returns Readonly<Matrix4>

      const atRest = bone.localTransform.equals(Matrix4.IDENTITY);
      
    • get shared(): Matrix4

      A shared Matrix4, reset to identity on every access, for a one-off calculation

      Important

      This matrix is shared and temporary. Do not store references to it.

      Returns Matrix4

      localHit.copyFrom(worldHit).applyMatrix4(Matrix4.shared.getInverse(mesh.worldTransform));
      
    • Pixi-style alias for Matrix4#multiply: this = this * m

      Parameters

      • m: Matrix4

        Matrix to append

      • out: Matrix4 = ...

        Optional target; defaults to writing into this matrix

      Returns this

      The matrix the result was written to

      gun.worldTransform.append(muzzleOffset, muzzleWorld);
      
    • Alias for Matrix4#multiplyMatrices: this matrix becomes a * b

      Parameters

      • a: Matrix4

        Left operand

      • b: Matrix4

        Right operand

      • out: Matrix4 = ...

        Optional target; defaults to writing into this matrix

      Returns this

      The matrix the result was written to

      viewProjection.appendFrom(camera.projection, camera.view);
      
    • Creates a new Matrix4 with the same elements

      Returns Matrix4

      The new matrix

      const restPose = bone.localTransform.clone();
      
    • Composes this matrix from a translation, rotation and scale

      A point is scaled first, then rotated, then moved: the order a Container3D builds its Container3D#localTransform in.

      Parameters

      • position: PointData3D

        Translation component

      • quaternion: Quaternion

        Rotation component

      • scale: PointData3D

        Scale component

      • out: Matrix4 = ...

        Optional target; defaults to writing into this matrix

      Returns this

      The matrix the result was written to

      const instance = new Matrix4();
      const unitScale = { x: 1, y: 1, z: 1 };

      for (let i = 0; i < treeCount; i++) {
      instance.compose(treePositions[i], treeRotations[i], unitScale);
      instanceData.set(instance.elements, i * 16);
      }
    • Copies the elements of m into this matrix

      Parameters

      Returns this

      This matrix

      previousWorld.copyFrom(mesh.worldTransform);
      
    • Copies this matrix's elements into target

      Type Parameters

      Parameters

      • target: T

        Matrix to copy into

      Returns T

      The given target matrix

      mesh.worldTransform.copyTo(previousWorld);
      
    • Splits this matrix into a translation, rotation and scale

      A mirroring matrix (negative determinant) comes back with a negative X scale, so the rotation stays a rotation. A sheared matrix has no exact split; the result only approximates it.

      Parameters

      • position: Vector3

        Receives the translation component

      • quaternion: Quaternion

        Receives the rotation component

      • scale: Vector3

        Receives the scale component

      • out: Matrix4 = ...

        Matrix that receives a copy of this one first; decomposing changes no matrix

      Returns this

      out, which is this matrix when omitted

      const position = new Vector3();
      const rotation = new Quaternion();
      const scale = new Vector3();

      mesh.worldTransform.decompose(position, rotation, scale);
    • Computes the determinant of this matrix

      Negative when the transform mirrors, as a negative scale does, and 0 when it flattens a dimension and can't be inverted.

      Returns number

      The determinant

      const mirrored = mesh.worldTransform.determinant() < 0;
      
    • Checks whether all 16 elements of this matrix match m exactly, with no tolerance

      Parameters

      • m: Matrix4

        Matrix to compare against

      Returns boolean

      True when every element matches

      const moved = !mesh.worldTransform.equals(previousWorld);
      
    • Writes the three basis vectors of this matrix into xAxis, yAxis and zAxis

      They are the first three columns: the matrix's own axes, scale included.

      Parameters

      • xAxis: Vector3

        Receives the X basis vector

      • yAxis: Vector3

        Receives the Y basis vector

      • zAxis: Vector3

        Receives the Z basis vector

      • out: Matrix4 = ...

        Optional matrix that receives a copy of this matrix first

      Returns this

      The matrix the basis was read from

      const right = new Vector3();
      const up = new Vector3();
      const back = new Vector3();

      camera.worldTransform.extractBasis(right, up, back);
    • Writes the negated Z column (forward direction, length 1) into out

      That is the way a Camera3D or a light faces. Other Container3Ds, such as meshes, face +Z, so for them this points backwards.

      Type Parameters

      Parameters

      • out: T

        Point that receives the direction

      Returns T

      The given output point

      const aim = camera.worldTransform.extractForward(new Vector3());
      
    • Writes the translation column into out

      Type Parameters

      Parameters

      • out: T

        Point that receives the translation

      Returns T

      The given output point

      const worldPosition = mesh.worldTransform.extractPosition(new Vector3());
      
    • Writes the X column (right direction, length 1) into out

      Type Parameters

      Parameters

      • out: T

        Point that receives the direction

      Returns T

      The given output point

      camera.worldTransform.extractRight(right);
      player.position.addScaledVector(right, strafeSpeed);
    • Sets this matrix to m with each axis scaled to unit length and the translation cleared

      That removes only the scale: a mirroring matrix (negative determinant) gives a mirrored result, and shear stays.

      Parameters

      • m: Matrix4

        Matrix to extract the rotation from

      • out: Matrix4 = ...

        Optional target; defaults to writing into this matrix

      Returns this

      The matrix the result was written to

      const rotationOnly = new Matrix4().extractRotation(mesh.worldTransform);
      
    • Writes the per-axis scale (column magnitudes) into out

      The lengths are never negative, so a mirrored axis reads as a positive scale; Matrix4#decompose reports the mirror.

      Type Parameters

      Parameters

      • out: T

        Point that receives the scale

      Returns T

      The given output point

      const worldScale = mesh.worldTransform.extractScale(new Vector3());
      
    • Writes the Y column (up direction, length 1) into out

      Type Parameters

      Parameters

      • out: T

        Point that receives the direction

      Returns T

      The given output point

      drone.worldTransform.extractUp(thrustDirection);
      
    • Reads the 16 elements from array (column-major) starting at offset

      Parameters

      • array: ArrayLike<number>

        Source array of column-major elements

      • offset: number = 0

        Index of the first element to read

      Returns this

      This matrix

      const instanceMatrix = new Matrix4().fromArray(instanceData, index * 16);
      
    • Sets this matrix to the inverse of m

      When m can't be inverted (its determinant is 0), the result is the identity and a warning is logged.

      Parameters

      • m: Matrix4

        Matrix to invert

      • OptionalthrowOnDegenerate: boolean

        true throws instead of warning when m can't be inverted

      • out: Matrix4 = ...

        Optional target; defaults to writing into this matrix

      Returns this

      The matrix the result was written to

      const worldToLocal = new Matrix4().getInverse(mesh.worldTransform);
      
    • Computes the largest of the three axis scales: the length of the longest of the first three columns

      Scaling a bounding radius by it covers rotation and per-axis scale. Under shear, as when a non-uniformly scaled parent holds a rotated child, the matrix can stretch some other direction further; Matrix4#getMaxSingularValueSq measures that.

      Returns number

      The largest axis scale

      const worldRadius = localRadius * mesh.worldTransform.getMaxScaleOnAxis();
      
    • Largest singular value of the upper-left 3x3, squared: the square of the most this matrix stretches any direction

      A bounding radius scaled by its square root covers the transformed shape even under shear, where Matrix4#getMaxScaleOnAxis can fall short; without shear, it's the square of that. It comes back squared so a comparison against squared distances skips a square root.

      Returns number

      const worldRadius = localRadius * Math.sqrt(mesh.worldTransform.getMaxSingularValueSq());
      
    • Resets this matrix to the identity matrix

      Returns this

      This matrix

      transform.identity().setPosition(spawnPoint);
      
    • Checks whether this matrix equals the identity matrix exactly

      Returns boolean

      True when every element matches the identity matrix

      const untouched = node.localTransform.isIdentity();
      
    • Sets this matrix's rotation so its -Z axis points from eye toward target, with its +Y axis as close to up as it can be

      That turns a camera at eye to face target. Only the rotation part is written; the translation and bottom row stay (copied into out first when it is another matrix). Set the position and invert the result to get the camera's view matrix. When up lies along the view direction, the direction is nudged slightly so the result is still a rotation.

      Parameters

      Returns this

      The matrix the result was written to

      const cameraWorld = new Matrix4().lookAt(eye, target, { x: 0, y: 1, z: 0 }).setPosition(eye);
      const view = new Matrix4().getInverse(cameraWorld);
    • Sets this matrix using the three basis vectors as its columns, with no translation

      Unit-length axes at right angles to each other make a rotation when zAxis is xAxis cross yAxis, and a mirror when it points the other way.

      Parameters

      Returns this

      This matrix

      const orientation = new Matrix4().makeBasis(right, up, back);
      
    • Sets this matrix to an orthographic projection of the box between the given planes, for a camera looking down -Z

      top comes before bottom in the arguments. Clip-space depth runs from -1 at near to 1 at far, as with Matrix4#makePerspective.

      Parameters

      • left: number

        Left clip plane

      • right: number

        Right clip plane

      • top: number

        Top clip plane

      • bottom: number

        Bottom clip plane

      • near: number

        Near clip distance

      • far: number

        Far clip distance

      Returns this

      This matrix

      const shadowProjection = new Matrix4().makeOrthographic(-20, 20, 20, -20, 0.5, 100);
      
    • Sets this matrix to a perspective projection from a vertical field-of-view (radians), for a camera looking down -Z

      Clip-space depth runs from -1 at near to 1 at far, as WebGL expects, and Camera3D#projection is built the same way. On WebGPU, whose depth runs from 0 to 1, the renderer remaps the copy it draws with, but a matrix you bind yourself, the camera's included, needs the same remap. fovy is in radians, unlike Camera3D#fov, which is in degrees.

      Parameters

      • fovy: number

        Vertical field-of-view in radians

      • aspect: number

        Viewport width / height

      • near: number

        Near clip distance

      • Optionalfar: number

        Far clip distance; leave it out or pass Infinity for no far plane

      Returns this

      This matrix

      const projection = new Matrix4().makePerspective(Math.PI / 3, width / height, 0.1, 500);
      
    • Sets this matrix to a rotation of angle radians around axis

      Positive angles turn counter-clockwise as seen from the tip of axis, like the single-axis methods.

      Parameters

      • axis: PointData3D

        Unit-length rotation axis

      • angle: number

        Rotation angle in radians

      Returns this

      This matrix

      const wobble = new Matrix4().makeRotationAxis(new Vector3(1, 0, 1).normalize(), 0.2);
      
    • Sets this matrix to a rotation derived from XYZ Euler angles in rotation (radians)

      The matrix is Rx * Ry * Rz, the convention Container3D#rotation and Quaternion#setFromEuler use, so the same angles give the same orientation.

      Parameters

      Returns this

      This matrix

      const facing = new Matrix4().makeRotationFromEuler({ x: 0, y: Math.PI / 2, z: 0 });
      
    • Sets this matrix to a rotation derived from the quaternion q

      Parameters

      Returns this

      This matrix

      const quarterTurn = new Quaternion().setFromAxisAngle({ x: 0, y: 1, z: 0 }, Math.PI / 2);
      const rotation = new Matrix4().makeRotationFromQuaternion(quarterTurn);
    • Sets this matrix to a rotation of theta radians around the X axis; positive angles turn +Y toward +Z

      Parameters

      • theta: number

        Rotation angle in radians

      Returns this

      This matrix

      const layFlat = new Matrix4().makeRotationX(-Math.PI / 2);
      
    • Sets this matrix to a rotation of theta radians around the Y axis; positive angles turn +Z toward +X

      Parameters

      • theta: number

        Rotation angle in radians

      Returns this

      This matrix

      const heading = new Matrix4().makeRotationY(yaw);
      
    • Sets this matrix to a rotation of theta radians around the Z axis; positive angles turn +X toward +Y

      Parameters

      • theta: number

        Rotation angle in radians

      Returns this

      This matrix

      const roll = new Matrix4().makeRotationZ(bankAngle);
      
    • Sets this matrix to a scale by (x, y, z); a negative factor mirrors that axis

      Parameters

      • x: number

        Scale along x

      • y: number

        Scale along y

      • z: number

        Scale along z

      Returns this

      This matrix

      const mirrorX = new Matrix4().makeScale(-1, 1, 1);
      
    • Sets this matrix to a shear, where each factor adds that multiple of a point's coordinate on its axis to the point's other two coordinates

      With y = 0.2, a point 1 unit up moves 0.2 along both x and z. To shear one axis only, write the matrix with Matrix4#set.

      Parameters

      • x: number

        How much a point's x adds to its y and z

      • y: number

        How much a point's y adds to its x and z

      • z: number

        How much a point's z adds to its x and y

      Returns this

      This matrix

      const lean = new Matrix4().makeShear(0, 0.2, 0);
      
    • Sets this matrix to a pure translation by (x, y, z)

      Parameters

      • x: number

        Translation along x

      • y: number

        Translation along y

      • z: number

        Translation along z

      Returns this

      This matrix

      const eyeOffset = new Matrix4().makeTranslation(0, 1.7, 0);
      
    • Multiplies this matrix by m: this = this * m, so m applies to a point first

      Parameters

      • m: Matrix4

        Matrix to multiply by

      • out: Matrix4 = ...

        Optional target; defaults to writing into this matrix

      Returns this

      The matrix the result was written to

      const muzzleWorld = new Matrix4();

      gun.worldTransform.multiply(muzzleOffset, muzzleWorld);
    • Sets this matrix to a * b, so b applies to a point first

      Parameters

      • a: Matrix4

        Left operand

      • b: Matrix4

        Right operand

      • out: Matrix4 = ...

        Optional target; defaults to writing into this matrix

      Returns this

      The matrix the result was written to

      const toClip = new Matrix4().multiplyMatrices(camera.viewProjection, mesh.worldTransform);
      
    • Advanced

      Multiplies every element of this matrix by the scalar s

      Parameters

      • s: number

        Scalar to multiply by

      • out: Matrix4 = ...

        Optional target; defaults to writing into this matrix

      Returns this

      The matrix the result was written to

    • Pre-multiplies this matrix by m: this = m * this, so m applies to a point last

      Parameters

      • m: Matrix4

        Matrix to pre-multiply by

      • out: Matrix4 = ...

        Optional target; defaults to writing into this matrix

      Returns this

      The matrix the result was written to

      const spin = new Matrix4().makeRotationY(0.01);

      app.ticker.add(() => orbit.premultiply(spin));
    • Pixi-style alias for Matrix4#premultiply: this = m * this

      Parameters

      • m: Matrix4

        Matrix to prepend

      • out: Matrix4 = ...

        Optional target; defaults to writing into this matrix

      Returns this

      The matrix the result was written to

      orbit.prepend(spin);
      
    • Scales this matrix along its own axes by (v.x, v.y, v.z)

      Multiplies the first three columns, which is the same as multiplying by Matrix4#makeScale on the right: the scale applies to a point first.

      Parameters

      • v: PointData3D

        Per-axis scale factors

      • out: Matrix4 = ...

        Optional target; defaults to writing into this matrix

      Returns this

      The matrix the result was written to

      const doubled = mesh.worldTransform.clone().scale({ x: 2, y: 2, z: 2 });
      
    • Sets the 16 elements from arguments given row by row, as the matrix is written on paper

      Parameters

      • n11: number

        Row 1, column 1

      • n12: number

        Row 1, column 2

      • n13: number

        Row 1, column 3

      • n14: number

        Row 1, column 4

      • n21: number

        Row 2, column 1

      • n22: number

        Row 2, column 2

      • n23: number

        Row 2, column 3

      • n24: number

        Row 2, column 4

      • n31: number

        Row 3, column 1

      • n32: number

        Row 3, column 2

      • n33: number

        Row 3, column 3

      • n34: number

        Row 3, column 4

      • n41: number

        Row 4, column 1

      • n42: number

        Row 4, column 2

      • n43: number

        Row 4, column 3

      • n44: number

        Row 4, column 4

      Returns this

      This matrix

      const shearX = new Matrix4().set(
      1, 0.5, 0, 0,
      0, 1, 0, 0,
      0, 0, 1, 0,
      0, 0, 0, 1,
      );
    • Writes (v.x, v.y, v.z) into the translation column of this matrix, leaving the rest intact

      Parameters

      • v: PointData3D

        Position to write

      • out: Matrix4 = ...

        Optional target; defaults to writing into this matrix

      Returns this

      The matrix the result was written to

      const spawn = new Matrix4().makeRotationY(heading).setPosition(spawnPoint);
      
    • Writes this matrix's elements into a Float32Array

      Without out, writes into and returns Matrix4#array.

      Parameters

      • Optionaltranspose: boolean

        true writes row-major instead of column-major

      • Optionalout: Float32Array<ArrayBufferLike>

        Optional destination array

      Returns Float32Array

      The populated array

      const rowMajor = new Float32Array(16);

      mesh.worldTransform.toArray(true, rowMajor);
    • Advanced

      Formats this matrix as a readable row-by-row string

      Returns string

      The string representation

    • Transposes this matrix

      Parameters

      • out: Matrix4 = ...

        Optional target; defaults to writing into this matrix

      Returns this

      The matrix the result was written to

      const normalMatrix = new Matrix4().getInverse(mesh.worldTransform).transpose();
      
    • Advanced

      Multiplies two affine matrices held in flat arrays, out = a * b, skipping the bottom row

      Reads only the top three rows of a and b and writes 0, 0, 0, 1 as the bottom row, so it does 36 multiplies where a full 4x4 product does 64. out may be the same array as a or b.

      Parameters

      • out: Float32Array

        Buffer receiving the product

      • outOffset: number

        Index of the product's first element in out

      • a: Float32Array

        Buffer holding the left operand

      • aOffset: number

        Index of the left operand's first element in a

      • b: Float32Array

        Buffer holding the right operand

      • bOffset: number

        Index of the right operand's first element in b

      Returns void

      for (let i = 0; i < nodeCount; i++) {
      Matrix4.multiplyAffine(worlds, i * 16, worlds, parentIndices[i] * 16, locals, i * 16);
      }
    • Advanced

      Multiplies two affine matrices, out = a * b, and writes the result as three rows of four

      The rows land as [m00 m01 m02 m03][m10 m11 m12 m13][m20 m21 m22 m23], translation last in each, so a shader can read them as three vec4s and transform a point with three dot products. The bottom rows of a and b are never read.

      Parameters

      • out: Float32Array

        Destination, 12 floats per entry.

      • outOffset: number

        Float offset of the destination entry.

      • a: Float32Array

        Left operand, 16 floats per entry (column-major).

      • aOffset: number

        Float offset of the left entry.

      • b: Float32Array

        Right operand, 16 floats per entry (column-major).

      • bOffset: number

        Float offset of the right entry.

      Returns void

      const boneRows = new Float32Array(boneCount * 12);

      for (let i = 0; i < boneCount; i++) {
      Matrix4.multiplyAffineTo3x4(boneRows, i * 12, boneWorlds, i * 16, inverseBinds, i * 16);
      }