Wenn Sie ein perspektivisches Bild erstellen und Ihr Modell implizite Schnittpunkte hat, werden diese Schnittpunkte bei Verwendung von "linearem Z" an den falschen Stellen angezeigt.
Stellen Sie sich zum Beispiel eine einfache Grundebene mit einer Reihe von Telefonmasten vor, die in die Ferne rücken und den Boden durchbohren (und weiter unten fortfahren). Die impliziten Schnittpunkte werden durch die interpolierten Tiefenwerte bestimmt. Wenn diese nicht interpoliert 1/Z
werden, sieht das Bild falsch aus, wenn die projizierten Scheitelpunkte mit Perspektive berechnet wurden.
Ich entschuldige mich für die nicht-ästhetische Qualität der folgenden Abbildungen, aber ich habe sie bereits 1997 gemacht.
Das erste Bild zeigt den erforderlichen Rendering-Effekt. (Beachten Sie, dass die blauen "Pylone" ziemlich weit unter der Grundebene liegen und daher am unteren Rand der Bilder abgeschnitten sind.)
Dieses zweite Bild zeigt das Ergebnis der Verwendung eines nicht reziproken Tiefenpuffers: (Entschuldigung für die Änderung der Skalierung - diese wurden aus einem alten MS Word-Dokument kopiert und ich habe keine Ahnung, was mit der Skalierung passiert ist.)
Wie Sie sehen können, sind die Ergebnisse falsch.
Möchten Sie wirklich eine lineare Z-Darstellung? Wenn Sie eine Perspektive rendern, möchten Sie sicher mehr Präzision näher an der Kamera als in der Ferne?
Zu Ihrem späteren Kommentar:
"Wenn diese nicht mit 1 / Z interpoliert sind", die ich nicht verstehe. Welche Interpolation ist das?
Das erste, was zu beachten ist, ist, dass bei einer standardmäßigen perspektivischen Projektion gerade Linien im Weltraum gerade Linien im perspektivischen Raum bleiben. Abstände / Längen bleiben jedoch nicht erhalten.
Nehmen wir der Einfachheit halber an, dass eine triviale Perspektiventransformation verwendet wird, um die Eckpunkte zu projizieren, dh
Wir sollten auch eine reziproke Bildschirmraumtiefe berechnen, z. B. aber lineares Z im Tiefenpuffer würde für mich Folgendes erfordern: (Wir können hier annehmen, dass scale = 1 ist)XScreen=XWorldZWorld
YScreen=YWorldZWorld
ZScreen=1ZWorld
ZScreen=scale∗ZWorld
Nehmen wir an, wir haben eine Linie mit den Endpunkten des Weltraums
Mit der perspektivischen Zuordnung dieser Karte zu Bildschirmraumkoordinaten
⎡⎣⎢001⎤⎦⎥and⎡⎣⎢200010⎤⎦⎥
⎡⎣⎢001⎤⎦⎥and⎡⎣⎢2000.1⎤⎦⎥
Das Rendering-System / die Rendering-Hardware interpoliert den Bildschirmraum z linear, sodass am 1/2 Wegpunkt der Linie, wie er auf dem Bildschirm erscheint, dh bei Pixel (10, 0), ein projiziertes (inverses) Z erhalten wird Wert von 0,55, was einem Weltraum-Z-Wert von ~ 1,818 entspricht. Bei den Start- und End-Z-Werten beträgt dies ungefähr 20% entlang der Länge der Linie.
Wenn wir stattdessen versuchen würden, mit den ursprünglichen Z-Werten zu interpolieren, würden wir Z erhalten, das einem Weltraumwert von 5,5 entspricht. Solange nichts schneidet, könnten Sie in Ordnung sein (ich habe darüber auch nicht gründlich gedacht) , aber nichts mit impliziten Kreuzungen wird falsch sein.
Was ich nicht erwähnt habe, ist, dass Sie, sobald Sie eine perspektivisch korrekte Texturierung (oder sogar eine perspektivisch korrekte Schattierung) eingeführt haben, eine Interpolation pro Pixel von 1 / w durchführen und zusätzlich auch den Kehrwert dieses interpolierten Werts pro Pixel berechnen müssen.
far / z
, was Standard ist, macht keinen Sinn. Es ergibt sich ein Tiefenpuffer, der linearer wird, je näher die beiden Clip-Ebenen beieinander liegen. Es scheint eine Verschmelzung zweier Konzepte zu sein: bildschirmraumlineares Z und eine nicht konstante Tiefenpufferzuordnung für einen Performance-Hack.(x, y, z) / w
Fragment berechnet würde , aber anscheinend müssen wir uns stattdessen mit einer linear interpolierten Version von(x/w, y/w, z/w)
? Das erscheint mir 2018 nicht vernünftig, aber es wäre gut zu wissen, ob das der Hack ist, mit dem wir jetzt sowieso leben müssen!Die Verwendung von Z / W für den Tiefenpuffer geht tiefer als nur das Abschneiden gegen die nahen und fernen Ebenen. Wie Simon angedeutet hat, hat dies mit der Interpolation zwischen den Eckpunkten eines Dreiecks während der Rasterung zu tun.
Z / W ist die einzigartige Option, mit der NDC-Tiefenwerte für Punkte im Inneren des Dreiecks korrekt berechnet werden können, indem die NDC-Tiefenwerte aus den Scheitelpunkten einfach linear im Bildschirmbereich interpoliert werden . Im Prinzip könnten wir jede Funktion verwenden, die wir möchten, um den Kameraraum Z auf den Tiefenpufferwert abzubilden - aber jede andere Wahl als Z / W würde eine kompliziertere Berechnung pro Pixel erfordern, was langsamer und schwieriger wäre Hardware einbauen.
Beachten Sie, dass , wenn Sie einen linearen Tiefenpuffer verwenden, dann natürlich linear Tiefenwerte interpoliert wird in korrekt seinen Weltraum ... aber nicht im allgemeinen im Bildraum! Und es ist der Bildschirmbereich, der für die Rasterung wichtig ist, da wir in der Lage sein müssen, perspektivisch korrekte Tiefenwerte (und andere Attributwerte wie UVs) für jedes Pixelzentrum oder jeden anderen Abtastpunkt innerhalb der Bildschirmbereichsgrenzen von a zu generieren Dreieck wird gerastert.
quelle