Signatur
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
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);
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);
// Wichtig · Fallstricke
- Häufigster Fehler:
uniform1i(loc, gl.TEXTURE1)stattuniform1i(loc, 1). Die Sampler-Uniform erwartet den Index der Einheit und nicht die Enum-Konstante (gl.TEXTURE0hat 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 übergl.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
WebGL2RenderingContextverfügbar und wird von allen modernen Browsern unterstützt.