Signatur
Beschreibung
stencilMask() steuert, welche einzelnen Bits im Stencil-Puffer verändert werden dürfen. Jedes gesetzte Bit in mask erlaubt das Schreiben an dieser Bitposition, jedes gelöschte Bit schützt die Position. Die Maske gilt sowohl für Stencil-Operationen beim Zeichnen (festgelegt über stencilOp()) als auch für gl.clear(gl.STENCIL_BUFFER_BIT).
Typische Anwendungsfälle sind Masken- und Portal-Effekte, Umrisse (Outlines), Spiegelungen oder Schatten-Volumen. Häufig schreibt man zuerst eine Form in den Stencil-Puffer (Maske 0xFF), sperrt danach das Schreiben mit stencilMask(0x00) und zeichnet weitere Geometrie nur noch dort, wo der Stencil-Test besteht. Außerdem lassen sich einzelne Bits als separate „Ebenen“ nutzen, etwa Bit 0 für eine Maske und Bit 1 für eine andere.
Die Methode wirkt auf Vorder- und Rückseiten. Für getrennte Masken pro Seite gibt es stencilMaskSeparate(face, mask). Der Anfangswert besteht aus lauter Einsen, es sind also alle Bits beschreibbar. Die Maske wirkt sich nicht auf den Stencil-Test aus. Dafür ist die Maske in stencilFunc() zuständig.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $mask Pflicht | GLuint (number) | alle Bits gesetzt (z. B. 0xFF bei einem 8-Bit-Stencil-Puffer) | Bitmaske, die das Schreiben einzelner Stencil-Bits erlaubt (Bit = 1) oder sperrt (Bit = 0). Der Wert wird als vorzeichenloser 32-Bit-Integer verarbeitet. |
Rückgabewert
undefined).Beispiele
Stencil-Schreiben aktivieren und sperren
const canvas = document.querySelector('canvas');
// Stencil-Puffer muss explizit angefordert werden
const gl = canvas.getContext('webgl', { stencil: true });
gl.enable(gl.STENCIL_TEST);
// Alle 8 Bits beschreibbar
gl.stencilMask(0xFF);
// Schreiben komplett sperren (Stencil ist nur noch lesbar)
gl.stencilMask(0x00);
console.log(gl.getParameter(gl.STENCIL_WRITEMASK));
Maske schreiben, danach nur innerhalb der Maske zeichnen
// Annahme: gl, drawMaskShape() und drawScene() sind vorhanden
const renderMasked = (gl, drawMaskShape, drawScene) => {
gl.enable(gl.STENCIL_TEST);
// 1. Stencil löschen – dazu muss die Maske das Schreiben erlauben
gl.stencilMask(0xFF);
gl.clearStencil(0);
gl.clear(gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
// 2. Form in den Stencil schreiben (Wert 1), ohne Farbausgabe
gl.colorMask(false, false, false, false);
gl.stencilFunc(gl.ALWAYS, 1, 0xFF);
gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
drawMaskShape();
// 3. Stencil-Schreiben sperren und nur dort zeichnen, wo Stencil == 1
gl.colorMask(true, true, true, true);
gl.stencilMask(0x00);
gl.stencilFunc(gl.EQUAL, 1, 0xFF);
drawScene();
};
Einzelne Bits als getrennte Ebenen nutzen
// Bit 0 = Spiegelfläche, Bit 1 = Portal
const MIRROR_BIT = 0b01;
const PORTAL_BIT = 0b10;
// Nur Bit 1 beschreiben, Bit 0 bleibt geschützt
gl.stencilMask(PORTAL_BIT);
gl.stencilFunc(gl.ALWAYS, PORTAL_BIT, 0xFF);
gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
// drawPortal();
console.log(gl.getParameter(gl.STENCIL_WRITEMASK) === PORTAL_BIT);
// Wichtig · Fallstricke
- Stencil-Puffer anfordern: Standardmäßig ist
stencilin den Kontextattributenfalse. OhnegetContext('webgl', { stencil: true })hat der Standard-Framebuffer möglicherweise keinen Stencil-Puffer, undstencilMask()bewirkt nichts Sichtbares. Das lässt sich mitgl.getContextAttributes().stencilprüfen. - Auch
clear()ist betroffen: Steht die Maske noch auf0x00, löschtgl.clear(gl.STENCIL_BUFFER_BIT)den Stencil-Puffer nicht. Das ist ein häufiger Fehler. Vor dem Löschen deshalbstencilMask(0xFF)setzen. - Die Schreibmaske ist nicht die Vergleichsmaske aus
stencilFunc(). Beide werden oft verwechselt. - In WebGL 1 müssen die Masken für Vorder- und Rückseite beim Zeichnen gleich sein. Wer mit
stencilMaskSeparate()verschiedene Werte setzt, bekommt beidrawArrays/drawElementsden FehlerINVALID_OPERATION. - Den aktuellen Wert liefert
gl.getParameter(gl.STENCIL_WRITEMASK)bzw.gl.STENCIL_BACK_WRITEMASK. - Die Methode ist in allen Browsern mit WebGL-Unterstützung verfügbar und genauso auch in
WebGL2RenderingContext.