Signatur
Beschreibung
depthFunc() bestimmt, nach welcher Regel WebGL beim Tiefentest entscheidet, ob ein neues Fragment gezeichnet wird. Der Tiefenwert des eingehenden Fragments wird mit dem Wert verglichen, der an dieser Pixelposition bereits im Tiefenpuffer steht. Besteht das Fragment den Test, wird es geschrieben (und bei aktivem depthMask(true) der Tiefenpuffer aktualisiert), andernfalls wird es verworfen.
Der Standardwert ist gl.LESS: Ein Fragment gewinnt nur, wenn es näher an der Kamera liegt als das bisher gespeicherte. Das ist für normale 3D-Szenen passend. Andere Funktionen braucht man zum Beispiel für Skyboxen (gl.LEQUAL, damit Tiefe 1.0 noch besteht), für Multi-Pass-Rendering bzw. einen Depth-Prepass (gl.EQUAL oder gl.LEQUAL), für Reversed-Z (gl.GREATER bzw. gl.GEQUAL) oder für Spezialeffekte wie verdeckte Umrisse (gl.GREATER).
Wichtig: Die Funktion wirkt nur, wenn der Tiefentest mit gl.enable(gl.DEPTH_TEST) eingeschaltet ist und der Zeichenpuffer einen Tiefenpuffer besitzt (beim Standard-Framebuffer über die Kontextoption depth: true, die Voreinstellung). Die Einstellung ist ein globaler Zustand des Kontexts und gilt für alle folgenden Zeichenaufrufe, bis sie geändert wird. Den aktuellen Wert liest man mit gl.getParameter(gl.DEPTH_FUNC) aus.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $func Pflicht | GLenum | gl.LESS | Die Vergleichsfunktion:
|
Rückgabewert
undefined).Beispiele
Tiefentest aktivieren und Vergleichsfunktion setzen
const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl');
gl.enable(gl.DEPTH_TEST); // ohne das hat depthFunc keine Wirkung
gl.depthFunc(gl.LEQUAL); // näher ODER gleich weit entfernt gewinnt
gl.clearColor(0, 0, 0, 1);
gl.clearDepth(1.0);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
console.log(gl.getParameter(gl.DEPTH_FUNC) === gl.LEQUAL);
Skybox nach der Szene zeichnen
const drawFrame = (gl, drawScene, drawSkybox) => {
gl.enable(gl.DEPTH_TEST);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
// Normale Geometrie mit Standardvergleich
gl.depthFunc(gl.LESS);
drawScene();
// Skybox-Shader setzt gl_Position.z = gl_Position.w (Tiefe 1.0).
// Mit LEQUAL besteht sie dort, wo noch nichts gezeichnet wurde.
gl.depthFunc(gl.LEQUAL);
gl.depthMask(false);
drawSkybox();
// Zustand zurücksetzen
gl.depthMask(true);
gl.depthFunc(gl.LESS);
};
Verdeckte Teile eines Objekts hervorheben
// Zeichnet ein Objekt normal und danach nur seine verdeckten Bereiche
const drawWithHiddenOutline = (gl, drawObject, useHighlightShader, useNormalShader) => {
gl.enable(gl.DEPTH_TEST);
useNormalShader();
gl.depthFunc(gl.LESS);
drawObject();
// Nur Fragmente HINTER bereits gezeichneter Geometrie bestehen
useHighlightShader();
gl.depthFunc(gl.GREATER);
gl.depthMask(false); // Tiefenpuffer nicht überschreiben
drawObject();
gl.depthMask(true);
gl.depthFunc(gl.LESS);
};
// Wichtig · Fallstricke
- Tiefentest muss aktiv sein: Ohne
gl.enable(gl.DEPTH_TEST)wirddepthFunc()ignoriert – alles wird in Zeichenreihenfolge übermalt. - Kein Tiefenpuffer vorhanden: Wurde der Kontext mit
{ depth: false }erzeugt oder hat ein eigener Framebuffer kein Depth-Attachment, verhält sich der Test so, als bestünde jedes Fragment. - Ungültige Werte erzeugen den Fehler
gl.INVALID_ENUM(abfragbar übergl.getError()); der Zustand bleibt unverändert. - Globaler Zustand: Wer
depthFuncfür einen Pass ändert, sollte sie danach zurücksetzen, sonst entstehen schwer auffindbare Darstellungsfehler. - Tiefenpuffer löschen: Passend zur Funktion muss
clearDepth()gewählt werden – beigl.GREATER(Reversed-Z) z. B.gl.clearDepth(0.0). gl.EQUAList anfällig für Präzisionsprobleme, wenn zwei Passes nicht bitgenau dieselben Vertex-Berechnungen ausführen.- Verfügbar in allen modernen Browsern sowie identisch in
WebGL2RenderingContext.