Signatur
Beschreibung
getActiveUniformBlockName() gibt den im GLSL-Shader deklarierten Namen eines Uniform-Blocks (Uniform Buffer Object, UBO) zurück. Uniform-Blöcke gibt es erst ab WebGL 2 (GLSL ES 3.00, #version 300 es). Mit ihnen fasst man mehrere Uniforms, etwa Kamera-Matrizen oder Lichtparameter, in einem Puffer zusammen, den sich mehrere Programme teilen können.
Man braucht die Methode vor allem zur Introspektion: Man fragt über getProgramParameter(program, gl.ACTIVE_UNIFORM_BLOCKS) die Anzahl der aktiven Blöcke ab, durchläuft die Indizes von 0 bis Anzahl - 1 und liest für jeden Index den Namen aus. So kann eine Engine Blöcke automatisch den passenden Binding-Points zuordnen, ohne die Namen fest im Code zu hinterlegen.
Der Weg geht auch umgekehrt: Kennt man den Namen schon, liefert getUniformBlockIndex() den Index dazu. Weitere Eigenschaften eines Blocks (Datengröße, Anzahl der Uniforms, Binding) liest man mit getActiveUniformBlockParameter() aus.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $program Pflicht | WebGLProgram | Das erfolgreich gelinkte Programm, dessen Uniform-Blöcke abgefragt werden. | |
| $uniformBlockIndex Pflicht | GLuint (number) | Index des aktiven Uniform-Blocks, zwischen 0 und gl.getProgramParameter(program, gl.ACTIVE_UNIFORM_BLOCKS) - 1. |
Rückgabewert
null zurück und setzt den Fehler gl.INVALID_VALUE.Beispiele
Alle Uniform-Blöcke eines Programms auflisten
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl2');
const vsSource = `#version 300 es
layout(std140) uniform Camera {
mat4 view;
mat4 projection;
};
layout(std140) uniform Model {
mat4 world;
};
in vec4 position;
void main() {
gl_Position = projection * view * world * position;
}`;
const fsSource = `#version 300 es
precision highp float;
out vec4 color;
void main() { color = vec4(1.0); }`;
const compile = (type, src) => {
const shader = gl.createShader(type);
gl.shaderSource(shader, src);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
throw new Error(gl.getShaderInfoLog(shader));
}
return shader;
};
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_UNIFORM_BLOCKS);
for (let i = 0; i < count; i++) {
console.log(i, gl.getActiveUniformBlockName(program, i));
}
Blöcke automatisch an Binding-Points binden
// Annahme: gl und ein gelinktes program existieren bereits
const bindingPoints = { Camera: 0, Model: 1, Lights: 2 };
const count = gl.getProgramParameter(program, gl.ACTIVE_UNIFORM_BLOCKS);
for (let i = 0; i < count; i++) {
const name = gl.getActiveUniformBlockName(program, i);
const binding = bindingPoints[name];
if (binding === undefined) {
console.warn(`Unbekannter Uniform-Block: ${name}`);
continue;
}
gl.uniformBlockBinding(program, i, binding);
const size = gl.getActiveUniformBlockParameter(
program, i, gl.UNIFORM_BLOCK_DATA_SIZE
);
console.log(`${name} → Binding ${binding}, ${size} Bytes`);
}
Ungültigen Index erkennen
const name = gl.getActiveUniformBlockName(program, 99);
console.log(name);
console.log(gl.getError() === gl.INVALID_VALUE);
// Wichtig · Fallstricke
- Nur WebGL 2: Die Methode gibt es ausschließlich auf
WebGL2RenderingContext. Einwebgl-Kontext (WebGL 1) hat keine Uniform-Blöcke. Vorher prüfen, obcanvas.getContext('webgl2')nichtnullliefert. - Blockname statt Instanzname: Bei
uniform Camera { … } cam;gibt die Methode"Camera"zurück, nicht"cam". Bei Block-Arrays wieuniform Lights { … } lights[4];erscheinen die Namen mit Index, zum Beispiel"Lights[0]". - Nur aktive Blöcke: Der Shader-Compiler kann Blöcke entfernen, die im Shader nicht benutzt werden. Solche Blöcke haben dann keinen Index. Die Reihenfolge der Indizes legt die Implementierung fest; man sollte sich nicht auf die Reihenfolge im Quelltext verlassen.
- Das Programm muss gelinkt sein (
gl.LINK_STATUSisttrue), sonst sind die Ergebnisse ungültig. - Performance: Introspektionsaufrufe können die GPU-Pipeline synchronisieren. Namen und Indizes daher einmal nach dem Linken abfragen und zwischenspeichern, nicht in jedem Frame.
- Kompatibilität: WebGL 2 läuft in Chrome, Edge, Firefox und Safari (ab 15). Wenn der Kontext verloren geht (
webglcontextlost), gibt die Methodenullzurück.