PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : OpenGL: Werte des Tiefenpuffers


Marscel
2014-06-28, 15:02:00
Meine Szene besteht aus ein paar wenigen Dreiecken im ansonsten leeren Raum, auf dem Monitor wird überwiegend also nur der glClearColor zu sehen sein.

GL_DEPTH_TEST ist aktiviert und glClear auf das GL_DEPTH_BIT auch.

Meine Frage, wenn ich nun glReadPixels mit GL_DEPTH_COMPONENT anhand der Cursorkoordinaten auslese, dann kriege ich Z-Werte zurück, die etwas irreführend sind. Und da das, was ich mit den Z-Werten machen will, nicht zuverlässig funktioniet, sind die gerade verdächtig. Angenommen, die Near- und Farplane sind vernünftig gesetzt, und 32bit Tiefenwerte sind genug, dann sollte doch, wann immer ich in den leeren Raum klicke, der Z-Wert 1 sein, und umgekehrt, wenn ich auf einen Pixel mit Fragment darunter, kleiner 1 sein, ist das richtig?

Wenn ja, ich manipuliere den Wert nicht im Fragmentshader, was könnte dazu führen, dass die Z-Werte sich z.T. nicht mit den Fragmenten decken? Mal gibt es im leeren ein Wert kleiner 1, mal auf einem Fragmentpixel einen Wert gleich 1.

Marscel
2014-06-29, 01:24:33
So siehts aus, wenn man gl_FragCoord.z als Grauwert ausgibt, also je heller, desto näher an 1.

http://abload.de/img/chipf0sfh.jpg (http://abload.de/image.php?img=chipf0sfh.jpg)

Das ist nicht das, was man eig. erwartet, richtig?

AwesomeSauce
2014-06-29, 02:10:16
Wäre hilfreich, wenn du folgendes noch anfügen könntest:
- benutzte Projectionmatrix
- near / far planes
- ganzer glReadPixels command (für Formate)

In OpenGL hat alles vor der Kamera eigentlich negative z-Werte (also linear Screen Space), also verwirrt mich die gegebene Ausgabe von gl_FragCoord.z doch etwas.
Und ja, falls du den Depth Buffer direkt ausliest, sollte alles auf der Far-Plane einen 1.0 depth value haben, alles davor einen tieferen Wert. Um den linearen Tiefenwert (Distanz zur Camera-Plane) zu erhalten, müsste man noch rückprojezieren:

z_e = 2*zFar*zNear / (zFar + zNear - (zFar - zNear)*(2*z_b -1));

wobei z_e für die Tiefe im Camera/Eye Space und z_b für den Tiefenwert im Depthbuffer stehen. Was kommen für Werte raus, wenn du diese Rückprojektion vornimmst?

Marscel
2014-06-29, 04:51:42
Wäre hilfreich, wenn du folgendes noch anfügen könntest:
- benutzte Projectionmatrix
- near / far planes
- ganzer glReadPixels command (für Formate)

glm::perspective(80.0f, aspect, 0.1f, 100.0f)

Das 0.1f-100.f sind Werte, die ich aus einem der Tutorials habe. Für das, was ich noch vorhabe, hören die sich gut an. Habe aber auch schon variiert, so streuen sich die Z-Werte allerdings nur anders auf [0,1].

glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &z);

Und z ist ein float.

wobei z_e für die Tiefe im Camera/Eye Space und z_b für den Tiefenwert im Depthbuffer stehen. Was kommen für Werte raus, wenn du diese Rückprojektion vornimmst?

Werte zwischen near und far. Tiefenpufferwerte liegen bei 0.90 bis 1 (+ sind je nach Perspektive total falsch/daneben), mappen sich hier dann auf 1.x bis 100.

AwesomeSauce
2014-06-29, 13:39:38
Werte zwischen near und far. Tiefenpufferwerte liegen bei 0.90 bis 1 (+ sind je nach Perspektive total falsch/daneben), mappen sich hier dann auf 1.x bis 100.
Das klingt nicht schlecht, bis auf die Bemerkung in Klammern. Der Depthbuffer ist nicht linear (Objekte nahe an der near plane haben höchste Tiefenauflösung), also können Werte von 0.9 bis 1.0 für die oben gezeigte Szene durchaus Sinn ergeben.

Wie gross ist das gezeichnete Objekt? Wo sind Kamera und Objekt positioniert? Wäre es möglich, mal den ganzen Depthbuffer auszulesen und als Bild darzustellen?

Edit: In meiner Szene, mit denselben Near/Far-Planes, zeigt mein Depthbuffer für ein Fragment mit Eye-Space z-Wert von ca. -7.5 (also 7.5 von der Cam-Plane entfernt, vor der Kamera) einen Depth-Value von ca. 0.988 an.
Wie gesagt, die Near/Far-Planes waren 0.1/100.0, also genau wie bei dir. Alles von 7.5 bis 100 muss also in den letzten 0.012 vom Depth-Buffer aufgelöst werden. Das zeigt, wie schlecht die Auflösung schon ab geringer Distanz bei dieser Near/Far-Plane Kombo ist.

del_4901
2014-06-29, 15:15:28
Ist normal, da der z Buffer nicht linear ist. NDC bei OGL für Z ist auch zwischen -1 und 1.

ScottManDeath
2014-06-29, 16:27:06
OpenGL Pixel Koordinaten sind Y-invertiert im Kontrast zu den ueblichen Mauskoordinaten, so dass man da leicht versehentlich den falschen Pixel interpretiert...

AwesomeSauce
2014-06-29, 16:41:50
OpenGL Pixel Koordinaten sind Y-invertiert im Kontrast zu den ueblichen Mauskoordinaten, so dass man da leicht versehentlich den falschen Pixel interpretiert...
Stimmt, da war mal was. Das dürfte die falschen/unsinnigen Werte für eine bestimmte x/y-Koordinate erklären.

Marscel
2014-06-29, 17:45:42
OpenGL Pixel Koordinaten sind Y-invertiert im Kontrast zu den ueblichen Mauskoordinaten, so dass man da leicht versehentlich den falschen Pixel interpretiert...

Ach, verdammt. Ich hatte noch geprüft, dass mir Qt oben links 0,0 zurückgibt und noch gedacht, so isses doch auch in OpenGL, statt unten links. Irrtum. Jetzt gibts wenigstens korrekte Z-Werte. Danke.

Wie gross ist das gezeichnete Objekt? Wo sind Kamera und Objekt positioniert? Wäre es möglich, mal den ganzen Depthbuffer auszulesen und als Bild darzustellen?

Das war wohl auch ein Ausgabefehler, war wohl zu spät gestern. Als ich jetzt den Z-Puffer als Bitmap gelesen habe (rechts) und nochmal einen Minimalshader für gl_FragCoord.z benutze (links), dann deckt sich das auch:

http://abload.de/img/chipzypjdp.jpg (http://abload.de/image.php?img=chipzypjdp.jpg)