Registriert: Mo Jan 18, 2010 02:48 Beiträge: 5 Wohnort: Aachen
Programmiersprache: C++ / Java
Hi,
mein Ziel ist es, einige Würfel in ein Framebuffer Object zu rendern, das Resultat zurück in den Standard-Framebuffer zu malen und schlussendlich noch etwas (einen einfachen Quad) in den Standard-Framebuffer zu rendern, so dass es korrekt mit dem bereits gerenderten Zeug überlappt. Um dies zu erreichen, muss ich die Tiefendaten aus dem Framebuffer Object weiterverwenden. Deshalb habe ich eine Depth-Texture an das Framebuffer Object gebunden und verwende einen Shader, der die Tiefendaten aus der Textur ausließt und nach gl_FragDepth schreibt.
Der folgende Screenshot zeigt das Resultat:
Wie man deutlich erkennt, funktioniert das Überlappen nicht, wie es soll.
Ich habe eine Minimalanwendung geschrieben, welche das Problem reproduziert, mehr dazu später. Vor einigen Tagen spielte ich mit dem Code der Anwendung herum, während ich auf der Suche nach der Fehlerursache war, und habe folgendes festgestellt: Wenn ich die Near Clipping Plane nach hinten setze und die Far Clipping Plane nach vorne, den Quotienten aus beiden also verkleinere und somit die Präzision der Depthbuffer erhöhe, wird der beobachtete Effekt weniger stark ausgeprägt. Der nachfolgende Screenshot zeigt dieselbe Szene wie eben mit glDepthRange( 1, 50 ) an Stelle von glDepthRange( 0.1f, 100 ) im Original:
Nun schaut es so aus, als würden die Tiefenwerte - irgendwie - viel zu stark quantisiert werden. Aber warum? Es kann eigentlich nicht an der Präzision der Depth-Texture liegen, welche bei 24 bit liegt, da der Effekt genau gleich bleibt, wenn ich die Präzision hier auf 32 bit erhöhe. Würde es an dessen Präzision liegen, hätte man ja erwartet, dass die Intensität des Effektes weiter abnimmt, was sie aber nicht tut.
Mir fallen zwei mögliche Ursachen für das Problem ein, auch wenn ich keine davon zu erklären in der Lage wäre: Also entweder die Projektionsmatrix geht auf irgendeine Weise "kaputt", so dass der Quotient aus Near- und Far Clipping Plane überdimensionale Größen erreicht. Oder die übernormale Quantisierung wird in der Anweisung "gl_FragDepth = texture2D( depthtex, gl_TexCoord[0].xy ).a" im Fragmentshader verursacht.
Ich verwende SFML2 zwecks Erzeugung des Contexts und Abfangen von Benutzereingaben. Ist SFML2 auf dem System vorhanden, kann dieser Code zum Ausführen der Minimalanwendung verwendet werden: http://pastebin.com/yJgvQpnK
Würde mich sehr freuen, wenn jemand die Zeit findet, mal drüber zu schauen, denn ich weiß absolut nicht weiter. Mich würde erst einmal interessieren, warum es nicht funktioniert. Es so hinzubiegen, dass es dann geht, ist eine darauf aufbauende Geschichte
Übrigens funktioniert alles, wie es soll, wenn ich direkt alles in den Standard-Framebuffer rendere und den FBO auslasse.
Bin gerade etwas knapp mit der Zeit, aber ich glaube das Problem liegt darin das du eben keine Depth-Texture benutzt, sondern einen normalen sampler2D. Es wäre möglich, dass du sampler2Dshadow nehmen musst. Ich habe aber bisher noch nie Depth-Texturen im Shader verwendet.
Registriert: Mo Jan 18, 2010 02:48 Beiträge: 5 Wohnort: Aachen
Programmiersprache: C++ / Java
Coolcat hat geschrieben:
Bin gerade etwas knapp mit der Zeit, aber ich glaube das Problem liegt darin das du eben keine Depth-Texture benutzt, sondern einen normalen sampler2D. Es wäre möglich, dass du sampler2Dshadow nehmen musst.
Um ein Texel von sampler2DShadow zu lesen (z.B. per shadow2D, laut Wiki) benötigt man aber ein Koordinaten-Trippel statt eines Tupels. Was soll man hier denn als dritte Koordinate angeben?
Wenn ich mich recht erinnere werden die ersten beiden Koordinaten durch die dritte Koordinate geteilt, da man hier normalerweise eine Projektion benötigt. Jedenfalls müsstest du mit der dritten Koordinate gleich 1.0 das bekommen was du willst. Wenn das nicht klappt schau mal in die GLSL Spezifikation, da wird das ja irgendwo beschrieben sein.
Was ich für einen Wert als dritte Koordinate für shadow2D nehme, scheint keinen Unterschied zu machen - ich kann auch 0 oder 10 einsetzen, das Ergebnis sieht immer gleich aus.
Use texture coordinate coord to do a depth comparison lookup on the depth texture bound to sampler, as described in section 3.8.14 of version 1.4 of the OpenGL specification. The 3rd component of coord (coord.p) is used as the R value. The texture bound to sampler must be a depth texture, or results are undefined. (...)
Ein Blick in Abschnitt 3.8.14 zeigt das die dritten Komponente als Vergleichswert dient, so dass shadow2D direkt 0 oder 1 zurück gibt, je nachdem ob der Wert kleiner oder größer ist. Das ganze hängt aber von der Einstellung GL_TEXTURE_COMPARE_MODE ab, in der Default-Einstellung "NONE" hat die dritte Komponente wie du gemerkt hast keine Auswirkungen und shadow2D gibt dir hier einfach wie gewünscht den Tiefenwert.
Mitglieder in diesem Forum: 0 Mitglieder und 5 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.