PDA

View Full Version : Can't get G-Buffers work correctly



Karmux
12-10-2010, 12:45 PM
Hello!

I have tried to implement deferred rendering for a week already :(
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 (http://img528.imageshack.us/img528/9463/wrongvpat6.jpg) image.

Any help will be appreciated!

carsten neumann
12-10-2010, 02:50 PM
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.

BionicBytes
12-10-2010, 03:01 PM
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.

Karmux
12-10-2010, 03:19 PM
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:

http://www.upload.ee/image/977283/positions.png

Any ideas?

Dark Photon
12-10-2010, 04:33 PM
What is the internal format of the FBO attachments you are using to store positions and normals?

Karmux
12-10-2010, 04:41 PM
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:

http://www.upload.ee/image/977435/positions2.png
This one rectangle should be a box made of 6 rotated rectangles.

BionicBytes
12-11-2010, 03:54 PM
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.

Karmux
12-11-2010, 06:23 PM
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);

Karmux
12-12-2010, 04:33 AM
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!

Dark Photon
12-12-2010, 03:10 PM
How can I visualise depth and use it in shader to compute lighting? ...I tried to bind depth to the fullscreen quad, but it gives white texture.
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:

* http://www.geeks3d.com/20091216/geexlab-how-to-visualize-the-depth-buffer-in-glsl/

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).

Karmux
12-13-2010, 05:41 AM
Wow! This really helped me! Thanks Dark Photon! ;)

Dark Photon
12-14-2010, 06:58 PM
Glad to help! Have fun!