Start · Sprachen · JavaScript · Referenz · WebGLActiveInfo

WebGLActiveInfo

Schnittstelle

Beschreibt ein aktives Attribut oder Uniform eines gelinkten Shader-Programms mit Name, Typ und Array-Größe. Man erhält es über <code>getActiveAttrib()</code> und <code>getActiveUniform()</code>.

seit JavaScript WebGL 1.0 – Baseline: alle modernen Browser Kategorie: webapi

Signatur

interface WebGLActiveInfo

Beschreibung

WebGLActiveInfo gehört zur WebGL-API. Ein Objekt dieses Typs gibt Auskunft über eine einzelne aktive Attribut- oder Uniform-Variable eines erfolgreich gelinkten WebGLProgram. Man erzeugt es nicht selbst. Die Methoden WebGLRenderingContext.getActiveAttrib() und WebGLRenderingContext.getActiveUniform() geben es zurück. In WebGL 2 liefert außerdem getTransformFeedbackVarying() ein solches Objekt.

Das Objekt hat drei schreibgeschützte Eigenschaften:

  • name (string): der Name der Variablen im GLSL-Quelltext. Bei Arrays hängt WebGL [0] an, z. B. "uLights[0]".
  • type (GLenum): der GLSL-Datentyp als Konstante, z. B. gl.FLOAT_VEC3, gl.FLOAT_MAT4 oder gl.SAMPLER_2D.
  • size (GLint): die Anzahl der Array-Elemente. Bei Variablen, die kein Array sind, ist der Wert 1.

Typische Einsatzgebiete sind Shader-Introspektion und das automatische Erzeugen von Uniform-Settern, wie es z. B. twgl.js oder three.js tun. Auch Debug-Werkzeuge nutzen die Schnittstelle, um alle Eingaben eines Programms aufzulisten. Die Anzahl der aktiven Variablen liefert gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES) bzw. gl.ACTIVE_UNIFORMS. Über diese Indizes iteriert man dann.

Rückgabewert

Typ
WebGLActiveInfo
Beschreibung
Instanzen entstehen nur als Rückgabewert von getActiveAttrib(), getActiveUniform() oder (WebGL 2) getTransformFeedbackVarying(). Der Rückgabewert ist null, wenn der Index ungültig ist.

Beispiele

Alle aktiven Uniforms eines Programms auflisten

const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl');

const vsSource = `
  attribute vec3 aPosition;
  uniform mat4 uModelView;
  void main() { gl_Position = uModelView * vec4(aPosition, 1.0); }
`;
const fsSource = `
  precision mediump float;
  uniform vec3 uColors[4];
  void main() { gl_FragColor = vec4(uColors[0] + uColors[3], 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.type, info.size);
}
uModelView 35676 1 uColors[0] 35665 4

Typ-Konstanten in lesbare Namen übersetzen

const gl = document.createElement('canvas').getContext('webgl');

// Umkehr-Tabelle: GLenum-Wert → Konstantenname
const typeNames = {};
for (const key of ['FLOAT', 'FLOAT_VEC2', 'FLOAT_VEC3', 'FLOAT_VEC4',
                   'FLOAT_MAT2', 'FLOAT_MAT3', 'FLOAT_MAT4',
                   'INT', 'BOOL', 'SAMPLER_2D', 'SAMPLER_CUBE']) {
  typeNames[gl[key]] = key;
}

const describe = (info) =>
  `${info.name}: ${typeNames[info.type] ?? info.type}` +
  (info.size > 1 ? ` [${info.size}]` : '');

// Verwendung mit einem gelinkten Programm "program":
// const info = gl.getActiveAttrib(program, 0);
// console.log(describe(info)); // z. B. "aPosition: FLOAT_VEC3"
console.log(typeNames[gl.FLOAT_MAT4]);
FLOAT_MAT4

Attribut-Locations automatisch ermitteln

const getAttribLocations = (gl, program) => {
  const locations = {};
  const count = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES);
  for (let i = 0; i < count; i++) {
    const info = gl.getActiveAttrib(program, i);
    if (!info) continue;
    locations[info.name] = gl.getAttribLocation(program, info.name);
  }
  return locations;
};

// const locs = getAttribLocations(gl, program);
// console.log(locs); // { aPosition: 0 }
{ aPosition: 0 }

// Wichtig · Fallstricke

  • Nur aktive Variablen: Der GLSL-Compiler entfernt Variablen, die im Shader nicht verwendet werden. Solche Variablen tauchen nicht auf, und getUniformLocation() gibt für sie null zurück.
  • Array-Namen: Uniform-Arrays erscheinen als "name[0]", und size gibt die Array-Länge an. Für einen Setter entfernt man das Suffix [0] oder fragt jedes Element einzeln ab. Hat der Compiler hintere Array-Elemente entfernt, kann size kleiner sein als die deklarierte Länge.
  • Structs erscheinen nicht als ein Eintrag. Jedes Feld wird einzeln aufgeführt, z. B. "uLight.color".
  • Das Programm muss erfolgreich gelinkt sein. Das prüft man mit gl.getProgramParameter(program, gl.LINK_STATUS). Ist der Index ungültig, geben die Methoden null zurück und setzen den Fehler INVALID_VALUE.
  • Integrierte Variablen wie gl_VertexID haben das Präfix gl_. Je nach Implementierung können sie in der Liste stehen; man sollte sie beim Auswerten herausfiltern.
  • Das Objekt ist eine unveränderliche Momentaufnahme. Ein erneutes Linken des Programms ändert bereits abgefragte Objekte nicht.
  • Kompatibilität: Die Schnittstelle steht in allen Browsern mit WebGL 1 oder 2 zur Verfügung, ebenso in Workern mit OffscreenCanvas.