Signatur
Beschreibung
Die Methode colorMaskiOES() gehört zur WebGL-Erweiterung OES_draw_buffers_indexed und ist die indizierte Variante von WebGLRenderingContext.colorMask(). Während colorMask() die Schreibmaske global für alle Farbanhänge eines Framebuffers setzt, gilt colorMaskiOES() nur für den Zeichenpuffer mit dem angegebenen Index.
Das ist vor allem beim Multiple Render Targets (MRT)-Rendering nützlich, etwa in einem Deferred-Shading-G-Buffer: Ein Fragment-Shader schreibt gleichzeitig in mehrere Farbanhänge (z. B. Albedo, Normalen, Material-Parameter), und man möchte für einzelne Anhänge bestimmte Kanäle schützen – etwa den Alpha-Kanal eines Anhangs, der Zusatzdaten aus einem früheren Durchgang enthält.
Die Erweiterung ist nur in WebGL 2-Kontexten verfügbar und muss vorher mit gl.getExtension("OES_draw_buffers_indexed") aktiviert werden. Der Index buf bezieht sich auf die Position in der mit gl.drawBuffers() festgelegten Liste, also auf gl.DRAW_BUFFERi, nicht direkt auf COLOR_ATTACHMENTi.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $buf Pflicht | GLuint (number) | Index des Zeichenpuffers, für den die Maske gesetzt wird. Muss kleiner als gl.getParameter(gl.MAX_DRAW_BUFFERS) sein. |
|
| $red Pflicht | GLboolean (boolean) | true | true, wenn der Rot-Kanal beschrieben werden darf. |
| $green Pflicht | GLboolean (boolean) | true | true, wenn der Grün-Kanal beschrieben werden darf. |
| $blue Pflicht | GLboolean (boolean) | true | true, wenn der Blau-Kanal beschrieben werden darf. |
| $alpha Pflicht | GLboolean (boolean) | true | true, wenn der Alpha-Kanal beschrieben werden darf. |
Rückgabewert
undefined).Beispiele
Erweiterung aktivieren und Alpha für Puffer 1 sperren
const canvas = document.createElement("canvas");
const gl = canvas.getContext("webgl2");
const ext = gl?.getExtension("OES_draw_buffers_indexed");
if (!ext) {
console.log("OES_draw_buffers_indexed wird nicht unterstützt");
} else {
// Puffer 0: alle Kanäle schreiben
ext.colorMaskiOES(0, true, true, true, true);
// Puffer 1: Alpha-Kanal schützen
ext.colorMaskiOES(1, true, true, true, false);
console.log("Masken gesetzt");
}
G-Buffer mit mehreren Render Targets
const gl = document.querySelector("canvas").getContext("webgl2");
const ext = gl.getExtension("OES_draw_buffers_indexed");
const createTarget = (w, h) => {
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA8, w, h);
return tex;
};
const fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
const albedo = createTarget(512, 512);
const normals = createTarget(512, 512);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, albedo, 0);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT1, gl.TEXTURE_2D, normals, 0);
gl.drawBuffers([gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1]);
// Decal-Pass: nur Albedo-RGB ändern, Normalen komplett unangetastet lassen
ext.colorMaskiOES(0, true, true, true, false);
ext.colorMaskiOES(1, false, false, false, false);
// ... gl.drawArrays(...) für die Decals ...
// Masken zurücksetzen
ext.colorMaskiOES(0, true, true, true, true);
ext.colorMaskiOES(1, true, true, true, true);
Aktuelle Maske eines Puffers abfragen
const gl = document.createElement("canvas").getContext("webgl2");
const ext = gl.getExtension("OES_draw_buffers_indexed");
ext.colorMaskiOES(0, true, false, true, false);
const mask = gl.getIndexedParameter(gl.COLOR_WRITEMASK, 0);
console.log(mask);
// Wichtig · Fallstricke
- Nur WebGL 2: In WebGL-1-Kontexten liefert
getExtension()immernull. Immer aufnullprüfen, bevor die Methode aufgerufen wird. - Browser-Unterstützung: Chromium-Browser ab Version 89 und Firefox ab 90; Safari und manche mobilen GPUs/Treiber stellen die Erweiterung nicht bereit. Einen Fallback mit globalem
gl.colorMask()vorsehen. - Ist
bufgrößer oder gleichMAX_DRAW_BUFFERS, wird der Fehlergl.INVALID_VALUEerzeugt (abfragbar übergl.getError()); die Maske bleibt unverändert. - Ein späterer Aufruf von
gl.colorMask()überschreibt die Masken aller Zeichenpuffer, auch die zuvor indiziert gesetzten. - Die Maske wirkt auch auf
gl.clear()undgl.clearBufferfv()– gesperrte Kanäle werden beim Löschen nicht zurückgesetzt. Nach dem Pass Masken daher bewusst wiederherstellen.