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

WebGLRenderingContext.depthFunc()

Methode

Legt die Vergleichsfunktion fest, mit der die Tiefe eingehender Fragmente gegen den aktuellen Wert im Tiefenpuffer geprüft wird.

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

Signatur

WebGLRenderingContext.prototype.depthFunc(func)

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:
  • gl.NEVER: besteht nie
  • gl.LESS: besteht, wenn neu < gespeichert
  • gl.EQUAL: besteht, wenn neu = gespeichert
  • gl.LEQUAL: besteht, wenn neu <= gespeichert
  • gl.GREATER: besteht, wenn neu > gespeichert
  • gl.NOTEQUAL: besteht, wenn neu ≠ gespeichert
  • gl.GEQUAL: besteht, wenn neu >= gespeichert
  • gl.ALWAYS: besteht immer

Rückgabewert

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

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) wird depthFunc() 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 über gl.getError()); der Zustand bleibt unverändert.
  • Globaler Zustand: Wer depthFunc fü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 – bei gl.GREATER (Reversed-Z) z. B. gl.clearDepth(0.0).
  • gl.EQUAL ist 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.