2

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?

John Katsantas
  • 571
  • 6
  • 20
  • 1
    As a side note: storing the position in the g-buffer is a total waste of memory bandwidth. All what is needed is a depth buffer (which you want to use anyway), and you can later reconstruct the 3D position in any relevant space from the depth and the 2D screen space position. – derhass Dec 26 '18 at 00:58

1 Answers1

3

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.

datenwolf
  • 159,371
  • 13
  • 185
  • 298
  • As you may have noticed I have no idea what I'm doing. Or at least I didn't when first writing this. I followed tutorials precisely and at some point I started moving things around hoping it will work. Your comments have been very helpful. I think I found what was causing the trouble though but I can't understand why it did. It turns out I had to define the output as a vec4 in the second case. Do you know why that would make such a difference? – John Katsantas Dec 25 '18 at 14:29