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

WebGLRenderingContext.stencilMask()

Methode

Legt eine Bitmaske fest, die bestimmt, welche Bits des Stencil-Puffers beim Zeichnen und Löschen beschrieben werden dürfen – für Vorder- und Rückseiten gleichzeitig.

seit JavaScript WebGL 1.0 – Baseline: alle modernen Browser Kategorie: webapi

Signatur

WebGLRenderingContext.prototype.stencilMask(mask)

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

Typ
void
Beschreibung
Kein 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);
true

// Wichtig · Fallstricke

  • Stencil-Puffer anfordern: Standardmäßig ist stencil in den Kontextattributen false. Ohne getContext('webgl', { stencil: true }) hat der Standard-Framebuffer möglicherweise keinen Stencil-Puffer, und stencilMask() bewirkt nichts Sichtbares. Das lässt sich mit gl.getContextAttributes().stencil prüfen.
  • Auch clear() ist betroffen: Steht die Maske noch auf 0x00, löscht gl.clear(gl.STENCIL_BUFFER_BIT) den Stencil-Puffer nicht. Das ist ein häufiger Fehler. Vor dem Löschen deshalb stencilMask(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 bei drawArrays/drawElements den Fehler INVALID_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.