Signatur
Beschreibung
Die Methodenfamilie uniformMatrix2x3fv(), uniformMatrix2x4fv(), uniformMatrix3x2fv(), uniformMatrix3x4fv(), uniformMatrix4x2fv() und uniformMatrix4x3fv() überträgt Gleitkomma-Matrizen an nicht-quadratische Uniform-Variablen eines GLSL-ES-3.00-Shaders. Diese Matrixtypen gibt es erst ab WebGL 2; für quadratische Matrizen gibt es uniformMatrix2fv(), uniformMatrix3fv() und uniformMatrix4fv().
Die Namen folgen der GLSL-Schreibweise matCxR: Die erste Zahl steht für die Spalten, die zweite für die Zeilen. uniformMatrix2x3fv() gehört also zu einem mat2x3 (2 Spalten, 3 Zeilen) und erwartet pro Matrix 6 Werte. Die Werte werden standardmäßig spaltenweise (column-major) gelesen, d. h. zuerst alle Zeilen der ersten Spalte, dann der zweiten usw.
Typische Einsatzfälle sind platzsparende Transformationen: Eine affine 3D-Transformation (Rotation, Skalierung, Verschiebung) kommt ohne die letzte Zeile 0 0 0 1 aus und passt in ein mat4x3 (12 statt 16 Floats) – ideal etwa für Knochenmatrizen beim Skinning, wo Uniform-Speicher knapp ist. Ein mat3x2 reicht für affine 2D-Transformationen.
Die Methode wirkt immer auf das Programm, das zuvor mit gl.useProgram() aktiviert wurde. Mit srcOffset und srcLength lässt sich ein Ausschnitt aus einem größeren Float32Array übertragen, ohne ein neues Teil-Array anlegen zu müssen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $location Pflicht | WebGLUniformLocation | null | Position der Uniform-Variablen, ermittelt über gl.getUniformLocation(). Bei null wird der Aufruf stillschweigend ignoriert. |
|
| $transpose Pflicht | boolean | true, wenn die Daten zeilenweise (row-major) vorliegen und beim Hochladen transponiert werden sollen. In WebGL 2 ist – anders als in WebGL 1 – auch true erlaubt. |
|
| $data Pflicht | Float32Array | Array<number> | Die Matrixwerte. Die Länge muss ein Vielfaches der Elementanzahl sein (z. B. 6 für 2x3/3x2, 8 für 2x4/4x2, 12 für 3x4/4x3). Mehrere Matrizen hintereinander füllen ein Uniform-Array. |
|
| $srcOffset | number | 0 | Index in data, ab dem gelesen wird. |
| $srcLength | number | 0 | Anzahl der zu lesenden Werte. 0 bedeutet: alles ab srcOffset bis zum Ende von data. |
Rückgabewert
undefined). Fehler werden über gl.getError() gemeldet.Beispiele
mat3x2 für eine affine 2D-Transformation
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl2');
const vsSource = `#version 300 es
in vec2 aPos;
uniform mat3x2 uTransform; // 3 Spalten, 2 Zeilen
void main() {
vec2 p = uTransform * vec3(aPos, 1.0);
gl_Position = vec4(p, 0.0, 1.0);
}`;
const fsSource = `#version 300 es
precision mediump float;
out vec4 color;
void main() { color = 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); // Pflicht vor dem Setzen der Uniforms
// Rotation um 45° + Verschiebung (0.2, -0.1), spaltenweise
const a = Math.PI / 4;
const transform = new Float32Array([
Math.cos(a), Math.sin(a), // Spalte 0
-Math.sin(a), Math.cos(a), // Spalte 1
0.2, -0.1 // Spalte 2 (Translation)
]);
const loc = gl.getUniformLocation(program, 'uTransform');
gl.uniformMatrix3x2fv(loc, false, transform);
console.log(gl.getError() === gl.NO_ERROR);
Knochenmatrizen als mat4x3-Array mit srcOffset/srcLength
// Im Shader: uniform mat4x3 uBones[32];
const BONE_FLOATS = 12; // 4 Spalten × 3 Zeilen
const allBones = new Float32Array(64 * BONE_FLOATS); // Pool für 64 Knochen
// Einheitsmatrix (ohne letzte Zeile) für jeden Knochen setzen
for (let i = 0; i < 64; i++) {
allBones.set([1,0,0, 0,1,0, 0,0,1, 0,0,0], i * BONE_FLOATS);
}
const uploadBones = (gl, program, firstBone, count) => {
gl.useProgram(program);
const loc = gl.getUniformLocation(program, 'uBones');
// Nur einen Ausschnitt übertragen – ohne subarray()-Kopie
gl.uniformMatrix4x3fv(
loc,
false,
allBones,
firstBone * BONE_FLOATS,
count * BONE_FLOATS
);
};
// z. B. Knochen 16–47 für das aktuelle Mesh
// uploadBones(gl, skinProgram, 16, 32);
Zeilenweise Daten mit transpose = true
// Im Shader: uniform mat2x3 uM; (2 Spalten, 3 Zeilen)
// Daten liegen mathematisch lesbar zeilenweise vor (2 Werte pro Zeile):
const rowMajor = new Float32Array([
1, 2, // Zeile 0
3, 4, // Zeile 1
5, 6 // Zeile 2
]);
// WebGL 2 transponiert beim Hochladen – in WebGL 1 wäre true ein Fehler
gl.useProgram(program);
gl.uniformMatrix2x3fv(gl.getUniformLocation(program, 'uM'), true, rowMajor);
// Kontrolle: getUniform liefert immer spaltenweise
console.log(Array.from(gl.getUniform(program, gl.getUniformLocation(program, 'uM'))));