Start · Sprachen · JavaScript · Referenz · WebGLUniformLocation

WebGLUniformLocation

Schnittstelle

Undurchsichtiges Objekt, das die Position einer Uniform-Variablen in einem gelinkten WebGL-Shader-Programm repräsentiert.

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

Signatur

interface WebGLUniformLocation

Beschreibung

WebGLUniformLocation ist ein undurchsichtiges Handle der WebGL-API. Es verweist auf eine Uniform-Variable (z. B. uniform mat4 uModelView; oder uniform sampler2D uTexture;) in einem bereits gelinkten WebGLProgram. Das Interface hat weder eigene Methoden noch Eigenschaften und kann nicht per new erzeugt werden.

Man erhält eine Instanz über gl.getUniformLocation(program, name). Das zurückgegebene Objekt übergibt man anschließend an die gl.uniform*()-Methoden – etwa uniform1f, uniform3fv, uniform1i oder uniformMatrix4fv –, um Werte in den Shader zu schreiben. Mit gl.getUniform(program, location) lässt sich der aktuelle Wert auch wieder auslesen.

In der Praxis fragt man die Positionen einmalig nach dem Linken ab und speichert sie zwischen, denn getUniformLocation sucht über einen String und ist deshalb vergleichsweise teuer. Im Render-Loop setzt man dann nur noch die Werte. Eine Position gilt immer nur für genau das Programm, aus dem sie stammt.

Rückgabewert

Typ
WebGLUniformLocation | null
Beschreibung
Wird von WebGLRenderingContext.getUniformLocation() geliefert. Ist die Uniform nicht vorhanden oder vom Shader-Compiler wegoptimiert worden, ist der Wert null.

Beispiele

Uniform-Position abfragen und Farbe setzen

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

const vsSource = `
  attribute vec2 aPosition;
  void main() { gl_Position = vec4(aPosition, 0.0, 1.0); }
`;
const fsSource = `
  precision mediump float;
  uniform vec4 uColor;
  void main() { gl_FragColor = uColor; }
`;

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

// WebGLUniformLocation erhalten
const uColor = gl.getUniformLocation(program, 'uColor');
console.log(uColor instanceof WebGLUniformLocation);

gl.useProgram(program);          // Programm muss aktiv sein!
gl.uniform4f(uColor, 1.0, 0.5, 0.0, 1.0); // Orange
true

Positionen zwischenspeichern und im Render-Loop nutzen

// Einmalig nach linkProgram()
const uniforms = {
  time: gl.getUniformLocation(program, 'uTime'),
  matrix: gl.getUniformLocation(program, 'uMatrix'),
  texture: gl.getUniformLocation(program, 'uTexture'),
};

const identity = new Float32Array([
  1, 0, 0, 0,
  0, 1, 0, 0,
  0, 0, 1, 0,
  0, 0, 0, 1,
]);

const render = (t) => {
  gl.useProgram(program);
  gl.uniform1f(uniforms.time, t / 1000);
  gl.uniformMatrix4fv(uniforms.matrix, false, identity);
  gl.uniform1i(uniforms.texture, 0); // Textur-Einheit 0
  gl.drawArrays(gl.TRIANGLES, 0, 3);
  requestAnimationFrame(render);
};
requestAnimationFrame(render);

Fehlende Uniforms erkennen und Wert auslesen

const loc = gl.getUniformLocation(program, 'uColor');
if (loc === null) {
  console.warn('Uniform uColor fehlt oder wurde wegoptimiert');
} else {
  gl.useProgram(program);
  gl.uniform4fv(loc, [0.2, 0.4, 0.6, 1.0]);
  const value = gl.getUniform(program, loc);
  console.log(Array.from(value).map((v) => v.toFixed(1)));
}

// Array-Elemente und Struct-Felder haben eigene Positionen
const light0 = gl.getUniformLocation(program, 'uLights[0].position');
["0.2", "0.4", "0.6", "1.0"]

// Wichtig · Fallstricke

  • Wegoptimierte Uniforms: Der GLSL-Compiler entfernt Uniforms, die sich nicht auf die Ausgabe auswirken. getUniformLocation gibt dann null zurück. Ein uniform*()-Aufruf mit null wird still ignoriert und löst keinen Fehler aus – Tippfehler im Namen bleiben so leicht unbemerkt.
  • Programm muss aktiv sein: gl.uniform*() wirkt immer auf das mit gl.useProgram() aktivierte Programm. Gehört die Position zu einem anderen Programm, entsteht INVALID_OPERATION.
  • Nicht übertragbar: Positionen gelten nur für das Programm, aus dem sie stammen. Nach einem erneuten linkProgram() und nach einem Kontextverlust (webglcontextlost) werden sie ungültig und müssen neu abgefragt werden.
  • Typen müssen passen: Sampler (sampler2D) setzt man mit uniform1i (Index der Textur-Einheit), Matrizen mit uniformMatrix*fv. In WebGL 1 muss der Parameter transpose false sein.
  • Kein Zahlenwert: Anders als in nativem OpenGL ist die Position keine Ganzzahl, sondern ein Objekt. Man kann nicht damit rechnen – für Array-Elemente fragt man daher z. B. 'uArr[2]' separat ab.
  • Kompatibilität: Wird in allen modernen Browsern unterstützt, sowohl in WebGLRenderingContext als auch in WebGL2RenderingContext. In Web Workern ist es über OffscreenCanvas verfügbar.