7
\$\begingroup\$

I have an existing depth texture and some other color textures, and want to process the information in them by rendering to a 3D texture (based on the depth contained in the depth texture, i.e. a point at (x/y) in the depth texture will be rendered to (x/y/texture(depth,uv)) in the 3D texture).

Simply doing one manual draw call for each slice of the 3D texture (via glFramebufferTextureLayer) is terribly slow, since I don't know beforehand to what slice of the 3D texture a given texel from one of the color textures or the depth texture belongs. This means the entire process is effectively

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

So I have to sample the depth texture completely per each slice, and I also have to go through the processing (at least until to discard;) for all texels in it.

It would be much faster if I could rearrange the process to

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

Is this possible? If so, how?

What I'm actually trying to do: the color textures contain lighting information (as seen from light view, it's a reflective shadow map). I want to accumulate that information in the 3D texture and then later use it to light the scene. More specifically I'm trying to implement Cryteks Light Propagation Volumes algorithm.

\$\endgroup\$
1
  • \$\begingroup\$ After some research it seems this would be possible with gpgpu processing, e.g. opengl compute shaders. But I assume there is some technical reason why OpenGL doesn't allow writing to a partcicular z directly. Does it destroy the cache? \$\endgroup\$
    – TravisG
    Commented Oct 24, 2013 at 15:09

1 Answer 1

8
\$\begingroup\$

It is very simple to do it in one simple draw call, by iterating every texel in the depth buffer inside the vertex shader. You will choose to draw points, as many as the depth buffer resolution or less, and in the vertex shader you will fetch the depth buffer value and project it into the cube, which the 3D texture covers.
You can choose from the vertex shader to which slice you want to render the point ( e.x. in openGL you pass the slice to the variable gl_Layer ). Then in the fragment shader, you do whatever calculations you want.

( There is an extension that supports the gl_Layer in the vertex shader (GL_AMD_vertex_shader_layer). You can use it if you can or you can have a simple pass through geometry shader that just sets the gl_Layer value )

\$\endgroup\$
5
  • \$\begingroup\$ Oh wow, that's perfect! Weird, I searched for a pretty long time but couldn't find anything about it. \$\endgroup\$
    – TravisG
    Commented Oct 25, 2013 at 9:25
  • \$\begingroup\$ Also, I should mention that gl_Layer is part of the OpenGL 4.2 core specification. It's only necessary as an extension if you want to keep to GL 3.x \$\endgroup\$
    – TravisG
    Commented Oct 25, 2013 at 14:40
  • \$\begingroup\$ gl_Layer in geometry shader is supported from GL 3.2 .As an input ( read only ) variable in fragment shader is supported from GL 4.3 . It is mentioned in the gl_Layer doc. \$\endgroup\$ Commented Oct 25, 2013 at 20:38
  • \$\begingroup\$ Yes, but not in the vertex shader. \$\endgroup\$
    – TravisG
    Commented Oct 26, 2013 at 0:41
  • \$\begingroup\$ Sorry, I was wrong. I had misread a line from the spec, it only says that it was written against the 4.2 specification. The extension is indeed just a vendor specific extension, and NVIDIA drivers generally don't seem to implement it. \$\endgroup\$
    – TravisG
    Commented Oct 27, 2013 at 13:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .