Game Development Stack Exchange is a question and answer site for professional and independent game developers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I render a normal and a depth image of a scene. Then I want to reuse these two images to do further texture/image processing in a second fragment shader. I use a framebuffer with 3 textures attached to it. 2 for the normal and the depth textures and one is supposed to contain the final processed image. The problem is, that I can't get the first two images to the second fragment shader to use them as texture samplers.

Here is my code: First I create a fbo and attach 3 textures to it.

    // create FBO
glGenFramebuffers(1, &Framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, Framebuffer); 

glGenTextures(1, &renderedNormalTexture);   
//glBindTexture, glTexImage2D, glTexParameteri ... left out for clarity 
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderedNormalTexture, 0);

glGenTextures(1, &renderedDepthTexture);    
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, renderedDepthTexture, 0);

glGenTextures(1, &edgeTexture); 
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, edgeTexture, 0);

ndbuffers[0] = GL_COLOR_ATTACHMENT0;
ndbuffers[1] = GL_COLOR_ATTACHMENT1;
ndbuffers[2] = GL_COLOR_ATTACHMENT2;
glDrawBuffers(3, ndbuffers);

Fragment shader 1: This is the first fragment shader which outputs 2 textures to position 0 and 1

in vec3 position_worldspace;
in vec3 normal_cameraspace;
in vec4 vpos_to_fragment;
uniform float zmin;
uniform float zmax;
layout(location = 0) out vec3 normalcolor;
layout(location = 1) out vec3 depthcolor;
void main() {   
normalcolor = normalize( normal_cameraspace ) * 0.5 + 0.5;  // normal out
  vec4 v = vec4(vpos_to_fragment);
v /= v.w;
float gray = (-v.z - zmin) / (zmax - zmin); 
depthcolor = vec3(gray);  // depth out                              

fragment shader 2:
And the second fragment shader which is supposed to receive two texture samplers from position 0 and 1 and do sth. with them:

uniform sampler2D normalImage;         
uniform sampler2D depthImage; 
uniform float width;
uniform float height;
in vec2 UV;
layout(location = 2) out vec3 color;

void main() {  
vec3 irgb = texture2D(normalImage, UV).rgb; 
// do sth here...
color = irgb ;

And finally the rendering step: Maybe I am mistaken here. I render the geometry/scene (once?!) and apply two fragment shaders.

RenderScene(); // render geometry


GLuint nID = glGetUniformLocation(FragmentShader2, "normalImage");
GLuint dID = glGetUniformLocation(FragmentShader2, "depthImage");

glBindTexture(GL_TEXTURE_2D, renderedNormalTexture);
glProgramUniform1i(FragmentShader2, nID, 0);

glBindTexture(GL_TEXTURE_2D, renderedDepthTexture);
glProgramUniform1i(FragmentShader2, dID, 1);

Now what I get is either nothing or a wrong colored image.

share|improve this question
You are doing it wrong. You should first make an FBO to contain the Normal and the Depth. Fill that FBO with the data you want. Use those FBO's textures to draw to the screen with the latter fragment shader. Also you can't "apply" a fragment shader, you have to draw something for it to have an effect. So for the second pass, you want to draw a fullscreen quad. – akaltar Jul 16 '13 at 8:33
Hey, thanks for your answer. The fullscreen quad worked. I can now display both (normal and depth) textures on the fullscreen quad. But actually thats not what I want. I'd like to extract information (like edges) from both textures and read these information with cuda from the resulting texture. If I draw the fullscreen quad I have to use glBindFramebuffer(GL_FRAMEBUFFER, 0); which significantly slows down the rendering. Is it impossible to use layout(location = 2) out vec3 color; in the second fragment shader and to render to that third texture? – urbste Jul 16 '13 at 9:28
You should create another FBO then, as I know you cant read / write to the same FBO at a time, and even if yes, its slow, its generally a better idea to use another FBO. What shader are u using to render the fullscreen quad to the screen? if you use the second shader, it should be the shader that extracts those edges, and if u render the fullscreen quad with that, it should give you the image you want. – akaltar Jul 16 '13 at 16:52
Yep for the second pass I use a vertex shader that simply passes the texture coordinates gl_Position = vec4(vertexPosition_modelspace,1); UV = (vertexPosition_modelspace.xy+vec2(1,1))/2.0; And I extract edges in the second fragment shader. It gives me the image I want! Its just that I want to do further processing with that image and need very fast read/write operation. I just started with shader programming and I have to adapt to that OpenGL/GLSL way of having a context and a geometry and so on ... thanks anyways, problem solved so far ;) – urbste Jul 17 '13 at 6:20
Then as I already recommended, use another FBO, by choosing the correct format, you might make it real fast( if performance it a problem ). I recommend this GPU gems article for learning more about FBO performance, even tough it's about deferred – akaltar Jul 17 '13 at 16:04

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.