Signatur
Beschreibung
Die Eigenschaft size eines WebGLActiveInfo-Objekts gibt an, wie viele Elemente die Variable hat, gemessen in Einheiten ihres Typs (type). Für eine einfache Variable wie uniform vec3 uColor; ist size gleich 1. Bei einem Array wie uniform mat4 uBones[32]; steht dort die Array-Länge, in diesem Fall 32.
Wichtig: size ist nicht die Größe in Bytes und auch nicht die Anzahl der Komponenten. Ein vec4 hat size === 1. Die Komponenten ergeben sich aus type (z. B. gl.FLOAT_VEC4). Wer die Gesamtzahl der Gleitkommawerte braucht, rechnet size × Komponenten des Typs.
In der Praxis nutzt man size vor allem beim Untersuchen eines gelinkten Shader-Programms, also bei der Introspektion: Man baut automatisch Tabellen mit Uniform-Positionen auf, prüft Array-Längen oder schreibt generische Material- und Debug-Werkzeuge, die jede aktive Variable kennen müssen.
Rückgabewert
GLint): 1 für Variablen, die kein Array sind, sonst die Anzahl der aktiv genutzten Array-Elemente.Beispiele
Größe eines Uniform-Arrays abfragen
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl');
const vsSource = `
attribute vec4 aPosition;
uniform mat4 uBones[4];
void main() {
gl_Position = uBones[0] * uBones[1] * uBones[2] * uBones[3] * aPosition;
}`;
const fsSource = `
precision mediump float;
uniform vec3 uColor;
void main() { gl_FragColor = vec4(uColor, 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);
const count = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
for (let i = 0; i < count; i++) {
const info = gl.getActiveUniform(program, i);
console.log(info.name, info.size);
}
Aktive Attribute auflisten
const listAttributes = (gl, program) => {
const count = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES);
return Array.from({ length: count }, (_, i) => {
const { name, size, type } = gl.getActiveAttrib(program, i);
return { name, size, type, location: gl.getAttribLocation(program, name) };
});
};
// Aufruf mit dem Programm aus dem vorherigen Beispiel
console.table(listAttributes(gl, program));
Anzahl der Floats für ein Uniform-Array berechnen
const COMPONENTS = {
[WebGLRenderingContext.FLOAT]: 1,
[WebGLRenderingContext.FLOAT_VEC2]: 2,
[WebGLRenderingContext.FLOAT_VEC3]: 3,
[WebGLRenderingContext.FLOAT_VEC4]: 4,
[WebGLRenderingContext.FLOAT_MAT3]: 9,
[WebGLRenderingContext.FLOAT_MAT4]: 16,
};
const buildUniformTable = (gl, program) => {
const table = new Map();
const count = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
for (let i = 0; i < count; i++) {
const info = gl.getActiveUniform(program, i);
const baseName = info.name.replace(/\[0\]$/, '');
table.set(baseName, {
location: gl.getUniformLocation(program, info.name),
floats: (COMPONENTS[info.type] ?? 0) * info.size,
});
}
return table;
};
const uniforms = buildUniformTable(gl, program);
console.log(uniforms.get('uBones').floats);
// Wichtig · Fallstricke
- Keine Byte-Größe:
sizezählt Elemente vom Typtype, keine Bytes und keine Komponenten. Einmat4ohne Array hatsize === 1. - Optimierung durch den Treiber: Der GLSL-Compiler kann ungenutzte hintere Array-Elemente entfernen.
sizegibt dann nur die höchste tatsächlich genutzte Position + 1 an und kann kleiner sein als die deklarierte Länge. Uniforms oder Attribute, die gar nicht genutzt werden, fehlen ganz. - Array-Namen: Bei Arrays endet
namein der Regel auf[0]. Für den Zugriff auf weitere Elemente fragt man die Position übergetUniformLocation(program, 'uBones[2]')ab. - Nur lesbar: Zuweisungen werden ignoriert; im Strict Mode lösen sie einen
TypeErroraus. - Kompatibilität: Wird in allen modernen Browsern mit WebGL 1 und WebGL 2 unterstützt. In WebGL 2 liefert auch
getTransformFeedbackVarying()einWebGLActiveInfo-Objekt mitsize. Ist das Programm nicht gelinkt oder der Index ungültig, wirdnullzurückgegeben. Den Wert deshalb vor dem Zugriff aufsizeprüfen.