Tiefentest: Unterschied zwischen den Versionen
I0n0s (Diskussion | Beiträge) K (Bildwunsch entfernt) |
Flash (Diskussion | Beiträge) K (→Beispiel) |
||
Zeile 13: | Zeile 13: | ||
[[Bild:Depthtest_nt_enabled.jpg|thumb|200px|Aktivierter Tiefentest]] | [[Bild:Depthtest_nt_enabled.jpg|thumb|200px|Aktivierter Tiefentest]] | ||
[[Bild:Depthtest_nt_disabled.jpg|thumb|200px|Deaktivierter Tiefentest]] | [[Bild:Depthtest_nt_disabled.jpg|thumb|200px|Deaktivierter Tiefentest]] | ||
− | Dieser Rendercode wird | + | Dieser Rendercode wird einmal mit und einmal ohne Tiefentest verwendet. |
glBegin(GL_QUADS); | glBegin(GL_QUADS); | ||
glColor4f(1.0, 0.5, 0.5, 1.0); | glColor4f(1.0, 0.5, 0.5, 1.0); | ||
Zeile 28: | Zeile 28: | ||
glEnd; | glEnd; | ||
− | Man kann deutlich erkennen, dass | + | Man kann deutlich erkennen, dass bei deaktiviertem Tiefentest das eigentlich vorne liegende rote Quad vom weiter hinten liegenden, allerdings später gerenderten, grünen Quad überdeckt wird. |
== Transparenz und Tiefentest == | == Transparenz und Tiefentest == | ||
Sobald Transparenz verwendet wird, kann der Tiefentest zumindest für diese Teile nicht mehr benutzt werden. Dies würde zu Fehlern führen, da das transparente Fragment ggfs. das durchscheinende, jedoch erst später an die Grafik-Pipeline gesendete und somit vom Tiefentest verworfene Fragment dahinter völlig verbirgt. Wenn man Transparente Fragmente nicht in den Tiefenbuffer schreibt, so können diese Fragmente von anderen, eigentlich weiter hinten liegenden, Fragmenten komplett überschrieben werden.<br> | Sobald Transparenz verwendet wird, kann der Tiefentest zumindest für diese Teile nicht mehr benutzt werden. Dies würde zu Fehlern führen, da das transparente Fragment ggfs. das durchscheinende, jedoch erst später an die Grafik-Pipeline gesendete und somit vom Tiefentest verworfene Fragment dahinter völlig verbirgt. Wenn man Transparente Fragmente nicht in den Tiefenbuffer schreibt, so können diese Fragmente von anderen, eigentlich weiter hinten liegenden, Fragmenten komplett überschrieben werden.<br> | ||
Aus diesem Grund sollten Transparente Objekte nach allen anderen Objekten an OpenGL geschickt werden und diese möglichst von hinten nach vorne sortiert sein. Das Sortieren kann durch einen Alpha Wert im [[Framebuffer]] umgangen werden, jedoch ist dieser nur selten in Hardware vorhanden, wodurch in den weit langsameren Softwaremodus gewechselt wird. | Aus diesem Grund sollten Transparente Objekte nach allen anderen Objekten an OpenGL geschickt werden und diese möglichst von hinten nach vorne sortiert sein. Das Sortieren kann durch einen Alpha Wert im [[Framebuffer]] umgangen werden, jedoch ist dieser nur selten in Hardware vorhanden, wodurch in den weit langsameren Softwaremodus gewechselt wird. |
Version vom 2. Dezember 2006, 17:37 Uhr
Bei der Berechnung eines Fragmentes, muss OpenGL feststellen können, welche Teile der Grafik im Vordergrund stehen und welche Objekte ganz oder teilweise durch andere Objekte verdeckt werden.
Funktionsweise
Für den Tiefentest existiert der Tiefenpuffer. Dieser ist genauso gross wie der Framebuffer. Für jeden Pixel auf dem Bildschirm gibt es dann also einen weiteren Wert - den Eintrag im Tiefenpuffer.
Im ersten Schritt wird der gesamte Tiefenpuffer auf den größtmöglichen Wert initialisiert (also die maximale Distanz, siehe glClear und glClearDepth). Sobald dann ein Objekt gerendert wird, wird für jeden Pixel überprüft, ob der Tiefenwert des Pixels dieses Objekts kleiner ist als der Wert im Tiefenpuffer. Ist dies der Fall, wird dieses Pixel in den Framebuffer gezeichnet und der Tiefepuffer aktualisiert, ansonsten wird es verworfen. Der Test kann mittels glDepthFunc auch abgeändert werden. Zum Beispiel kann man dafür sorgen, dass auch gleich große Tiefenwerte akzeptiert werden.
Der Tiefentest findet verhältnismäßig früh in der Fragment-Pipeline statt, wodurch er sehr effizient nicht benötigte Fragmente ausschließen kann. Wenn Objekte tiefensortiert (in diesem Fall von vorne nach hinten) gezeichnet werden, ist der Tiefentest sehr gut geeignet um sehr früh nicht benötigte Fragmente zu verwerfen um so die Füllrate zu schonen.
Beispiel
Dieser Rendercode wird einmal mit und einmal ohne Tiefentest verwendet.
glBegin(GL_QUADS); glColor4f(1.0, 0.5, 0.5, 1.0); glVertex3f(-1.0, 0.0, -1.0); glVertex3f(-1.0, 0.0, 1.0); glVertex3f(1.0, 0.0, 1.0); glVertex3f(1.0, 0.0, -1.0); glColor4f(0.5, 1.0, 0.5, 1.0); glVertex3f(-1.0, 0.5, -1.0); glVertex3f(-1.0, 0.5, 1.0); glVertex3f(1.0, 0.5, 1.0); glVertex3f(1.0, 0.5, -1.0); glEnd;
Man kann deutlich erkennen, dass bei deaktiviertem Tiefentest das eigentlich vorne liegende rote Quad vom weiter hinten liegenden, allerdings später gerenderten, grünen Quad überdeckt wird.
Transparenz und Tiefentest
Sobald Transparenz verwendet wird, kann der Tiefentest zumindest für diese Teile nicht mehr benutzt werden. Dies würde zu Fehlern führen, da das transparente Fragment ggfs. das durchscheinende, jedoch erst später an die Grafik-Pipeline gesendete und somit vom Tiefentest verworfene Fragment dahinter völlig verbirgt. Wenn man Transparente Fragmente nicht in den Tiefenbuffer schreibt, so können diese Fragmente von anderen, eigentlich weiter hinten liegenden, Fragmenten komplett überschrieben werden.
Aus diesem Grund sollten Transparente Objekte nach allen anderen Objekten an OpenGL geschickt werden und diese möglichst von hinten nach vorne sortiert sein. Das Sortieren kann durch einen Alpha Wert im Framebuffer umgangen werden, jedoch ist dieser nur selten in Hardware vorhanden, wodurch in den weit langsameren Softwaremodus gewechselt wird.