Wie arbeitet der Z-Buffer von Direct3D?
-
wie arbeitet der Z-Buffer von Direct3D? Nach der Perspektivischen Projektion und der Umwandlung dieser Homogenen Koordinaten in Kartesische liegen ja die z-Werte in einem Bereich von 0 bis 1, wobei der Z-Buffer aber nicht linear, sondern hyperbolisch "angeordnet" ist. Wenn ich jetzt zwei z-Werte gegeben habe z. B. z1 und z2 wie kann ich dann zwischen diesen Interpolieren?
Meine Ideen/Feststellungen
1. wenn ich linear Interpoliere kommt nur Müll raushttp://www.codeguru.com/cpp/misc/misc/math/article.php/c10123__3
f f*n f(z) = (f/(f-n)*z-fn/(f-n))/z = --- - --- * z f-n f-nf(n) = 0
f(f) = 1
In der Regel:
f((f-n)/2) != 0.5
f((f-n)/2) > 0.5f(z) kann man ja berechnen - also kann ich jetzt zwischen z1 und z2 einfach linear Interpolieren und erhalte die richtigen Werte, z. B.:
z1 = 0.1 und z2 = 0.6 delta=0.1
f(0.1)=...
f(0.2)=...
..
f(0.6)=...oh schön - etwas hyperbolisches auf etwas lineares zurückgeführt
das ständige einsetzen in f(z) ist ja aber etwas rechenaufwändig. Die Webseiten, die ich mit google gefunden haben lösen das etwas anders. Sie rechnen da irgendwie einen delta Wert aus, der dann bei jedem Schritt auf den Ausgangswert aufaddiert wird. Aber irgendwie verstehe ich es noch nicht... wie berechnet man so ein delta, auf das man dann immer aufaddieren kann?
mmmh wenn ich so überlege: wenn man irgendwie mit dem Kehrwert arbeitet dann ist es doch wieder lniear... mmh... hilf mich!
-
in screen-koordinaten wird 1/z interpoliert weil z wegen der perspektivischen transformation nicht mehr linear ist.
man koennte dir uebrigens besser folgen, wenn du kurz umreisst, was du vor hast...
-
er möchte die z-aufteilung des zbuffer linear machen.
@VW
man könnte das so machen, ist aber extrem aufwendig, intern arbeitetn die grakas auch ein wenig anders und deswegen kannst du eher einen float framebuffer nehmen, statt z zu linearisieren, ist fixer und güsntiger.
-
der sinn und zweck des zbuffer ist ja, z-werte einzelner pixel miteinander vergleichen zu koennen.
diese z-werte werden entlang der kanten eines polygons interpoliert.
da man bei der perspektivischen transformation die x,y-koordinaten der polygon-eckpunkte durch z geteilt hat, verlaeuft z (wie auch alle anderen parameter die man interpolieren moechte) nicht mehr linear ueber das polygon, stattdessen aber 1/z.
dh wuerde man z linear ueber das polygon interpolieren, waeren diese werte zwar an den eckpunkten korrekt, innerhalb eines polygons aber nicht.
es wuerde nun aber keinen sinn machen, pro pixel eine zusaetzliche division durchzufuehren, nur um das tatsaechlich z in den zbuffer einzutragen, denn fuer den eigentlichen z-vergleich aendert sich lediglich das vorzeichen:
z1 < z2 => 1/z1 > 1/z2
ein weiterer vorteil von 1/z ist der, dass der zbuffer nahe am betrachter die hoechste praezision hat.
ein floating-point zbuffer ist nicht unbedingt notwendig aber praktikabel, weil die integer-darstellung aller positiven floats streng monoton steigend ist (also nicht innerhalb der fpu durchgefuehrt werden muss) und alle negativen z sowieso dem clipper zum opfer gefallen sind.
-
diese z-werte werden entlang der kanten eines polygons interpoliert.
wie? sagen wir z1 = 0.1 und z2=0.6 - nehmen wir an der Scanline Algorithmus hat festgestellt, das
5 Spans zu rendern sindmit einem Linearen Z-Buffer erhalte ich folgendes Ergebnis:
Für den 1. Span ist die Tiefe 0.1
Für den 2. Span ist die Tiefe 0.2
Für den 3. Span ist die Tiefe 0.3
Für den 4. Span ist die Tiefe 0.4
Für den 5. Span ist die Tiefe 0.5wie sieht das jetzt mit 1/z aus?
-
du nimmst an den eckpunkten einfach den kehrwert von z und interpolierst das linear - also bei deinem beispiel:
z1= 0.1 => iz1= 10.0
z2= 0.6 => iz2= 1.6667span1: 10.0000
span2: 7.9167
span3: 5.8333
span4: 3.7499
span5: 1.6667das was dann im rahmen von direct3d tatsaechlich im zbuffer eingetragen wird ist natuerlich noch entsprechend der zbuffer-praezision skaliert...
edit:
im fall eines polygons wuerde diese interpolation dann entlang der kanten auf der linken und rechten seite ausgefuehrt, sodass man ein fuer jede scanline ein ein zlinks,zrechts erhaellt und die wieder entsprechend entlang der scanline interpoliert, also einen z-wert fuer jeden pixel erhaelt.
weil 1/z aber linear ist, heisst das, dass die verlaeufe von z innerhalb der einzelnen scanlines alle gleich sind!
-
hey danke!
um wieder auf die echte Tiefe zu kommen muss ich wieder
den Kehrwert nehmen:
span1: 10.0000 => 0.1
span2: 7.9167 => 0.126
span3: 5.8333 => 0.171
span4: 3.7499 => 0.267
span5: 1.6667 => 0.6noch eine Frage:
das was dann im rahmen von direct3d tatsaechlich im zbuffer eingetragen wird ist natuerlich noch entsprechend der zbuffer-praezision skaliert...
was soll die zbuffer-präzision sein? Meinst du jetzt 16 Bit oder 32 Bit? wir das ganze dann wieder auf 0 bis 1 skaliert oder wie?
außerdem: woher weißt du das - wo kann man das nachlesen
webseite/buch???
-
was soll die zbuffer-präzision sein?
Meinst du jetzt 16 Bit oder 32 Bit?ja genau. die grafikkarte nutzt fuer gewoehnlich 24bit weil die oberen 8 fuer den stencil-buffer reserveriert sind, der gleichzeitig mit dem zbuffer ausgelesen und verglichen wird.
problematisch ist eben, dass bei einem wertebereich von 0..1 der kehrwert +inf..1 ist (wobei inf eigentlich nicht auftritt, weil das der near-clipping plane entspricht), man sich da also was geschicktes ueberlegen muss, um das auf integer zu mappen - oder eben einfach in floating point lassen.woher weißt du das - wo kann man das nachlesen???
ich hab irgendwann in den 90ern mal nen software-renderer programmiert, dabei ist einiges an mittlerweile unnuetzem wissen angefallen, von dem ich nicht mehr genau sagen kann, woher es stammt. aber das sollte eigentlich alles im foley (computer graphics: principles and practice) zu finden sein...
ausserdem ist ein dreieck im dreidimensionalen raum offensichtlich linear und man kann leicht mathematisch beweisen, was mit der linearitaet der eckpunkt-parameter passiert, wenn man eine 2d-transformation macht.
darfst du aber gerne alleine machen
-
Vertexwahn schrieb:
wo kann man das nachlesen
webseite/buch???in jedem buch in dem ein softwarerasterizer geschrieben wird.
-
@raspo:
ich interessiere mich halt dafür was die Leute für Bücher lesen
-
Vertexwahn schrieb:
@raspo:
ich interessiere mich halt dafür was die Leute für Bücher lesen
schau mal hier
