Signatur
Beschreibung
Mit depthMask() legst du fest, ob Fragmente, die den Tiefentest bestehen, ihren Tiefenwert in den Tiefenpuffer schreiben. Der Tiefentest selbst wird davon nicht beeinflusst. Er wird über gl.enable(gl.DEPTH_TEST) und gl.depthFunc() gesteuert. Mit depthMask(false) werden Fragmente also weiterhin gegen den vorhandenen Tiefenpuffer geprüft, verändern ihn aber nicht.
Typischer Einsatz ist das Zeichnen transparenter Objekte: Zuerst zeichnest du alle undurchsichtigen Objekte mit aktivem Tiefenschreiben. Danach zeichnest du die transparenten Objekte mit depthMask(false). So werden sie korrekt von undurchsichtiger Geometrie verdeckt, verdecken sich aber nicht gegenseitig im Tiefenpuffer. Weitere Anwendungen sind Skyboxen, Partikelsysteme, Overlays und HUD-Elemente.
Die Einstellung ist ein globaler Zustand des Kontexts. Sie gilt, bis sie erneut geändert wird. Außerdem beeinflusst sie auch gl.clear(gl.DEPTH_BUFFER_BIT): Bei depthMask(false) wird der Tiefenpuffer beim Löschen nicht zurückgesetzt. Den aktuellen Wert fragst du mit gl.getParameter(gl.DEPTH_WRITEMASK) ab.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $flag Pflicht | boolean | true | true aktiviert das Schreiben in den Tiefenpuffer, false deaktiviert es. Der Anfangswert im Kontext ist true. |
Rückgabewert
undefined).Beispiele
Tiefenschreiben ein- und ausschalten und Zustand abfragen
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl');
console.log(gl.getParameter(gl.DEPTH_WRITEMASK)); // Standardwert
gl.depthMask(false);
console.log(gl.getParameter(gl.DEPTH_WRITEMASK));
gl.depthMask(true);
console.log(gl.getParameter(gl.DEPTH_WRITEMASK));
Undurchsichtige und transparente Objekte in zwei Durchgängen rendern
// Annahme: drawMesh(mesh) bindet Buffer und ruft gl.drawArrays/drawElements auf
const renderFrame = (gl, opaqueMeshes, transparentMeshes, cameraPos) => {
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(gl.LEQUAL);
// Wichtig: vor clear() Tiefenschreiben aktivieren, sonst wird der Tiefenpuffer nicht gelöscht
gl.depthMask(true);
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
// 1. Durchgang: undurchsichtig, mit Tiefenschreiben
gl.disable(gl.BLEND);
opaqueMeshes.forEach(drawMesh);
// 2. Durchgang: transparent, von hinten nach vorne, ohne Tiefenschreiben
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
gl.depthMask(false);
const dist = (m) => Math.hypot(
m.position[0] - cameraPos[0],
m.position[1] - cameraPos[1],
m.position[2] - cameraPos[2]
);
[...transparentMeshes]
.sort((a, b) => dist(b) - dist(a))
.forEach(drawMesh);
// Zustand zurücksetzen
gl.depthMask(true);
gl.disable(gl.BLEND);
};
Skybox zeichnen, ohne den Tiefenpuffer zu verändern
const drawSkybox = (gl, skyboxProgram, drawCube) => {
gl.useProgram(skyboxProgram);
gl.depthMask(false); // Skybox soll nichts verdecken
drawCube();
gl.depthMask(true); // danach normale Szene zeichnen
};
// Wichtig · Fallstricke
- Häufiger Fehler: Wenn
depthMask(false)noch aktiv ist, löschtgl.clear(gl.DEPTH_BUFFER_BIT)den Tiefenpuffer nicht. Aktiviere vor dem Löschen deshalb immerdepthMask(true). depthMask()schaltet den Tiefentest nicht ab. Um ihn ganz zu umgehen, verwendest dugl.disable(gl.DEPTH_TEST). IstDEPTH_TESTdeaktiviert, wird übrigens auch nicht in den Tiefenpuffer geschrieben.- Das Ausschalten des Tiefenschreibens bei transparenten Objekten löst das Sortierproblem nicht vollständig. Für korrektes Überblenden solltest du trotzdem von hinten nach vorne zeichnen oder ordnungsunabhängige Transparenz verwenden.
- Der Kontext braucht einen Tiefenpuffer. Die Option
depthingetContext('webgl', { depth: true })ist standardmäßigtrue. Beifalsehat die Methode keine sichtbare Wirkung. - Die Methode steht genauso in
WebGL2RenderingContextzur Verfügung. Sie wird in allen modernen Browsern unterstützt. - Die Methode entspricht
glDepthMaskaus OpenGL ES 2.0.