Signatur
Beschreibung
Die Eigenschaft type eines WebGLActiveInfo-Objekts enthält den Datentyp einer aktiven Shader-Variablen als GLenum-Zahl. Solche Objekte bekommt man von gl.getActiveAttrib(), gl.getActiveUniform() und in WebGL 2 zusätzlich von gl.getTransformFeedbackVarying().
Der Wert ist eine Zahl, die einer WebGL-Konstanten entspricht. Häufige Werte sind gl.FLOAT, gl.FLOAT_VEC2, gl.FLOAT_VEC3, gl.FLOAT_VEC4, gl.INT, gl.BOOL, gl.FLOAT_MAT4, gl.SAMPLER_2D und gl.SAMPLER_CUBE. WebGL 2 ergänzt unter anderem gl.UNSIGNED_INT_VEC*, gl.FLOAT_MAT2x3 und gl.SAMPLER_3D.
Gebraucht wird die Eigenschaft vor allem beim Reflektieren von Shader-Programmen. Engines und Hilfsbibliotheken lesen damit nach dem Linken alle Attribute und Uniforms aus und wählen automatisch die passende Setter-Funktion, zum Beispiel uniform3fv für FLOAT_VEC3 oder uniformMatrix4fv für FLOAT_MAT4.
Rückgabewert
35665 für gl.FLOAT_VEC3.Beispiele
Typ eines Attributs abfragen
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl');
const vsSource = `attribute vec3 aPosition;
void main() { gl_Position = vec4(aPosition, 1.0); }`;
const fsSource = `precision mediump float;
void main() { gl_FragColor = vec4(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 info = gl.getActiveAttrib(program, 0);
console.log(info.name, info.type, info.type === gl.FLOAT_VEC3);
Alle Uniforms mit lesbarem Typnamen auflisten
// Annahme: gl und ein gelinktes program existieren bereits
const typeName = (gl, type) =>
Object.keys(Object.getPrototypeOf(gl))
.find((key) => gl[key] === type && /VEC|MAT|SAMPLER|FLOAT|INT|BOOL/.test(key)) ?? `0x${type.toString(16)}`;
const count = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
for (let i = 0; i < count; i++) {
const { name, type, size } = gl.getActiveUniform(program, i);
console.log(`${name}: ${typeName(gl, type)} (size ${size})`);
}
Automatische Uniform-Setter anhand des Typs
const createUniformSetters = (gl, program) => {
const setters = {};
const count = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
for (let i = 0; i < count; i++) {
const info = gl.getActiveUniform(program, i);
const loc = gl.getUniformLocation(program, info.name);
switch (info.type) {
case gl.FLOAT: setters[info.name] = (v) => gl.uniform1f(loc, v); break;
case gl.FLOAT_VEC3: setters[info.name] = (v) => gl.uniform3fv(loc, v); break;
case gl.FLOAT_MAT4: setters[info.name] = (v) => gl.uniformMatrix4fv(loc, false, v); break;
case gl.SAMPLER_2D:
case gl.INT:
case gl.BOOL: setters[info.name] = (v) => gl.uniform1i(loc, v); break;
default: console.warn(`Nicht behandelter Typ ${info.type} für ${info.name}`);
}
}
return setters;
};
const setters = createUniformSetters(gl, program);
gl.useProgram(program);
setters.uColor?.([1, 0, 0]);
// Wichtig · Fallstricke
typeist eine Zahl, kein String. Vergleiche daher immer mit den Konstanten des Kontexts (gl.FLOAT_VEC3) und nicht mit Texten wie"vec3".- Die Eigenschaft ist schreibgeschützt. Zuweisungen werden ohne Fehlermeldung ignoriert, im Strict Mode lösen sie einen
TypeErroraus. - Bei Arrays (z. B.
uniform vec4 uLights[4]) gibttypeden Typ eines einzelnen Elements an. Die Anzahl der Elemente steht insize, undnameendet auf[0]. - Der GLSL-Compiler entfernt Variablen, die im Shader nicht benutzt werden. Sie tauchen dann gar nicht auf. Ist der Index ungültig, geben
getActiveAttrib()bzw.getActiveUniform()nullzurück. Vor dem Zugriff auf.typedeshalb aufnullprüfen. - Die Typen, die es nur in WebGL 2 gibt (z. B.
SAMPLER_3D,UNSIGNED_INT_VEC2), sind nur in einemWebGL2RenderingContextvorhanden. - Kompatibilität: Die Eigenschaft wird in allen modernen Browsern unterstützt, auch in Web Workern über
OffscreenCanvas.