Signatur
Beschreibung
Die Methode stencilMaskSeparate() setzt eine Bitmaske, die bestimmt, welche Bits der Stencil-Ebenen (Schablonenpuffer) durch Stencil-Operationen verändert werden dürfen. Ein gesetztes Bit (1) erlaubt das Schreiben, ein gelöschtes Bit (0) schützt das entsprechende Bit vor Änderungen. Im Unterschied zu stencilMask() kann die Maske hier getrennt für vorder- und rückseitige Polygone angegeben werden.
Das ist vor allem bei Techniken nützlich, die Vorder- und Rückseiten im selben Zeichendurchgang unterschiedlich behandeln, etwa bei Stencil-Schattenvolumen (Z-Pass/Z-Fail) oder beim Markieren von Bereichen, die sich in mehreren Bitebenen überlagern. Welche Fläche als „vorne“ gilt, richtet sich nach frontFace() (Standard: gl.CCW).
Die Maske wirkt auf alle Schreibvorgänge in den Stencil-Puffer – also auf Operationen, die mit stencilOp()/stencilOpSeparate() festgelegt wurden, und auf gl.clear(gl.STENCIL_BUFFER_BIT). Der Standardwert ist „alle Bits beschreibbar“ (alle Einsen). Den aktuellen Wert fragt man mit gl.getParameter(gl.STENCIL_WRITEMASK) bzw. gl.STENCIL_BACK_WRITEMASK ab.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $face Pflicht | GLenum | Für welche Flächen die Maske gilt: gl.FRONT, gl.BACK oder gl.FRONT_AND_BACK. |
|
| $mask Pflicht | GLuint (number) | Bitmaske, die das Schreiben einzelner Stencil-Bits erlaubt (1) oder verhindert (0). Standard ist 0xFFFFFFFF (alle Bits beschreibbar). |
Rückgabewert
undefined).Beispiele
Grundlegende Verwendung und Abfrage
const canvas = document.createElement('canvas');
// Stencil-Puffer muss explizit angefordert werden
const gl = canvas.getContext('webgl', { stencil: true });
// Vorderseiten dürfen nur die unteren 4 Bits schreiben
gl.stencilMaskSeparate(gl.FRONT, 0x0F);
// Rückseiten dürfen nur die oberen 4 Bits schreiben
gl.stencilMaskSeparate(gl.BACK, 0xF0);
console.log(gl.getParameter(gl.STENCIL_WRITEMASK).toString(16));
console.log(gl.getParameter(gl.STENCIL_BACK_WRITEMASK).toString(16));
Stencil-Schattenvolumen (Z-Fail) in einem Durchgang
const gl = document.querySelector('canvas').getContext('webgl', { stencil: true, depth: true });
const drawShadowVolume = (drawVolume) => {
gl.enable(gl.STENCIL_TEST);
gl.disable(gl.CULL_FACE); // beide Seiten zeichnen
gl.colorMask(false, false, false, false);
gl.depthMask(false);
// Beide Seiten dürfen alle 8 Bits schreiben
gl.stencilMaskSeparate(gl.FRONT_AND_BACK, 0xFF);
gl.stencilFunc(gl.ALWAYS, 0, 0xFF);
gl.stencilOpSeparate(gl.BACK, gl.KEEP, gl.INCR_WRAP, gl.KEEP);
gl.stencilOpSeparate(gl.FRONT, gl.KEEP, gl.DECR_WRAP, gl.KEEP);
drawVolume();
gl.colorMask(true, true, true, true);
gl.depthMask(true);
};
drawShadowVolume(() => { /* gl.drawArrays(...) für das Schattenvolumen */ });
Bits beim Löschen schützen
const gl = document.querySelector('canvas').getContext('webgl', { stencil: true });
// Bit 7 enthält eine dauerhafte Maske (z. B. UI-Bereich) und soll erhalten bleiben
gl.stencilMaskSeparate(gl.FRONT_AND_BACK, 0x7F);
gl.clearStencil(0);
gl.clear(gl.STENCIL_BUFFER_BIT); // löscht nur die Bits 0–6
// Danach wieder alle Bits freigeben
gl.stencilMaskSeparate(gl.FRONT_AND_BACK, 0xFF);
// Wichtig · Fallstricke
- Stencil-Puffer anfordern: Ohne
getContext('webgl', { stencil: true })gibt es in der Regel keinen Stencil-Puffer (gl.getParameter(gl.STENCIL_BITS)liefert dann0) – die Maske hat dann keine Wirkung. - WebGL-Einschränkung: Anders als in OpenGL ES verlangt WebGL, dass Vorder- und Rückseiten-Schreibmaske (sowie Referenzwert und Vergleichsmaske aus
stencilFuncSeparate()) beim Zeichnen gleich sind, bezogen auf die tatsächlich vorhandenen Stencil-Bits. Sonst löstdrawArrays()/drawElements()den Fehlergl.INVALID_OPERATIONaus. Unterschiedliche Masken wie im ersten Beispiel sind also zwar setzbar, aber nicht zum Zeichnen verwendbar. - Ein ungültiger Wert für
faceerzeugtgl.INVALID_ENUM(prüfbar mitgl.getError()). - Die Maske beeinflusst auch
gl.clear()– ein vergessenes Zurücksetzen führt oft zu „nicht gelöschten“ Stencil-Werten. - Verfügbar in allen modernen Browsern, ebenso in
WebGL2RenderingContext.