Start · Sprachen · JavaScript · Referenz · WebGLActiveInfo.size

WebGLActiveInfo.size

Eigenschaft

Schreibgeschützte Zahl, die die Array-Länge eines aktiven Attributs oder Uniforms angibt, wie sie <code>getActiveAttrib()</code> bzw. <code>getActiveUniform()</code> liefern.

seit JavaScript Baseline: alle Browser (WebGL 1.0 / WebGL 2.0) Kategorie: webapi

Signatur

WebGLActiveInfo.size

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

Typ
number
Beschreibung
Eine positive ganze Zahl (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);
}
uBones[0] 4 uColor 1

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));
┌─────────┬─────────────┬──────┬───────┬──────────┐ │ (index) │ name │ size │ type │ location │ │ 0 │ 'aPosition' │ 1 │ 35666 │ 0 │ └─────────┴─────────────┴──────┴───────┴──────────┘

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);
64

// Wichtig · Fallstricke

  • Keine Byte-Größe: size zählt Elemente vom Typ type, keine Bytes und keine Komponenten. Ein mat4 ohne Array hat size === 1.
  • Optimierung durch den Treiber: Der GLSL-Compiler kann ungenutzte hintere Array-Elemente entfernen. size gibt 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 name in der Regel auf [0]. Für den Zugriff auf weitere Elemente fragt man die Position über getUniformLocation(program, 'uBones[2]') ab.
  • Nur lesbar: Zuweisungen werden ignoriert; im Strict Mode lösen sie einen TypeError aus.
  • Kompatibilität: Wird in allen modernen Browsern mit WebGL 1 und WebGL 2 unterstützt. In WebGL 2 liefert auch getTransformFeedbackVarying() ein WebGLActiveInfo-Objekt mit size. Ist das Programm nicht gelinkt oder der Index ungültig, wird null zurückgegeben. Den Wert deshalb vor dem Zugriff auf size prüfen.