ZFighting: Unterschied zwischen den Versionen

Aus DGL Wiki
Wechseln zu: Navigation, Suche
K (weitere Infos im Web)
(Verbessert)
 
(5 dazwischenliegende Versionen von 4 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
 
== Ursache ==
 
== Ursache ==
 +
[[Bild:Zfighting.jpg|right|thumb|200px|Z-Fighting im oberen Bereich des Quads]]
  
Z-Fighting nennt man den Effekt, der auftritt, wenn zwei Polygone genau auf der gleichen Stelle positioniert wurden, und/oder wenn der [[Tiefenpuffer]] nicht hoch genug auflöst.
+
Z-Fighting nennt man den Effekt, der auftritt, wenn zwei Polygone genau auf der gleichen Stelle positioniert wurden, und/oder wenn der [[Tiefenpuffer]] nicht hoch genug auflöst: das Problem hat also seine Ursprünge in mangelnder Numerischer Stabilität bei der Berechnung der Tiefenwerte und damit zusammenhängend der Genauigkeit des verwendeten Zahlentyps im Tiefenpuffer.
  
 
== Beschreibung ==
 
== Beschreibung ==
  
Z-Fighting erkennt man am Flimmern der sich überdeckenden Polygone/Linien bei Bewegungen der Szene. Dabei kommt es mitunter auch zur partiellen Sichtbarkeit beider Polygone.
+
Z-Fighting erkennt man am Flimmern der sich überdeckenden Polygone/Linien bei Bewegungen der Szene. Dabei kommt es mitunter auch zur partiellen Sichtbarkeit beider Polygone.  
  
 
Ausgelöst wird dies dadurch, dass  
 
Ausgelöst wird dies dadurch, dass  
Zeile 14: Zeile 15:
  
 
Wenn der Tiefenpuffer 16Bit-Werte speichern kann, bedeutet dies, dass er 65536 verschiedene Tiefenabstufungen unterscheiden kann. Diese Tiefenstufen werden auf den sichtbaren Teil der Szene (dem [[Frustum]]) übertragen und durch die sogenannte Near- und Far-[[Clipping Plane]] (CP) begrenzt.
 
Wenn der Tiefenpuffer 16Bit-Werte speichern kann, bedeutet dies, dass er 65536 verschiedene Tiefenabstufungen unterscheiden kann. Diese Tiefenstufen werden auf den sichtbaren Teil der Szene (dem [[Frustum]]) übertragen und durch die sogenannte Near- und Far-[[Clipping Plane]] (CP) begrenzt.
 +
[[Bild:Frustum.png|right||thumb|200px|Skizze des Frustums]]
  
 
Wenn die NearCP z.B. bei 1 und die FarCP bei 1000 liegt, gibt es innerhalb der 1000 OpenGL Einheiten 65536 Abstufungen. Das sind also 65,536 Stufen pro Einheit. Wenn die FarCP aber bei 100000 liegt gibt es entsprechend nur noch 0,65536 Stufen pro Einheit. Bei einem so grob auflösenden [[Tiefenpuffer]] kann es dann sogar vorkommen, dass Polygone, die 1 Einheit weit voneinander entfernt sind, trotzdem in die selbe Tiefenstufe gelangen können. Das kann dann zu besagtem '''Z-Fighting''' führen.
 
Wenn die NearCP z.B. bei 1 und die FarCP bei 1000 liegt, gibt es innerhalb der 1000 OpenGL Einheiten 65536 Abstufungen. Das sind also 65,536 Stufen pro Einheit. Wenn die FarCP aber bei 100000 liegt gibt es entsprechend nur noch 0,65536 Stufen pro Einheit. Bei einem so grob auflösenden [[Tiefenpuffer]] kann es dann sogar vorkommen, dass Polygone, die 1 Einheit weit voneinander entfernt sind, trotzdem in die selbe Tiefenstufe gelangen können. Das kann dann zu besagtem '''Z-Fighting''' führen.
 +
 +
Besonders problematisch ist es, der NearCP zu wenig Abstand zum Betrachter zu geben, denn der Tiefenpuffer ist meist als eine Art Fliesskommatyp realisiert. Fliesskommazahlen sind am dichtesten bei der 0 und verlieren Genauigkeit zu größeren Zahlen hin. Da die 0 im Tiefenpuffer jedoch die NearCP repräsentiert, ist die Genauigkeit dort besonders hoch. Die NearCP gibt damit quasi an, ab welchem Bereich im Blickfeld es interessant wird - wenn Gegenstände normalerweise in Entfernungen von einigen Einheiten sind, dann ist eine NearCP von 0.1 eher hinderlich.
  
 
== Lösung ==
 
== Lösung ==
  
 
Z-Fighting kann durch verschieden Techniken verhindert werden:  
 
Z-Fighting kann durch verschieden Techniken verhindert werden:  
<ul><li>Die Tiefenfunktion ändern ( [[glDepthFunc]](GL_LEQUAL) ).</li>
+
<ul>
 +
<li>Die Near-Clipping-Plane soweit hinausschieben wie möglich und die Far-Clipping-Plane so nahe wie möglich halten, damit der Z-Puffer besser aufgeteilt wird. ('''Hilft am meisten''')</li>
 +
<li>Die Tiefenfunktion ändern ( [[glDepthFunc]](GL_LEQUAL) ).</li>
 
<li>Genauigkeit des Tiefenbuffers erhöhen (z.B. 24 oder 32 Bit statt 16 Bit, wobei moderne Karten meist maximal 24 Bit unterstützen).</li>
 
<li>Genauigkeit des Tiefenbuffers erhöhen (z.B. 24 oder 32 Bit statt 16 Bit, wobei moderne Karten meist maximal 24 Bit unterstützen).</li>
<li>Die Near-Clipping-Plane soweit hinausschieben wie möglich und die Far-Clipping-Plane so nahe wie möglich halten. (Damit der Z-Puffer besser aufgeteilt wird)</li>
 
 
<li>Keine zwei Polygone an der selben Stelle rendern lassen.</li>
 
<li>Keine zwei Polygone an der selben Stelle rendern lassen.</li>
 
<li>"Polygon Offset" verwenden ( [[glPolygonOffset]] ).</li>
 
<li>"Polygon Offset" verwenden ( [[glPolygonOffset]] ).</li>
Zeile 29: Zeile 34:
 
== weitere Infos im Web ==
 
== weitere Infos im Web ==
  
[http://www.sjbaker.org/steve/omniv/love_your_z_buffer.html Ein interresanter Artikel über Z-Buffer] (Falls Link nicht funktioniert: [http://www.google.com/search?q=cache:-rnJ929O4dgJ:www.sjbaker.org/steve/omniv/love_your_z_buffer.html+%22love_your_z_buffer%22&hl=de&gl=de&ct=clnk&cd=1 Google-Chache])
+
[http://www.sjbaker.org/steve/omniv/love_your_z_buffer.html Ein interresanter Artikel über Z-Buffer] (Falls Link nicht funktioniert: [http://www.google.com/search?q=cache:-rnJ929O4dgJ:www.sjbaker.org/steve/omniv/love_your_z_buffer.html+%22love_your_z_buffer%22&hl=de&gl=de&ct=clnk&cd=1 Google-Cache])

Aktuelle Version vom 30. September 2011, 19:44 Uhr

Ursache

Z-Fighting im oberen Bereich des Quads

Z-Fighting nennt man den Effekt, der auftritt, wenn zwei Polygone genau auf der gleichen Stelle positioniert wurden, und/oder wenn der Tiefenpuffer nicht hoch genug auflöst: das Problem hat also seine Ursprünge in mangelnder Numerischer Stabilität bei der Berechnung der Tiefenwerte und damit zusammenhängend der Genauigkeit des verwendeten Zahlentyps im Tiefenpuffer.

Beschreibung

Z-Fighting erkennt man am Flimmern der sich überdeckenden Polygone/Linien bei Bewegungen der Szene. Dabei kommt es mitunter auch zur partiellen Sichtbarkeit beider Polygone.

Ausgelöst wird dies dadurch, dass

  • entweder 2 Polygone auf der selben Tiefenposition liegen und z.B. durch Rundungsfehler einmal das eine und dann wieder das andere sichtbar ist
  • oder 2 Polygone relativ nah beieinander liegen, aber im Tiefenpuffer als gleich weit entfernt eingeordnet werden, weil der Tiefenpuffer nicht genau genug arbeiten kann.

Eine Erklärung ist hierbei wohl nur bei dem zweiten Auftreten nötig:

Wenn der Tiefenpuffer 16Bit-Werte speichern kann, bedeutet dies, dass er 65536 verschiedene Tiefenabstufungen unterscheiden kann. Diese Tiefenstufen werden auf den sichtbaren Teil der Szene (dem Frustum) übertragen und durch die sogenannte Near- und Far-Clipping Plane (CP) begrenzt.

Skizze des Frustums

Wenn die NearCP z.B. bei 1 und die FarCP bei 1000 liegt, gibt es innerhalb der 1000 OpenGL Einheiten 65536 Abstufungen. Das sind also 65,536 Stufen pro Einheit. Wenn die FarCP aber bei 100000 liegt gibt es entsprechend nur noch 0,65536 Stufen pro Einheit. Bei einem so grob auflösenden Tiefenpuffer kann es dann sogar vorkommen, dass Polygone, die 1 Einheit weit voneinander entfernt sind, trotzdem in die selbe Tiefenstufe gelangen können. Das kann dann zu besagtem Z-Fighting führen.

Besonders problematisch ist es, der NearCP zu wenig Abstand zum Betrachter zu geben, denn der Tiefenpuffer ist meist als eine Art Fliesskommatyp realisiert. Fliesskommazahlen sind am dichtesten bei der 0 und verlieren Genauigkeit zu größeren Zahlen hin. Da die 0 im Tiefenpuffer jedoch die NearCP repräsentiert, ist die Genauigkeit dort besonders hoch. Die NearCP gibt damit quasi an, ab welchem Bereich im Blickfeld es interessant wird - wenn Gegenstände normalerweise in Entfernungen von einigen Einheiten sind, dann ist eine NearCP von 0.1 eher hinderlich.

Lösung

Z-Fighting kann durch verschieden Techniken verhindert werden:

  • Die Near-Clipping-Plane soweit hinausschieben wie möglich und die Far-Clipping-Plane so nahe wie möglich halten, damit der Z-Puffer besser aufgeteilt wird. (Hilft am meisten)
  • Die Tiefenfunktion ändern ( glDepthFunc(GL_LEQUAL) ).
  • Genauigkeit des Tiefenbuffers erhöhen (z.B. 24 oder 32 Bit statt 16 Bit, wobei moderne Karten meist maximal 24 Bit unterstützen).
  • Keine zwei Polygone an der selben Stelle rendern lassen.
  • "Polygon Offset" verwenden ( glPolygonOffset ).

weitere Infos im Web

Ein interresanter Artikel über Z-Buffer (Falls Link nicht funktioniert: Google-Cache)