Signatur
Beschreibung
clearStencil() setzt den Löschwert für den Stencil-Buffer, also den Wert, den jedes Pixel im Stencil-Buffer bekommt, wenn der Buffer mit gl.clear(gl.STENCIL_BUFFER_BIT) geleert wird. Die Methode löscht selbst nichts. Sie ändert nur einen Zustand im WebGL-Kontext, der bestehen bleibt, bis er erneut gesetzt wird.
Der Stencil-Buffer ist ein Ganzzahl-Puffer mit meist 8 Bit pro Pixel. Man nutzt ihn für Masken, Portale, Spiegelungen, Umrisse (Outlines) und Schattenvolumen. Vor jedem Frame setzt man ihn in der Regel auf einen bekannten Ausgangswert, meistens 0, und schreibt dann mit stencilFunc() und stencilOp() gezielt Werte hinein.
Wichtig: Der Kontext hat nur dann einen Stencil-Buffer, wenn er mit { stencil: true } erzeugt wurde, zum Beispiel über canvas.getContext("webgl", { stencil: true }). Die Voreinstellung ist false. Ohne Stencil-Buffer haben clearStencil() und alle Stencil-Tests keine sichtbare Wirkung.
Den aktuell gesetzten Wert liest man mit gl.getParameter(gl.STENCIL_CLEAR_VALUE) aus. Der Standardwert ist 0.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $s Pflicht | number (GLint) | 0 | Ganzzahliger Wert, mit dem der Stencil-Buffer beim Löschen gefüllt wird. Er wird mit 2n - 1 maskiert, wobei n die Anzahl der Stencil-Bits ist (meist 8, also Werte 0–255). |
Rückgabewert
undefined).Beispiele
Stencil-Löschwert setzen und auslesen
const canvas = document.createElement("canvas");
// Stencil-Buffer muss explizit angefordert werden
const gl = canvas.getContext("webgl", { stencil: true });
gl.clearStencil(1);
console.log(gl.getParameter(gl.STENCIL_CLEAR_VALUE));
console.log(gl.getParameter(gl.STENCIL_BITS));
Farb-, Tiefen- und Stencil-Buffer pro Frame löschen
const gl = document.querySelector("#scene").getContext("webgl", { stencil: true });
gl.clearColor(0.1, 0.1, 0.1, 1.0);
gl.clearDepth(1.0);
gl.clearStencil(0);
const render = () => {
// Alle drei Buffer in einem Aufruf löschen
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
// ... Zeichenbefehle ...
requestAnimationFrame(render);
};
requestAnimationFrame(render);
Maske vorbereiten: nur innerhalb eines Bereichs zeichnen
const gl = document.querySelector("#scene").getContext("webgl", { stencil: true });
gl.enable(gl.STENCIL_TEST);
gl.clearStencil(0);
gl.clear(gl.STENCIL_BUFFER_BIT);
// Nur einen Rechteck-Bereich über Scissor mit 1 füllen
gl.enable(gl.SCISSOR_TEST);
gl.scissor(50, 50, 200, 100);
gl.clearStencil(1);
gl.clear(gl.STENCIL_BUFFER_BIT);
gl.disable(gl.SCISSOR_TEST);
// Ab jetzt nur dort zeichnen, wo der Stencil-Wert 1 ist
gl.stencilFunc(gl.EQUAL, 1, 0xff);
gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
// ... drawArrays / drawElements ...
// Wichtig · Fallstricke
- Kein Stencil-Buffer ohne Anforderung:
getContext("webgl")legt standardmäßig keinen Stencil-Buffer an. Übergib{ stencil: true }und prüfe mitgl.getContextAttributes().stencilodergl.getParameter(gl.STENCIL_BITS), ob wirklich einer vorhanden ist. - Maskierung: Werte außerhalb von 0 bis 2n−1 werden bitweise abgeschnitten. Bei 8 Bit wird zum Beispiel
256zu0und-1zu255. - Was
gl.clear()beeinflusst: Welche Bits gelöscht werden, hängt vonstencilMask()ab, und bei aktivemSCISSOR_TESTnur der Scissor-Bereich.stencilFunc()undstencilOp()spielen beim Löschen keine Rolle. - Eigene Framebuffer: Beim Rendern in ein eigenes Framebuffer-Objekt braucht es einen Renderbuffer mit
STENCIL_INDEX8oderDEPTH_STENCIL. - Kompatibilität: In allen modernen Browsern verfügbar. Gibt es genauso in
WebGL2RenderingContext.