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

WebGLRenderingContext.clearStencil()

Methode

Legt den Wert fest, mit dem der Stencil-Buffer beim nächsten Aufruf von <code>gl.clear(gl.STENCIL_BUFFER_BIT)</code> gefüllt wird.

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

Signatur

WebGLRenderingContext.prototype.clearStencil(s)

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

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

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 mit gl.getContextAttributes().stencil oder gl.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 256 zu 0 und -1 zu 255.
  • Was gl.clear() beeinflusst: Welche Bits gelöscht werden, hängt von stencilMask() ab, und bei aktivem SCISSOR_TEST nur der Scissor-Bereich. stencilFunc() und stencilOp() spielen beim Löschen keine Rolle.
  • Eigene Framebuffer: Beim Rendern in ein eigenes Framebuffer-Objekt braucht es einen Renderbuffer mit STENCIL_INDEX8 oder DEPTH_STENCIL.
  • Kompatibilität: In allen modernen Browsern verfügbar. Gibt es genauso in WebGL2RenderingContext.