Signatur
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
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);
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
falseist erlaubt;trueerzeugtINVALID_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()entstehtINVALID_OPERATION. Uniform-Werte gelten pro Programm und bleiben bis zur nächsten Änderung erhalten. - Typ und Länge müssen passen:
uniformMatrix4fvauf einemat3oder eine Länge, die kein Vielfaches von 16 ist, führt zuINVALID_OPERATIONbzw.INVALID_VALUE. - Wegoptimierte Uniforms: Nutzt der Shader die Variable nicht, liefert
getUniformLocation()nullund 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/srcLengthund nicht-quadratische Varianten gibt es nur inWebGL2RenderingContext.