Start · Sprachen · JavaScript · Referenz · WebGLRenderingContext.uniformMatrix[234]fv()

WebGLRenderingContext.uniformMatrix[234]fv()

Methode

Überträgt eine 2×2-, 3×3- oder 4×4-Matrix aus Gleitkommawerten an eine <code>uniform mat2/mat3/mat4</code>-Variable des aktuell aktiven Shader-Programms.

seit JavaScript WebGL 1.0 – Baseline: alle modernen Browser Kategorie: webapi

Signatur

WebGLRenderingContext.prototype.uniformMatrix[234]fv(location, transpose, value)

Beschreibung

Mit den Methoden uniformMatrix2fv(), uniformMatrix3fv() und uniformMatrix4fv() übergibst du Matrizen aus JavaScript an Uniform-Variablen der Typen mat2, mat3 und mat4 in GLSL-Shadern. Typische Einsatzfälle sind Projektions-, Kamera- (View) und Modellmatrizen (mat4) sowie Normalenmatrizen (mat3) für die Beleuchtung.

Die Werte werden in spaltenweiser Reihenfolge (column-major) erwartet, also so, wie auch Bibliotheken wie gl-matrix ihre Matrizen ablegen. Die Übertragung wirkt immer auf das Programm, das zuvor mit gl.useProgram() aktiviert wurde. Den Ort der Variablen ermittelst du einmalig mit gl.getUniformLocation() und speicherst ihn zwischen.

Ist die Uniform ein Array (z. B. uniform mat4 uBones[16]), kannst du mehrere Matrizen am Stück übergeben: Die Länge von value muss dann ein Vielfaches von 4, 9 bzw. 16 sein. In WebGL 2 stehen zusätzlich Überladungen mit srcOffset und srcLength sowie nicht-quadratische Varianten wie uniformMatrix3x4fv() zur Verfügung.

Parameter

Name Typ Default Beschreibung
$location Pflicht WebGLUniformLocation | null Ort der Uniform-Variablen, geliefert von gl.getUniformLocation(). Bei null wird der Aufruf stillschweigend ignoriert.
$transpose Pflicht boolean Ob die Matrix transponiert werden soll. In WebGL 1 muss der Wert false sein, sonst entsteht INVALID_VALUE. In WebGL 2 ist true erlaubt.
$value Pflicht Float32Array | Array<number> Matrixwerte in spaltenweiser Reihenfolge: 4 (mat2), 9 (mat3) oder 16 (mat4) Werte bzw. ein Vielfaches davon für Uniform-Arrays.
$srcOffset number 0 Nur WebGL 2: Startindex innerhalb von value.
$srcLength number 0 Nur WebGL 2: Anzahl der zu lesenden Elemente; 0 bedeutet bis zum Ende.

Rückgabewert

Typ
void
Beschreibung
Kein Rückgabewert. Fehler werden über gl.getError() gemeldet (z. B. INVALID_OPERATION bei falschem Uniform-Typ oder fehlendem aktivem Programm).

Beispiele

Projektionsmatrix (mat4) an den Vertex-Shader übergeben

const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl');

const vsSource = `
  attribute vec4 aPosition;
  uniform mat4 uProjection;
  void main() { gl_Position = uProjection * aPosition; }
`;
const fsSource = `
  precision mediump float;
  void main() { gl_FragColor = vec4(1.0, 0.5, 0.0, 1.0); }
`;

const compile = (type, src) => {
  const s = gl.createShader(type);
  gl.shaderSource(s, src);
  gl.compileShader(s);
  return s;
};
const program = gl.createProgram();
gl.attachShader(program, compile(gl.VERTEX_SHADER, vsSource));
gl.attachShader(program, compile(gl.FRAGMENT_SHADER, fsSource));
gl.linkProgram(program);
gl.useProgram(program);

// Perspektivische Projektion, spaltenweise abgelegt
const perspective = (fovy, aspect, near, far) => {
  const f = 1 / Math.tan(fovy / 2);
  const nf = 1 / (near - far);
  return new Float32Array([
    f / aspect, 0, 0, 0,
    0, f, 0, 0,
    0, 0, (far + near) * nf, -1,
    0, 0, 2 * far * near * nf, 0,
  ]);
};

const uProjection = gl.getUniformLocation(program, 'uProjection');
gl.uniformMatrix4fv(uProjection, false,
  perspective(Math.PI / 4, canvas.width / canvas.height, 0.1, 100));
console.log(gl.getError() === gl.NO_ERROR);
true

2D-Rotation mit mat2 pro Frame aktualisieren

// Annahme: program ist aktiv und enthält 'uniform mat2 uRotation;'
const uRotation = gl.getUniformLocation(program, 'uRotation');
const rot = new Float32Array(4); // einmal anlegen, wiederverwenden

const render = (time) => {
  const a = time / 1000;
  const c = Math.cos(a), s = Math.sin(a);
  // Spalte 1: (c, s), Spalte 2: (-s, c)
  rot.set([c, s, -s, c]);
  gl.uniformMatrix2fv(uRotation, false, rot);
  gl.clear(gl.COLOR_BUFFER_BIT);
  gl.drawArrays(gl.TRIANGLES, 0, 3);
  requestAnimationFrame(render);
};
requestAnimationFrame(render);

Normalenmatrix (mat3) und Uniform-Array von Matrizen

// GLSL: uniform mat3 uNormalMatrix; uniform mat4 uBones[2];
const uNormal = gl.getUniformLocation(program, 'uNormalMatrix');
const uBones = gl.getUniformLocation(program, 'uBones');

// Einheitsmatrix 3×3 als Normalenmatrix
gl.uniformMatrix3fv(uNormal, false, [
  1, 0, 0,
  0, 1, 0,
  0, 0, 1,
]);

// Zwei 4×4-Matrizen am Stück (32 Werte)
const identity = [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1];
const translateX = [1,0,0,0, 0,1,0,0, 0,0,1,0, 2,0,0,1];
gl.uniformMatrix4fv(uBones, false, new Float32Array([...identity, ...translateX]));
console.log(gl.getError());

// Wichtig · Fallstricke

  • transpose in WebGL 1: Nur false ist erlaubt; true erzeugt INVALID_VALUE. Transponiere die Matrix bei Bedarf selbst in JavaScript.
  • Spaltenweise Reihenfolge: Die Translation einer 4×4-Matrix steht in den Indizes 12–14, nicht 3, 7, 11. Wer zeilenweise denkt, erhält verzerrte oder falsch verschobene Geometrie.
  • Programm muss aktiv sein: Ohne vorheriges gl.useProgram() entsteht INVALID_OPERATION. Uniform-Werte gelten pro Programm und bleiben bis zur nächsten Änderung erhalten.
  • Typ und Länge müssen passen: uniformMatrix4fv auf eine mat3 oder eine Länge, die kein Vielfaches von 16 ist, führt zu INVALID_OPERATION bzw. INVALID_VALUE.
  • Wegoptimierte Uniforms: Nutzt der Shader die Variable nicht, liefert getUniformLocation() null und der Aufruf bewirkt nichts – ohne Fehlermeldung.
  • Performance: Lege Float32Arrays einmal an und verwende sie wieder, statt pro Frame neue Arrays zu erzeugen; Locations zwischenspeichern.
  • Kompatibilität: WebGL 1 wird von allen modernen Browsern unterstützt; srcOffset/srcLength und nicht-quadratische Varianten gibt es nur in WebGL2RenderingContext.