OpenGL.org 3Dsource.de: Infos rund um 3D-Computergrafik, OpenGL und VRML
space Telefon-Tarife space VDI - Arbeitskreis Fahrzeugtechnik space Beschallungsanlagen und Elektroakustik space Heise-News space

12 Z-Buffer (Depth Buffer, Tiefeninformation)

12.010 Wie kann ich den Z-Buffer aktivieren ?

Das Programm muss zumindest folgende Schritte unternehmen, um den Tiefenbuffer zu aktivieren:

  1. Der Rendering Context muss bereits mit Tiefenbuffer angelegt werden.
  2. Nach dem Anlegen des Rendering Context muss der Tiefenbuffer mit glEnable(GL_DEPTH_TEST) aktiviert werden.
  3. Die Grenzen des Viewing Volumes (zNear und zFar) müssen so gesetzt werden, dass der Tiefenbuffer korrekt arbeiten kann (zNear >= 1.0, zFar nicht zu gross).
  4. glClear() muss zusätzlich mit GL_DEPTH_BUFFER_BIT aufgerufen werden.

Es gibt ausreichend Beispielprogramme im Netz, die mit dem Z-Buffer arbeiten. Falls es Probleme gibt, sollte man zunächst eines dieser Beispiele austesten. Links enthält die FAQ hier.

12.020 Der Z-Buffer scheint nicht mit der Zentralperspektive zu funktionieren. Warum nicht ?

Zunächst sollte man sich versichern, dass zNear und zFar vernünftige Werte enthalten (zu Testzwecken kann man für zNear = 1.0 - 10.0, für zFar = 200 - 1000) setzen).

Ein häfig gemachter Fehler sind zu geringe Werte für zNear. Dieser muss positiv und grösser Null sein, da hiermit eine Division durchgeführt wird). Beide Werte zählen als positiver Abstand vom Auge, dürfen also nie negativ sein.
Sind die Werte für zNear,zFar ungültig, meldet OpenGL be3i Verwendung von gluPerspective() trotzdem keine Fehler. Der Tiefenbuffer arbeitet dann aber nicht oder es werden unerwünschte Ergebnisse erzielt.

Im Falle von glFrustum() kann der Fehler durch glGetError() auch abgefragt werden. Die Funktion selbst wird deaktiviert.

12.030 Wie kann ich eine kurz vorher gespeicherte Tiefeninformation in den aktuellen Z-Buffer übertragen ?

Das kann man mittels glDrawPixels() und dem Parameter GL_DEPTH_COMPONENT realisieren. Es kann sinnvoll sein, den Color Buffer vorher zu deaktivieren, das geht durch glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE).

12.040 Der Z-Buffer scheint zu arbeiten, allerdings werden einige Polygone durch andere, im Vordergrund befindliche Polygone durchdrungen zu werden. Warum ?

Die Ursache ist meist in falschen Werten für zNear und zFar zu finden. Insbesondere Werte von zNear nahe Null beschränken die Präzision des Tiefenbuffers erheblich. Der Einfluss von zu grossen Werten für zFar ist dagegen nicht ganz so erheblich (sinnvolle Werte für zNear, zFar).

Die OpenGL Reference Manual enthält eine Aussage darüber, wie gross der Einfluss von zNear, zFar auf den Tiefenbuffer ist: ca. log2(zFar/zNear) gehen an Präzision verloren. Ist zNear nahe Null gesetzt, wird das Ergebnis unendlich gross.

Obwohl die Beschreibung aus dem Blue Book das Verhältnis der Werte gut nachvollziehbar macht, ist sie etwas oberflächlich. Wird der Wert von (zFar/zNear) grösser, nimmt die Präzision im hinteren Bereich des Tiefenbuffers im Vergleich zum vorderen Bereich deutlich stärker ab. Damit treten diese Durchdringungserscheinung von Objekten eher im hinteren Bereich des Viewing Volumes auf.

Es kann aber auch sein, dass der Tiefenbuffer einfach nicht gross genug für die Anforderungen der Szene ist (sie auch Frage 12.070).

Eine dritte Ursache kann sein, dass mehrere Flächen auf annähernd gleicher Höhe liegen. Damit sind Rundungsfehler während der Rasterisation nicht auszuschliessen. Eine Option ist z.B. der PolygonOffset.

12.050 Warum arbeitet mein Z-Buffer so ungenau ?

Die Präzision des Tiefenbuffers hängt wesentlich vom Verhältnis zFar/zNear, von zFar und vom Abstand des Objekts zu zNear ab.

Das heisst, zNear und zFar sollten so nah wie möglich beieinander liegen und zNear nicht zu nahe am Augpunkt.

Ein nachgerechnetes Beispiel findet sich in der englischen Version der OpenGL FAQ.

12.060 Wie kann ich die vordere Clippingfläche deaktivieren ?

Diese Frage wurde bereits in einem früheren Abschnitt beantwortet.

12.070 Warum arbeitet der Z-Buffer im vorderen Bereich genauer ?

Nachdem die Projektionsmatrix durchlaufen wurde, werden die Clipping Koordinaten XYZ durch ihre homogene Komponente W dividiert, die den Abstand des Vertex vom Augpunkt beschreibt. Daraus ergeben sich die normalisierten Device Koordinaten. Je weiter dass Objekt vom Augpunkt entfernt ist, desto mehr nähert sich Z/W Null an. Damit werden auch X/W and Y/W kleiner, dass Objekt als ganzes schrumpft also am Horizont, die Zentralprojektion ist damit verwirklicht.

Genauso wie in der Realität hat ein Bewegen der Kamera auf die Grösse der weiter entfernten Objekte wenig Auswirkungen.

12.080 Mein Z-Buffer ist nicht ausreichend gross für meine überdimensionale Szene. Welche Möglichkeiten habe ich noch ?

Eine typische Lösung ist es, eine Multipass Technik zu nutzen. Die Anwendung kann die Objekte zu Gruppen zusammenfassen, die in annähernd gleichem Abstand zum Augpunkt sind und einen ausreichenden Abstand zu anderen Objekten haben. Dann wird jede Gruppe getrennt gezeichnet, jeweils beginnend bei den am weitesten entfernten Objekten der Gruppe. Vor dem Zeichnen einer weiteren Gruppe wird der Tiefenbuffer gelöscht. Dadurch steht jeder Region die volle Breite des Tiefenbuffers zur Verfügung.

Seite durchsuchen nach:

Fragen oder Ideen an:
Thomas.Kern@3Dsource.de
Linux-Counter
(C) Thomas Kern