Can't get G-Buffers work correctly

Hello!

I have tried to implement deferred rendering for a week already :frowning:
Before I can go forward to the lighting calculations g-buffers must be correct.
Color/Texture buffer is fine, but when I enable only positions or normals then I donā€™t see nothing on the screen. Iā€™m sure that problem is somewhere in the following code.

My rendering pipeline:

1) Clear scene
2) Bind FBO with MRT
3) Bind shader
4)
glGetFloatv(GL_MODELVIEW_MATRIX, mm);
glGetFloatv(GL_PROJECTION_MATRIX, pm);
gbuffer_shader->set("mm", mm);
gbuffer_shader->set("pm", pm);
5) Move camera
6) Draw scene
7) Unbind shader
8) Render FBO to the fullscreen quad

Vertex Shader:

varying vec3 vertex_position;
varying vec3 normal_vector;
uniform mat4 mm;
uniform mat4 pm;
void main() {
	gl_Position = mm * pm * gl_Vertex;
	vertex_position = vec3(mm * gl_Vertex); 
	normal_vector = vec3(gl_NormalMatrix * gl_Normal);
	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
	gl_TexCoord[1] = gl_TextureMatrix[1] * gl_MultiTexCoord1;
}

Fragment Shader:

varying vec3 vertex_position;
varying vec3 normal_vector;
uniform sampler2D texture0, texture1;
vec4 texel, texel0, texel1;
uniform vec4 color;
void main() {
	texel0 = texture2D(texture0, gl_TexCoord[0].st);
	texel1 = texture2D(texture1, gl_TexCoord[1].st);
	texel = texel0 * texel1;
	gl_FragData[0] = texel;
	gl_FragData[1] = vec4(vertex_position, 1);
	gl_FragData[2] = vec4(normal_vector, 1);
}

I would like to get position colors exactly like this image.

Any help will be appreciated!


4) glGetFloatv(GL_MODELVIEW_MATRIX, mm);
   glGetFloatv(GL_PROJECTION_MATRIX, pm);
   gbuffer_shader->set("mm", mm);
   gbuffer_shader->set("pm", pm);
5) Move camera

moving the camera changes the modelview matrix, looks like you are uploading the wrong values to your shader.

Your vertex shader is wrong. Your calc of gl_position should be pm * mm * gl_Vertex

Also you should update the camera then get the mm and pm from GL.

I tried to put 5) before 4) in pipeline and changed my gl_Position calc in vertex shader to

gl_Position = pm * mm * gl_Vertex;

but I got same black screen.

Only when gl_Position = mm * pm * gl_Vertex I got big artifact:

Any ideas?

What is the internal format of the FBO attachments you are using to store positions and normals?

Internal format is GL_RGBA8 and format is GL_RGBA.

I finally get rid of artifact when changing 3rd of variable to false in glUniformMatrix4fv.

Now I have scene but every rectangle in scene is in 0,0,0 position - no rotations and translations inside draw_scene() :confused:

Screen to illustrate things:


This one rectangle should be a box made of 6 rotated rectangles.

RGB8 is a fixed point format so unless you have disabled clamping you will be in trouble. Itā€™s also very low precsion for what you need. If you have ARB fbo then consider RGB16F for position attachment. Thatā€™s what I use.

Iā€™m using Intel 4500 :o
I have read that it doesnā€™t support floating point textures.
Also I found that view space is easier to implement for first time. I have just googled 3 hours how to get depth texture and it isnā€™t working yet. Deferred Rendering seems like mission impossible to me. If I only find very trivial and rational complete demo codeā€¦

GL_FRAMEBUFFER_COMPLETE = false:

	glGenTextures(1, &depth);
	glBindTexture(GL_TEXTURE_2D, depth);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, width, height, 0, GL_DEPTH_COMPONENT24, GL_UNSIGNED_BYTE, NULL);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_NEAREST);  
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_NEAREST);  
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);  
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE);
	glBindTexture(GL_TEXTURE_2D, 0);
	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth, 0);

I have no idea how could I get z from it:

	glGenRenderbuffers(1, &depth);
	glBindRenderbuffer(GL_RENDERBUFFER, depth);
	glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
	glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth);
	glBindRenderbuffer(GL_RENDERBUFFER, 0);
	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth, 0);

How can I visualise depth and use it in shader to compute lighting?

glGenTextures(1, &depth);
glBindTexture(GL_TEXTURE_2D, depth);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth, 0);
glBindTexture(GL_TEXTURE_2D, 0);

I tried to bind depth to the fullscreen quad, but it gives white texture.

Please help!

I see you fixed some of your errors creating the depth texture.

Well, bind this depth texture to a texture unit, and pass it into a sampler2D uniform in the shader. Then just sample the texture in the shader using a 0ā€¦1 texcoord (or 0ā€¦1 object-space position), keep the ā€œ.rā€ component, and visualize that. Initially, just plot it as is, but youā€™ll probably see better if you render 1-depth_tex_value, rather than depth_tex_value. Pull your far clip in tighter to get more color contrast. But for clearer visualizationā€¦

The value stored in the depth texture is screen-space depth, which for a perspective projection, is a function of 1/eye_space_z and tends to cluster up around 0.9ā€¦1.0. So you probably want to convert to linear depth to visualize it more clearly with linear intensity. For instance, compute eye_space_z from this screen-space depth texture value, and then have 0% intensity = near plane dist and 100% intensity = far plane distance.

For tips, see the archives on this site, or hereā€™s one tutorial for doing this:

This mapping back to linear eye-space depth value is something youā€™re going to want for your lighting pass anyway (unless you write linear eye-space depth to the G-buffer of course, which is a little work without floating-point render targets), so itā€™s certainly not wasted effort.

Iā€™m using Intel 4500 ā€¦ Deferred Rendering seems like mission impossible to me

Itā€™s possible on older GPUs, but much easier on newer ones. Other things youā€™re going to want to find out about your GPU: does it support MRT, does it allow different formats for each RT, which formats does it allow, does it support MSAA render targets (unless youā€™re going to live with jaggies, blur/MLAA, or supersample).

Wow! This really helped me! Thanks Dark Photon! :wink:

Glad to help! Have fun!