2010-04-07 3 views
5

Soweit ich weiß, können wir nicht den Z (Tiefe) Wert in OpenGL ES 2.0 lesen. Also frage ich mich, wie wir die 3D-Welt Koordinaten von einem Punkt auf dem 2D-Bildschirm bekommen können?OpenGL es 2.0 Lesen Tiefe Puffer

Eigentlich habe ich einige zufällige Gedanken könnte funktionieren. Da wir den RGBA-Wert unter Verwendung von glReadPixels lesen können, können wir den Tiefenpuffer duplizieren und in einem Farbpuffer speichern (z. B. ColorforDepth). Natürlich muss es eine nette Konvention geben, damit wir keine Informationen über den Tiefenpuffer verlieren. Und wenn wir die Weltkoordinaten eines Punktes benötigen, fügen wir diesen ColorforDepth-Farbpuffer an den Framebuffer an und rendern ihn dann. Also, wenn wir glReadPixels verwenden, um die Tiefeninformation in diesem Frame zu lesen.

Allerdings wird dies zu 1 Frame-Flash führen, da der Farbpuffer ein seltsamer Puffer aus dem Tiefenpuffer übersetzt wird. Ich frage mich immer noch, ob es einen Standard Weg gibt, um die Tiefe in OpenGL es 2.0 zu bekommen?

Thx im Voraus! :)

Antwort

7

Mit einem FBO können Sie rendern, ohne die Ergebnisse anzuzeigen. Wenn Sie in ES 2.0 sind, kann Ihr Fragment-Shader als Teil von gl_FragCoord auf die Tiefe des aktuellen Fragments (in Fensterkoordinaten) zugreifen, sodass Sie diese in den Farbpuffer schreiben können. Verwenden Sie glReadPixels, um das Ergebnis zurückzuerhalten und fortzufahren. Alternativ können Sie den World-Space z als variierendes laden und das von Ihrem Fragment-Shader schreiben, falls das einfacher ist.

Um sich davon zu überzeugen, versuchen Sie einen schnellen Shader zu schreiben, der gl_FragCoord.z ​​in geringer Präzision, z. nur

gl_FragColor = vec4(vec3(gl_FragCoord.z), 1.0); 

Sie sollten eine Graustufe mit der Intensität der Farbe erhalten, die Tiefe darstellt. Da Sie sich in Fensterkoordinaten befinden, reicht die Intensität von 0.0 (nächstmögliches nicht abgehängtes Fragment) bis 1.0 (weitestmögliches nicht abgehängtes Fragment). Um nicht zu viel Genauigkeit zu verlieren, ist es wahrscheinlich hilfreicher, den Wert zwischen den Komponenten aufzuteilen, da Ihr Hersteller höchstwahrscheinlich keine Gleitkomma-Zielpuffer unterstützt.

+0

Tommy, könnten Sie bitte etwas mehr über das Teilen von gl_FragCoord.z ​​zwischen Komponenten sagen. Nicht folgend. Prost. – dugla

+1

@dugla Wenn Tiefe eine 32-Bit-Ganzzahl wäre, könnten Sie nur 8-Bits davon in jedem von R, G, B und A machen. In der Praxis würden Sie also etwas tun, wie den Vektor zu multiplizieren (1, 256) , 65536, 16777216) ', dann speichere jede Komponente dieses Vektors mod 1.0 in den relevanten Kanälen. Sie können später rekombinieren, indem Sie sie durch die relevanten Komponenten dividieren und addieren. – Tommy

0

Ich benutze einen Grund ray zum Gießen eines 3D-Objekt aus einem Touch-Screen Kommissionierung. Tatsächlich berechne ich den Schnittpunkt zwischen der Bildschirmnormalen am Berührungspunkt und einer Kugel, die mein Objekt enthält. Für eine sehr präzise Auswahl oder komplizierte Form müssen Sie mehrere Kugeln verwenden.

Sie können auch einige Schlüsselpunkte Ihres Objekts im 2D-Raum Ihres Bildschirms projizieren (Multiplizieren Ihres 3D-Punkts mit Ihrer Transformationsmatrix) und dann einen 2D-Vergleich (Abstand) mit Ihrem Berührungspunkt vornehmen.

0

Ich würde auch gerne in der Lage sein, Werte im Tiefenpuffer zu lesen, aber Forschung zeigt an, dass es nicht getan werden kann.

wie Vincent vorschlägt, wenn Sie einfache Formen wie Kugeln haben, ist Ray-Casting wahrscheinlich besser.

für komplexere Formen Tho, ich denke, um das Objekt zu einem (potentiell kleinen) dem Rendering-Off-Screen-Puffer, manuell eine der Farbkomponenten jeden Eckpunkts Zuweisen die Tiefe dieses Scheitelpunktes zu sein, und dann Lesen der Farbwerte. Das ist etwas unelegant und nervig, und erfordert, dass Sie den Objektraum in den Bildschirmraum umwandeln können (ich benutze meine eigenen Quaternionen, um die Matrizen zu steuern, damit sich das kümmert). Es kann einen Weg mit Shadern geben, um die Tiefeninformation in den Farb- oder Schablonenpuffer zu schreiben (hat GL ES sogar einen Schablonenpuffer?)

Wenn jemand einen saubereren Ansatz hat, würde ich ihn gerne hören.