Start · Sprachen · JavaScript · Referenz · WebGL2RenderingContext.uniform[1234][uif][v]()

WebGL2RenderingContext.uniform[1234][uif][v]()

Methode

Legt Werte für Uniform-Variablen im aktuell aktiven Shader-Programm fest. Dazu gehören die neuen vorzeichenlosen <code>ui</code>-Varianten und die Array-Varianten mit Offset und Länge.

seit JavaScript WebGL 2.0 – Baseline: alle modernen Browser (seit Kategorie: webapi

Signatur

WebGL2RenderingContext.prototype.uniform[1234][uif][v](location, data, srcOffset, srcLength)

Beschreibung

Die Familie uniform[1234][uif][v]() überträgt Werte aus JavaScript an Uniform-Variablen eines GLSL-Shaders. Uniforms bleiben innerhalb eines Draw-Calls für alle Vertices und Fragmente gleich. Man nutzt sie typischerweise für Zeit, Auflösung, Farben, Lichtpositionen oder Index-Werte. Der Methodenname gibt die Form der Daten an:

  • Ziffer 1–4: Anzahl der Komponenten, also Skalar, vec2, vec3 oder vec4.
  • f: float. i: int bzw. bool oder Sampler. ui: uint bzw. uvec* (neu in WebGL 2).
  • Suffix v: Die Werte kommen als Array bzw. typisiertes Array statt als Einzelargumente.

WebGL 2 erweitert die v-Varianten um zwei optionale Parameter, srcOffset und srcLength. Damit kann man einen Ausschnitt aus einem großen Float32Array, Int32Array oder Uint32Array hochladen, ohne mit subarray() ein neues Array anzulegen. Das ist praktisch, wenn viele Uniform-Daten in einem gemeinsamen Puffer liegen.

Die Methoden wirken immer auf das Programm, das gerade mit gl.useProgram() aktiviert ist. Die location holt man vorher mit gl.getUniformLocation(). Methode und GLSL-Typ müssen zusammenpassen: Für ein uint braucht man uniform1ui, nicht uniform1i. Sonst meldet WebGL den Fehler INVALID_OPERATION.

Parameter

Name Typ Default Beschreibung
$location Pflicht WebGLUniformLocation | null Position der Uniform-Variablen, geliefert von gl.getUniformLocation(). Bei null wird der Aufruf still ignoriert.
$v0, v1, v2, v3 Pflicht number Nur bei den Varianten ohne v: je nach Ziffer 1 bis 4 Einzelwerte. Bei ui werden sie in vorzeichenlose 32-Bit-Ganzzahlen umgewandelt.
$data Pflicht Float32Array | Int32Array | Uint32Array | number[] Nur bei v-Varianten: die Werte als (typisiertes) Array. Die Länge muss ein Vielfaches der Komponentenanzahl sein. Für uiv Uint32Array verwenden, für iv Int32Array, für fv Float32Array.
$srcOffset number 0 Nur bei v-Varianten (WebGL 2): Index des ersten Elements in data, ab dem gelesen wird.
$srcLength number 0 Nur bei v-Varianten (WebGL 2): Anzahl der zu lesenden Elemente. Bei 0 wird alles ab srcOffset bis zum Ende gelesen.

Rückgabewert

Typ
void
Beschreibung
Kein Rückgabewert. Fehler kann man über gl.getError() abfragen, z. B. INVALID_OPERATION bei unpassendem Typ oder fehlendem aktivem Programm und INVALID_VALUE bei ungültigem Offset oder ungültiger Länge.

Beispiele

Skalar- und Vektor-Uniforms pro Frame setzen

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

const vsSource = `#version 300 es
in vec4 aPosition;
void main() { gl_Position = aPosition; }`;

const fsSource = `#version 300 es
precision highp float;
uniform float uTime;
uniform vec2 uResolution;
uniform vec4 uColor;
out vec4 outColor;
void main() {
  vec2 st = gl_FragCoord.xy / uResolution;
  outColor = uColor * (0.5 + 0.5 * sin(uTime + st.x * 6.28));
}`;

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);
gl.useProgram(program); // Pflicht vor uniform*()

const uTime = gl.getUniformLocation(program, 'uTime');
const uResolution = gl.getUniformLocation(program, 'uResolution');
const uColor = gl.getUniformLocation(program, 'uColor');

const render = (t) => {
  gl.uniform1f(uTime, t / 1000);
  gl.uniform2f(uResolution, canvas.width, canvas.height);
  gl.uniform4fv(uColor, [0.2, 0.6, 1.0, 1.0]);
  // ... gl.drawArrays(...)
  requestAnimationFrame(render);
};
requestAnimationFrame(render);

Vorzeichenlose Ganzzahlen mit uniform*ui (nur WebGL 2)

// GLSL: uniform uint uFrame; uniform uvec2 uTileIndex; uniform uvec4 uMask;
const uFrame = gl.getUniformLocation(program, 'uFrame');
const uTileIndex = gl.getUniformLocation(program, 'uTileIndex');
const uMask = gl.getUniformLocation(program, 'uMask');

gl.useProgram(program);
gl.uniform1ui(uFrame, 42);
gl.uniform2ui(uTileIndex, 3, 7);
gl.uniform4uiv(uMask, new Uint32Array([0xFF, 0xFF00, 0xFF0000, 0xFF000000]));

console.log(gl.getUniform(program, uFrame));
console.log(gl.getError() === gl.NO_ERROR);
42 true

Ausschnitt aus einem gemeinsamen Puffer mit srcOffset/srcLength

// GLSL: uniform vec3 uLights[4];
// Ein großer Puffer mit Positionen für 8 Lichter (je 3 Floats)
const allLights = new Float32Array([
  0, 1, 0,   1, 1, 0,   2, 1, 0,   3, 1, 0,
  4, 1, 0,   5, 1, 0,   6, 1, 0,   7, 1, 0
]);

const uLights = gl.getUniformLocation(program, 'uLights');
gl.useProgram(program);

// Lichter 4–7 hochladen: ab Element 12, genau 12 Floats (4 × vec3)
gl.uniform3fv(uLights, allLights, 12, 12);

const first = gl.getUniformLocation(program, 'uLights[0]');
console.log(gl.getUniform(program, first));
Float32Array(3) [4, 1, 0]