2013-07-26 12 views
5

Ich möchte den Tiefenpuffer auf eine etwas unorthodoxe Art und Weise verwenden und ich wurde durch die gesamte Normalisierung, Skalierung und was auch immer dort passiert, sehr verwirrt.Wie verwende ich Tiefenpuffer, um Indizes zu speichern

Mein Plan ist es, einen räumlichen Hash-Algorithmus von einigen Jungs von AMD zu implementieren (link to pdf).

tl; dr-version: Beschleunigen Sie die Nearest-Neighbor-Suche, indem Sie 3D-Scheitelpunkte in ein Array von (flachen 2D) Tiefenstrukturen diskretisieren und die Tiefe auf die VertexID festlegen. Der Grund für die Verwendung von Tiefen-Texturen ist, dass es einige intelligente Tiefen-Tests gibt, um die Ergebnisse in einer sortierten Reihenfolge zu erhalten, aber das ist hier weniger wichtig.

Mein Problem ist, dass die VertexID offensichtlich eine ganze Zahl ist, von 0 auf die Gesamtmenge von Vertices Bereich ParticleCount, aber das nicht direkt verwendet werden kann, da der Ausgang des Vertex-Shader zu [-1..1) in OpenGL werden normalisierte (oder [0..1) in DirectX).

Mein Vertex-Shader hat also etwas wie folgt aus:

float depth = 2.0 * gl_VertexID/ParticleCount - 1.0; 
gl_Position = vec4(flatCoords, depth, 1.0); 

Diese Art von Arbeit ist, aber welche Werte tatsächlich gespeichert sind, in die Tiefe Textur auf die aktuelle Framebuffer verwirrt mich gebunden. Ich erhalte nicht den Unterschied zwischen dem Fließkomma-Tiefenpuffer und der Integer-Version, wenn ich nicht einmal echte Ganzzahlen ausgeben kann und wenn ich später aus der Tiefenstruktur lese, scheint alles auf [0..1] normalisiert zu sein, egal welches interne Format Ich setze (DepthComponent24, 32, 32f).

Kann mir jemand einen Rat geben, wie man die VertexIDs aus diesen Tiefenstrukturen herausholt?

Dank

+0

„* normalisiert auf [-1..1) in OpenGL (oder [0..1) in DirectX * "Die 1 ist in beiden Fällen inklusive. –

+0

Sie haben Recht, ein leichtes Versehen. Aber das Standardverhalten des Tiefentests löscht den Tiefenpuffer auf 1 und verwendet einen "weniger als" Vergleich, daher werden alle Punkte mit einer Tiefe von 1 gekeult. – Gigo

Antwort

1

Output vom Vertex-Shader in OpenGL nach Perspektive divide auf [-1,1] eingeclipst, das gl_Position.z/gl_Position.w in diesem Bereich bedeutet, sein muss. Der Tiefenwert, der tatsächlich im Tiefenpuffer gespeichert wird, wird jedoch unter Verwendung der Werte für den aktuellen Tiefenbereich (glDepthRange) in den Bereich von 0..1 neu zugeordnet. Standardmäßig ist der Tiefenbereich 0..1, die in Ihrem Fall letztlich enthält Werte von Schwimmer (gl_VertexID)/ParticleCount und damit die Tiefenpuffer also zu

depth_buf_value = 0.5 + 0.5 * gl_Position.z/gl_Position.w; 

übersetzt:

vertex_id = depth_buf_value * ParticleCount 
+0

Ok, das bestätigt, dass das, was ich versucht habe, hätte funktionieren sollen, aber es hat nicht funktioniert. Ich werde versuchen, bald zu diesem Projekt zurückzukehren, damit es funktioniert. – Gigo

+0

Ein anderer Gedanke, den ich hatte: Was ist mit Präzision? Das interne Format, das für den Tiefenpuffer verwendet wird, verwirrt mich etwas. Es wird wie ein Float behandelt, aber als normalisiertes int? Beeinflusst das die Reichweite, die dargestellt werden kann? Der ParticleCount könnte sehr wohl eine Million oder mehr sein, und ich muss in der Lage sein, den Partikelindex zuverlässig aus dem Tiefenpuffer wiederherzustellen. – Gigo

+1

Ein Gleitkommawert im Bereich 0..1 wird in das angegebene interne Format konvertiert. Sie sollten die gleiche Genauigkeit mit 24-Bit-Ganzzahlformat und dem Gleitkommaformat erhalten, da letztere eine 24-Bit-Mantisse (23 + implizites Vorlaufbit) hat, die zur Darstellung von Ganzzahlen ohne Bitverlust verwendet werden kann. Da es jedoch in OpenGL diesen Neuzuordnungsteil durchläuft, ist mindestens ein Bit dieser Genauigkeit verloren.Aber das lässt immer noch 23 Bits mit> 8mil unterschiedlichen Werten übrig. – camenomizoratojoakizunewake

Verwandte Themen