Start · Sprachen · JavaScript · Referenz · WebGLRenderingContext.activeTexture()

WebGLRenderingContext.activeTexture()

Methode

Legt fest, welche Textureinheit aktiv ist. Nachfolgende Aufrufe wie <code>bindTexture()</code> oder <code>texParameteri()</code> beziehen sich auf diese Einheit.

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

Signatur

WebGLRenderingContext.prototype.activeTexture(texture)

Beschreibung

activeTexture() wählt die aktive Textureinheit des WebGL-Kontexts aus. Eine GPU hat mehrere Textureinheiten („Slots“). An jede davon kann gleichzeitig eine Textur gebunden sein. Alle folgenden Textur-Aufrufe wie bindTexture(), texImage2D(), texParameteri() oder generateMipmap() wirken immer auf die gerade aktive Einheit.

Du brauchst die Methode vor allem, wenn ein Shader mehrere Texturen gleichzeitig ausliest, etwa eine Diffuse-Map plus Normal-Map oder zwei Bilder zum Überblenden. Der Ablauf sieht dann so aus: Einheit aktivieren, Textur binden und anschließend der sampler2D-Uniform per uniform1i() den Index der Einheit mitgeben (also 0, 1, … und nicht die Konstante gl.TEXTURE0).

Der Parameter ist die Konstante gl.TEXTURE0 plus ein Versatz, also gl.TEXTURE0 + i. Wie viele Einheiten es gibt, hängt von der Hardware ab. Die Obergrenze liefert gl.getParameter(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS), WebGL 1 garantiert mindestens 8. Standardmäßig ist gl.TEXTURE0 aktiv.

Parameter

Name Typ Default Beschreibung
$texture Pflicht GLenum (number) Die zu aktivierende Textureinheit: gl.TEXTURE0 bis gl.TEXTURE0 + (MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1). Üblich ist die Schreibweise gl.TEXTURE0 + i.

Rückgabewert

Typ
void
Beschreibung
Kein Rückgabewert (undefined).

Beispiele

Eine Textur auf Einheit 0 binden und dem Shader übergeben

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

// program ist ein bereits gelinktes WebGLProgram mit "uniform sampler2D u_image;"
const texture = gl.createTexture();

gl.activeTexture(gl.TEXTURE0);          // Einheit 0 aktivieren
gl.bindTexture(gl.TEXTURE_2D, texture); // Textur an Einheit 0 binden
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE,
  new Uint8Array([255, 0, 0, 255])); // 1×1 rotes Pixel

gl.useProgram(program);
const loc = gl.getUniformLocation(program, 'u_image');
gl.uniform1i(loc, 0); // Index der Einheit, NICHT gl.TEXTURE0

console.log(gl.getParameter(gl.ACTIVE_TEXTURE) === gl.TEXTURE0);
true

Mehrere Texturen (Diffuse + Normal-Map) gleichzeitig nutzen

const bindTextureToUnit = (gl, program, uniformName, texture, unit) => {
  gl.activeTexture(gl.TEXTURE0 + unit);
  gl.bindTexture(gl.TEXTURE_2D, texture);
  gl.uniform1i(gl.getUniformLocation(program, uniformName), unit);
};

gl.useProgram(program);
bindTextureToUnit(gl, program, 'u_diffuse', diffuseTexture, 0);
bindTextureToUnit(gl, program, 'u_normalMap', normalTexture, 1);

gl.drawArrays(gl.TRIANGLES, 0, vertexCount);

Anzahl verfügbarer Textureinheiten prüfen

const gl = document.createElement('canvas').getContext('webgl');
const maxUnits = gl.getParameter(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS);
console.log(`Verfügbare Textureinheiten: ${maxUnits}`);

// Ungültige Einheit führt zu INVALID_ENUM
gl.activeTexture(gl.TEXTURE0 + maxUnits);
console.log(gl.getError() === gl.INVALID_ENUM);
Verfügbare Textureinheiten: 32 true

// Wichtig · Fallstricke

  • Häufigster Fehler: uniform1i(loc, gl.TEXTURE1) statt uniform1i(loc, 1). Die Sampler-Uniform erwartet den Index der Einheit und nicht die Enum-Konstante (gl.TEXTURE0 hat den Wert 33984).
  • Übergibst du eine Einheit außerhalb des gültigen Bereichs, entsteht der Fehler gl.INVALID_ENUM. Eine Ausnahme wird dabei nicht geworfen, du erkennst den Fehler nur über gl.getError().
  • Die aktive Einheit ist ein globaler Zustand. Hilfsfunktionen, die intern activeTexture() aufrufen (etwa beim Hochladen von Texturen), können unbemerkt die Bindungen einer anderen Einheit überschreiben.
  • Die Zahl der Einheiten hängt von der Hardware ab. Es gibt getrennte Grenzen für den Fragment-Shader (MAX_TEXTURE_IMAGE_UNITS, mindestens 8) und für den Vertex-Shader (MAX_VERTEX_TEXTURE_IMAGE_UNITS, kann 0 sein).
  • Die Methode ist in WebGL 1 und identisch in WebGL2RenderingContext verfügbar und wird von allen modernen Browsern unterstützt.