Efficent render to 3D texture

Developping 3D fluid simulation, I’m using the common technique in order to write to all layers of a 3D texture:

For each tex3D slice Do
Render a Quad with a shader program

However, as i have several RTT pass this solution uses a lot of CPU drawCall (depth*nbpass) and so is the bottleneck of my engine.

I’ve read here http://developer.download.nvidia.com/books/gpu_gems_3/samples/gems3_ch30.pdf that in directX:
instancing can be used to draw all slices in a single draw call, rather than
making a separate call for each slice. In this case, the instance ID can be used to specify
the target slice.

I see that Opengl offer a functionality in order to write different cubemap faces using gl_layer in a geometry shader.

So I decide to improve performance with a geometry shader that specify wich is the targetted slice of my 3D texture to write to.
(fbo binding :glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture3D, 0):wink:

But it doesnt work properly (all 3Dtexture is updated when i define a constant gl_Layer=0);
Q: Have you test it?
Q: Do i need glFramebufferTexture working on my HW to do this?

I also see that gl_layer is used to output differents 2D textures of a TEXTURE_2D_ARRAY…
Q:Would it be a good thing for performances to reorganise my 3D texture as a 2D texture array?


Dev on QTX275/QuadCore Q8300

Instanced rendering to 3D texture should work. Use gl_InstanceID to select a layer. Yes, you need glFrambufferTexture to be supported by your hardware.

Hmm, forgive me for intruding, but can you actually attach a 3D texture as a render target to a FBO?

Hmm, forgive me for intruding, but can you actually attach a 3D texture as a render target to a FBO?

You can attach a 2D slice of the texture to an FBO. You can also attach a full mipmap of the 3D texture for layered rendering, which is what Randall is talking about.

In relation to this topic, what would be the most effective way of rendering to a 3D texture in a specific slice order, possibly part of a slice as well, to make use of calculations from previous processed slice when processing the next one.

I know you can specify active layer in a 3D texture using glFramebufferTexture3DEXT and then calling glDrawArrays or glDrawElements with vertices specifying two triangles or a quad.

However, several glDraw calls and especially glFramebufferTexture3DEXT is expensive.

You can also use a geometry shader and an array of vertices to perfrom layered rendering of a 3D texture with only one glDraw call. However, it seems that these primitives would not be processed in an order for next slice to use the result from the previous rendered one.

Suggestions? Using OpenCL?

Other questions: Is geometry instancing useful for processing of let’s say 1000 quads, over regular one call glDrawArrays?

I quote only the most “related to my work” technique:
Actually, target a layer using [b]glFrameBufferTexture/b and gl_layer=gl_instanceID on 3D texture work great in combination with glDrawInstanced.

However I want to develop a 2 pass technique based on patch instancing:
-1st pass: generate triangle patches via Geometry Shader that match region where texture3d have to change (target matrix region)
-2e pass:render generated patches without Instancing (solve linear local)
This way only suffisant texels will target by the 2e pass.
It could be a cool framework in order to solve 3D matrix with a lot of zeros…( Tell me if I’m wrong…:/)

But I have a huge problem to set gl_layer=int(vertexposition.z*NbLayers) without drawinstanced:
Doing it I always output to gl_layer 0 !!..:frowning:

Is it a driver issue or something i missed in the spec ?
Any advice would be glad.

PS: To answer the last post : instancing has no notable performance improvement over not instanced geometry as number of slice never exceed 128.
so it may be a good idea to use TextureArray layered Texture3D…but you should need several FBOs… I have not bench it but think it can be very expensive…

Okay I went wrong with some code…Actually all works fine