ZFighting

Aus DGL Wiki
Wechseln zu: Navigation, Suche

Ursache

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.

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. Zfighting.jpg

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.

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.

Lösung

Z-Fighting kann durch verschieden Techniken verhindert werden:

  • 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).
  • 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)
  • 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)