Wo wird bei OpenGL gesampelt?
-
Angenommen ich hab ein Dreieck in OpenGL, das nicht geclippt werden muss und sichtbar für den Benutzer ist. Nun werden ja die Objektkoordinaten v1, v2, v3 ja erst mit der modelview Matrix multipliziert um die Koordinaten in Bezug auf das Kamerakoordinatensystem zu berechnen. Anschließend wird mit der Projektionsmatrix multipliziert und durch w geteilt um Normalisierte Device Koordinaten zu erhalten.
Beim Rasterisieren werden jetzt die Normalisierten Device Koordinaten mit der Modelviewmatrix multipliziert , die die z-Koordinaten unverändert lässt und x bzw. y entsprechend des Viewports skaliert.
Kurze Zusammenfassung:
vN = projection * modelview * vN vN.x /= vN.w vN.y /= vN.w vN.z /= vN.w vN = viewport * vN
Nun werden die Koordinaten weiter an den Rastersierer übergeben, wo das Dreieck an bestimmten Positionen abgetastet/gesampelt wird.
Genau hierauf bezieht sich meine Frage. Wo wird das Dreieck abgetastet? Im folgenden soll nur ein Sample pro Pixel abgetastet werden (Single Sample Rasterization). Antialiasing (multi-sample rasterization) soll dabei ignoriert werden.
1. Idee:
(2.5|2.5) +-----+-----+-----+ | | | | | + | + | + | |(0|2)|(1|2)|(2|2)| +-----+-----+-----+ | | | | | + | + | + | |(0|1)|(1|1)|(2|1)| +-----+-----+-----+ | | | | | + | + | + | |(0|0)|(1|0)|(2|0)| +-----+-----+-----+ (-0.5|-0.5)
Der Viewport geht von -0.5 bis 2.5 jeweils in x als auch in y Richtung.
1. Frage: Das geht doch in OpenGL gar nicht, weil Dreiecke nach dem Clippen im Bereich von (0,0) bis (3,3) liegen, es also keine Vertices mit x bzw. y Koordinaten < 0.0 gibt - liege ich da richtig?
2. Idee:
(3|3) +---------+---------+---------+ | | | | | | | | | + | + | + | |(0.5|2.5)|(1.5|2.5)|(2.5|2.5)| | | | | +---------+---------+---------+ | | | | | | | | | + | + | + | |(0.5|1.5)|(1.5|1.5)|(2.5|1.5)| | | | | +---------+---------+---------+ | | | | | | | | | + | + | + | |(0.5|0.5)|(1.5|0.5)|(2.5|0.5)| | | | | +---------+---------+---------+ (0|0)
Die Samplepositionen sind jetzt immer an "half-integer" Positionen.
2. Frage: Ist das so richtig?
-
in D3D10 hat microsoft die selben rasterization rules eingefuehrt wie opengl sie immer hatte:
http://msdn.microsoft.com/en-us/library/cc627092(VS.85).aspx
das sollte alle fragen beantworten.
-
ah okay - dann ist es genauso wie bei meiner 2ten Idee und so wie ich es in meinen Software Rasterizer programmiert habe.
Ich hatte im Hinterkopf noch immer die Rasterization Rules von D3D9 (http://msdn.microsoft.com/en-us/library/bb147314(VS.85).aspx) - was mich bei den D3D9 Raster Rules weiterhin wundert ist, warum nach dem Viewport Mapping eine "Bildschirmkoordinate" eine x oder y Wert kleiner 0 annehmen soll - das geht doch gar nicht - oder?
Das erinnert mich gerade an das Clipping Paper von Nvidia wo ja wegen der teueren Clipping Operatonen etwas großzügiger gerendert wird mit einem größeren Frustum - und dann einfach die überflüssigen Pixel discarded werden. In diesem Szenario gäbe es dann sehr wohl Koordinaten die da im Bereich [-0.5;0] liegen. Hat es eventuell damit etwas zu tun?