Effizientes Rendern in 3D-Textur

7

Ich habe eine vorhandene Tiefenstruktur und einige andere Farbtexturen und möchte die darin enthaltenen Informationen verarbeiten, indem ich sie in eine 3D-Textur rendere (basierend auf der in der Tiefenstruktur enthaltenen Tiefe, dh einem Punkt bei (x / y) in der Tiefenstruktur wird in der 3D-Textur auf (x / y / Textur (Tiefe, UV)) gerendert).

Das einfache Ausführen eines manuellen Zeichenaufrufs für jedes Stück der 3D-Textur (über glFramebufferTextureLayer) ist furchtbar langsam, da ich vorher nicht weiß, zu welchem ​​Stück der 3D-Textur ein bestimmtes Texel aus einer der Farbtexturen oder der Tiefenstruktur gehört. Dies bedeutet, dass der gesamte Prozess effektiv ist

for each slice
  for each texel in depth texture
      process color textures and render to slice

Also muss ich die Tiefenstruktur pro Slice vollständig abtasten und ich muss auch die Verarbeitung (zumindest bis zum Verwerfen;) für alle darin enthaltenen Texel durchlaufen.

Es wäre viel schneller, wenn ich den Prozess neu ordnen könnte

for each texel in depth texture
   figure out what slice it should end up in
       process color textures and render to slice

Ist das möglich? Wenn das so ist, wie?

Was ich eigentlich versuche: Die Farbtexturen enthalten Beleuchtungsinformationen (aus Sicht der Lichtansicht handelt es sich um eine reflektierende Schattenkarte). Ich möchte diese Informationen in der 3D-Textur sammeln und später zum Beleuchten der Szene verwenden. Insbesondere versuche ich, den Algorithmus für Cryteks Light Propagation Volumes zu implementieren.

TravisG
quelle
Nach einigen Recherchen scheint dies mit der GPGPU-Verarbeitung möglich zu sein, z. B. mit OpenGL-Compute-Shadern. Ich gehe jedoch davon aus, dass es einen technischen Grund gibt, warum OpenGL das direkte Schreiben in ein bestimmtes z nicht zulässt. Zerstört es den Cache?
TravisG

Antworten:

8

Es ist sehr einfach, dies in einem einfachen Zeichenaufruf zu tun, indem jedes Texel im Tiefenpuffer im Vertex-Shader iteriert wird. Sie können Punkte zeichnen, die so hoch sind wie die Tiefenpufferauflösung oder weniger, und im Vertex-Shader rufen Sie den Tiefenpufferwert ab und projizieren ihn in den Würfel, den die 3D-Textur abdeckt.
Sie können aus dem Vertex-Shader auswählen, auf welches Slice Sie den Punkt rendern möchten (z. B. in openGL übergeben Sie das Slice an die Variable gl_Layer ). Dann führen Sie im Fragment-Shader die gewünschten Berechnungen durch.

(Es gibt eine Erweiterung, die gl_Layer im Vertex-Shader unterstützt (GL_AMD_vertex_shader_layer). Sie können sie verwenden, wenn Sie können, oder Sie können einen einfachen Durchlauf-Geometrie-Shader verwenden, der nur den gl_Layer-Wert festlegt.)

Anastasios G.
quelle
Oh wow, das ist perfekt! Seltsam, ich habe ziemlich lange gesucht, konnte aber nichts darüber finden.
TravisG
Außerdem sollte ich erwähnen, dass gl_Layer Teil der OpenGL 4.2-Kernspezifikation ist. Es ist nur als Erweiterung erforderlich, wenn Sie GL 3.x
TravisG
gl_Layer im Geometrie-Shader wird von GL 3.2 unterstützt. Da eine Eingabevariable (schreibgeschützt) im Fragment-Shader von GL 4.3 unterstützt wird. Es wird im gl_Layer-Dokument erwähnt.
Anastasios G
Ja, aber nicht im Vertex-Shader.
TravisG
Tut mir leid ich lag falsch. Ich hatte eine Zeile aus der Spezifikation falsch gelesen, sie besagt nur, dass sie gegen die 4.2-Spezifikation geschrieben wurde. Die Erweiterung ist in der Tat nur eine herstellerspezifische Erweiterung, und NVIDIA-Treiber scheinen sie im Allgemeinen nicht zu implementieren.
TravisG