Wie ich es verstehe, werden OpenGL-Polygone normalerweise im Clip-Raum abgeschnitten und nur diese Dreiecke (oder Teile der Dreiecke, wenn der Beschneidungsprozess sie aufteilt), die den Vergleich mit + - w überstehen. Dies erfordert dann die Implementierung eines Polygon-Clipping-Algorithmus wie Sutherland-Hodgman.Dreiecke im Bildschirmbereich pro Pixel schneiden
Ich implementiere meinen eigenen CPU-Rasterizer und möchte das jetzt vermeiden. Ich habe die NDC-Koordinaten der Scheitelpunkte verfügbar (nicht wirklich normalisiert, da ich nichts abgeschnitten habe, so dass die Positionen nicht im Bereich [-1, 1] sein können). Ich möchte diese Werte für alle Pixel interpolieren und nur Pixel zeichnen, deren NDC-Koordinaten innerhalb von [-1, 1] in den Dimensionen x, y und z liegen. Ich würde dann zusätzlich den Tiefentest durchführen.
Würde das funktionieren? Wenn ja, wie würde die Interpolation aussehen? Kann ich die Formel OpenGl spec (Seite 427 14.9) für die Attributinterpolation wie beschrieben verwenden here? Alternativ, sollte ich die Formel 14.10 verwenden, die für die Tiefeninterpolation (z) für alle 3 Koordinaten verwendet wird (ich verstehe nicht wirklich, warum dort eine andere verwendet wird)?
Update: habe ich versucht, die NDC-Werte pro Pixel durch zwei Verfahren interpoliert:
w0, w1, w2
sind die baryzentrischen Gewichte der Vertices.
1) float x_ndc = w0 * v0_NDC.x + w1 * v1_NDC.x + w2 * v2_NDC.x; float y_ndc = w0 * v0_NDC.y + w1 * v1_NDC.y + w2 * v2_NDC.y; float z_ndc = w0 * v0_NDC.z + w1 * v1_NDC.z + w2 * v2_NDC.z;
2) float x_ndc = (w0*v0_NDC.x/v0_NDC.w + w1*v1_NDC.x/v1_NDC.w + w2*v2_NDC.x/v2_NDC.w)/ (w0/v0_NDC.w + w1/v1_NDC.w + w2/v2_NDC.w); float y_ndc = (w0*v0_NDC.y/v0_NDC.w + w1*v1_NDC.y/v1_NDC.w + w2*v2_NDC.y/v2_NDC.w)/ (w0/v0_NDC.w + w1/w1_NDC.w + w2/v2_NDC.w); float z_ndc = w0 * v0_NDC.z + w1 * v1_NDC.z + w2 * v2_NDC.z;
Der Abschneide + Tiefentest immer sieht wie folgt aus:
if (-1.0f < z_ndc && z_ndc < 1.0f && z_ndc < currentDepth && 1.0f < y_ndc && y_ndc < 1.0f && -1.0f < x_ndc && x_ndc < 1.0f)
Fall 1) entspricht Gleichung 14.10 für die Interpolation. Fall 2) entspricht der Verwendung der Gleichung 14.9 für die Interpolation.
Ergebnisse documented in gifs on imgur. 1) Seltsame Dinge passieren, wenn der zweite Würfel hinter der Kamera ist oder wenn ich in einen Würfel gehe. 2) Seltsame Artefakte sind nicht sichtbar, aber wenn sich die Kamera den Scheitelpunkten nähert, verschwinden sie. Und da dies die perspective correct interpolation of attributes Scheitelpunkte (näher an der Kamera?) Sind, haben sie ein größeres Gewicht, so dass, sobald ein Scheitelpunkt abgeschnitten wird, diese Information mit starkem Gewicht auf die Dreieckspixel interpoliert wird.
Wird all dies erwartet oder habe ich etwas falsch gemacht?
Ich weiß nicht, was Sie hier erreichen. Wie Nicol Bolas bereits darauf hingewiesen hat, ist das Clipping sehr wichtig, wenn ein Primitiv die Ebene "z_eye = 0" schneidet. Und die Interpolation für solche Primitiven wird völlig bedeutungslos (und für einen Knoten genau bei 'z_eye = 0' würden Sie sogar mit einer Division durch Null enden). Die Überprüfung gegen '-1 <= x, y, z <= 1' in NDC ist nicht äquivalent zu '-w <= x, y, z <= w' im Clipraum, da die Punkte, die 'w <= x erfüllen, y, z, <= -w (hinter der Kamera) würde das auch erfüllen. Ich habe keine Ahnung, was du mit "NDC.w" meinst, denn in NDC gibt es kein w (oder es wäre 1). – derhass
Um dies zusammenzufassen: Meiner Meinung nach, Clipping im Bildschirm Raum macht nicht den geringsten Sinn (Uness Sie tun die [Rasterisierung selbst in homogenen Koordinaten] (http://www.cs.unc.edu/~olano/papers/2dh-tri /)), und es wird viel langsamer sein. Also ich weiß nicht, was Sie hier gewinnen. – derhass
Danke für die Klärung der Sache. Ich habe Nicols Antwort dann nicht richtig verstanden (ich dachte, er meinte, dass die Mathematik auch im Falle eines Clippens gegen z_eye = 0 funktionieren könnte). In meinem Code benutzte ich NDC.w als Kameraraum z des Scheitelpunktes. Zugegeben, das macht nach der perspektivischen Teilung keinen Sinn. – pseudomarvin