Ich arbeite an einem Front-to-Back-Renderer für eine 2D-Engine mit einer orthografischen Projektion. Ich möchte den Tiefenpuffer verwenden, um ein Überziehen zu vermeiden. Ich habe einen 16-Bit-Tiefenpuffer, eine Kamera bei Z = 100 mit Blick auf Z = 0, zNear ist 1 und zFar ist 1000. Jedes gerenderte Sprite setzt seine Z-Koordinaten auf immer weiter entfernte Werte, sodass der Tiefentest das Rendern überspringen kann alles was darunter ist.
Mir ist jedoch bewusst, dass die Art und Weise, wie Z-Positionen mit Z-Pufferwerten enden, nicht linear ist. Ich möchte die volle Auflösung des 16-Bit-Tiefenpuffers nutzen, dh 65536 eindeutige Werte zulassen. Daher möchte ich für jedes gerenderte Sprite die Z-Position auf die nächste Position erhöhen, um sie mit dem nächsten eindeutigen Tiefenpufferwert zu korrelieren.
Mit anderen Worten, ich möchte einen inkrementierenden Index (0, 1, 2, 3 ...) des eingezogenen Sprites an die entsprechende Z-Position für jedes Sprite drehen, um einen eindeutigen Tiefenpufferwert zu erhalten. Ich bin mir nicht sicher, welche Mathematik dahinter steckt. Was ist die Berechnung, um dies zu tun?
Hinweis: Ich arbeite in WebGL (im Grunde OpenGL ES 2) und muss eine breite Palette von Hardware unterstützen. Erweiterungen wie gl_FragDepth erleichtern dies möglicherweise, können es jedoch aus Kompatibilitätsgründen nicht verwenden.
quelle
Antworten:
In der Tat sind die im Z-Puffer gespeicherten Werte nicht linear zu den tatsächlichen Z-Koordinaten Ihrer Objekte, sondern zu deren Kehrwert, um dem, was sich in der Nähe des Auges befindet, eine höhere Auflösung zu verleihen als dem, was sich näher an der Rückwand befindet.
Was Sie tun, ist, dass Sie Ihr
zNear
zu0
und IhrzFar
zu zuordnen1
. FürzNear=1
undzFar=2
sollte es so aussehenDie Art und Weise, dies zu berechnen, wird definiert durch:
Wo
... und z_buffer_value ist eine ganze Zahl.
Die obige Gleichung wurde Ihnen mit freundlicher Genehmigung dieser fantastischen Seite zur Verfügung gestellt , auf der Z-Puffer auf wirklich gute Weise erklärt werden.
Um das Notwendige
z
für eine bestimmte zu findenz_buffer_value
, löschen wir einfach Folgendesz
:quelle
z_buffer_value = k * (a + (b / z))
und einfach neu ordne, um zu lösenz
, dann bekomme ich:z = b / ((z_buffer_value / k) - a)
- wie bist du zu der anderen letzten Formel gekommen?(v / k) - a => (v - k * a) / k
und kollabierst zu(k * b) / (v - (k * a))
. Es ist das gleiche Ergebnis.Vielleicht sollten Sie Ihre Herangehensweise an etwas Einfacheres ändern. Was ich tun würde; Behalten Sie Ihre Z-Tiefen-Sache bei, aber führen Sie eine Liste dessen, was Sie rendern. Ordnen Sie diese Liste basierend auf dem Wert z Depth und rendern Sie Objekte in der Reihenfolge der Liste.
Hoffe das kann helfen. Die Leute sagen mir immer, ich soll die Dinge einfach halten.
quelle
Müssen Sie den Z-Index wirklich erhöhen, da Sie bereits eine sortierte Liste der zu rendernden Dinge (von vorne nach hinten) haben? Können Sie nicht "kleiner oder gleich" für die "Überprüfungsfunktion" verwenden? Auf diese Weise wird tatsächlich geprüft, ob ein bestimmtes Pixel bereits gezeichnet wurde oder nicht.
quelle