openglframebufferdeferred-renderingdeferred-shading

Making position buffer for deferred rendering - noise in the generated textures


I'm trying to implement deferred shading for the first time but I'm having trouble generating the buffers. I've started trying to make just the position buffer so here is the relative code:

glGenFramebuffers(1, &gBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, gBuffer);

glGenTextures(1, &gPosition);
glBindTexture(GL_TEXTURE_2D, gPosition);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, 1024, 1024, 0, GL_RGB, GL_FLOAT,
    NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gPosition, 0);
unsigned int rbo;
glGenRenderbuffers(1, &rbo);
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 1024, 1024);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
    std::cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" << std::endl;


glBindFramebuffer(GL_FRAMEBUFFER, 0);

The framebuffer is successfully completed and we go to the main loop:

glBindFramebuffer(GL_FRAMEBUFFER, gBuffer);
glActiveTexture(gPosition);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, 1024, 1024);
mat4 modelMatrix = mat4(1);
glUseProgram(gShader);
glUniformMatrix4fv(mgLoc, 1, GL_FALSE, &modelMatrix[0][0]);
glUniformMatrix4fv(pgLoc, 1, GL_FALSE, &projectionMatrix[0][0]);
glUniformMatrix4fv(vgLoc, 1, GL_FALSE, &viewMatrix[0][0]);
glBindVertexArray(objVAO);
glDrawArrays(GL_TRIANGLES, 0, objVertices.size());
glBindFramebuffer(GL_FRAMEBUFFER, 0);

And this is the fragment shader:

layout (location=0) out vec3 gPosition;
in vec3 vertex_world;
out vec4 FragColor;

void main()
    {

     FragColor=vec4(vertex_world,1.0);


    }

The position buffer seems fine :

enter image description here

However, if you look at my shader I haven't given a value to gPosition. It seems like the buffer is just taking the output fragColor.

This is what I plan to do but it gives me wrong results:

layout (location=0) out vec3 gPosition;
in vec3 vertex_world;


void main()
{

     gPosition=vertex_world;


}` 

It does pass something to the position buffer but you will see that it's quite strange: enter image description here

What could be wrong?

Edit/Solved

It turns out that I had to define gPosition as a vec4 in the fragment shader. It works perfectly now. So the new question is why did it work now?


Solution

  • glActiveTexture does not take a texture name, but selects the active texture unit (GL_TEXTURE0 + n) – yeah, the name is misleading.

    Anyway, it seems like you want to bind the position buffer texture before rendering to it. Why? If you actually did that you might end up with a feedback loop – see https://www.khronos.org/opengl/wiki/Framebuffer_Object#Feedback_Loops. You're fine as long as you don't sample from it, but the mere possibility of having a feedback loop might throw you into a slower codepath. So try do not do that. You've bound the texture as an attachment to the FBO, that's enough.

    As far as rendering an actual position buffer is concerned: Why do that in the first place? Just use a depth buffer texture (instead of renderbuffer) and reconstruct the position from the single depth value and un-projection.