I'm currently trying to implement deferred shading in OpenGL 3.2 and have a problem that I just can't seem to solve no matter what I try.
I implemented it in two steps(geometry pass and lighting pass) like one would expect. After compiling and running it the screen shows the scene I prepared almost like one would expect it to look like. The colors of the objects are correct and they are also positioned where and how I wanted them to be.
The thing is, that the light calculations seem to have no influence on the color, what so ever. After a lot of hours I found out, that the textures for the positions and normals seem to contain the same content like the color texture.
If one changes the last line in the lighting fragment shader from fragColor = lightIntensity * color;
to fragColor = lightIntensity * norm;
or fragColor = lightIntensity * pos;
it has absolutely no impact on how the screen is rendered.
I have tried a lot to figure out what is going wrong but honestly have no idea what it could be.
It would be awesome if someone could help me.
My render method looks like this:
void render()
{
//geometry pass
gBuffer->bindForWriting();
geometryShader->use(true);
calculateGBuffer();
//lighting pass
gBuffer->bindForReading(lightShader->programID());
lightShader->use(true);
drawOnScreen();
}
The initialization of the gBuffer
object is like this:
void GBuffer::initializeFBO(int viewWidth, int viewHeight)
{
//initialize fbo and corresponding textures;
glGenFramebuffers(1, &fbo_ID);
glBindFramebuffer(GL_FRAMEBUFFER, fbo_ID);
glGenTextures(1, &colorTexture_ID);
glBindTexture(GL_TEXTURE_2D, colorTexture_ID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, viewWidth, viewHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 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, colorTexture_ID, 0);
glGenTextures(1, &posTexture_ID);
glBindTexture(GL_TEXTURE_2D, posTexture_ID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, viewWidth, viewHeight, 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_ATTACHMENT1, GL_TEXTURE_2D, posTexture_ID, 0);
glGenTextures(1, &normTexture_ID);
glBindTexture(GL_TEXTURE_2D, normTexture_ID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, viewWidth, viewHeight, 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_ATTACHMENT2, GL_TEXTURE_2D, normTexture_ID, 0);
GLuint attachments[3] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 };
glDrawBuffers(3, attachments);
glGenRenderbuffers(1, &depthBuffer_ID);
glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer_ID);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, viewWidth, viewHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer_ID);
//Check Status
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
qDebug() << "error while initializing framebuffer" << glCheckFramebufferStatus(GL_FRAMEBUFFER);
else{
qDebug() << "framebuffer successfully created";
initialized = true;
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
The methods bindForReading
and bindForWriting
:
void GBuffer::bindForWriting()
{
glBindFramebuffer(GL_FRAMEBUFFER, fbo_ID);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
void GBuffer::bindForReading(GLuint programID)
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, colorTexture_ID);
GLuint samplerTexture_ID = glGetUniformLocation(programID, "colorTexture");
glUniform1i(samplerTexture_ID, 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, posTexture_ID);
samplerTexture_ID = glGetUniformLocation(programID, "positionTexture");
glUniform1i(samplerTexture_ID, 1);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, normTexture_ID);
samplerTexture_ID = glGetUniformLocation(programID, "normTexture");
glUniform1i(samplerTexture_ID, 2);
}
And at last the 4 Shaders:
Geometry Vertex Shader:
#version 150
#extension GL_ARB_separate_shader_objects : enable
uniform mat4 MVPMatrix;
uniform mat4 modelMatrix;
in vec4 in_position;
in vec4 in_color;
in vec2 in_texcoord;
in vec3 in_norm;
out vec4 color_varying;
out vec3 frag_position;
out vec3 norm_vec;
out vec2 texcoord_varying;
void main()
{
gl_Position = MVPMatrix * in_position;
vec4 worldPosition = (modelMatrix * in_position);
frag_position = worldPosition.xyz;
norm_vec = in_norm;
color_varying = in_color;
texcoord_varying = in_texcoord;
}
Geometry Fragment Shader:
#version 150
#extension GL_ARB_explicit_attrib_location : enable
in vec4 color_varying;
in vec3 frag_position;
in vec3 norm_vec;
in vec2 texcoord_varying;
layout (location = 0) out vec4 fragColor;
layout (location = 1) out vec3 fragPosition;
layout (location = 2) out vec3 frag_norm_vec;
uniform sampler2D myTexture;
void main()
{
vec4 texel = texture(myTexture, texcoord_varying);
fragColor = texel * color_varying;
fragPosition = frag_position;
frag_norm_vec = normalize(norm_vec);
}
Lighting VertexShader:
#version 150
#extension GL_ARB_explicit_attrib_location : enable
layout (location = 0) in vec2 in_position;
out vec2 texCoord;
void main()
{
gl_Position = vec4(in_position, 0, 1.0f);
texCoord = in_position;
if(texCoord.x == -1.0f)
texCoord.x = 0.0f;
if(texCoord.y == -1.0f)
texCoord.y = 0.0f;
}
Lighting Fragment Shader(without lighting calculation to make it shorter)
#version 150
#extension GL_ARB_separate_shader_objects : enable
out vec4 fragColor;
in vec2 texCoord;
uniform sampler2D colorTexture;
uniform sampler2D positionTexture;
uniform sampler2D normTexture;
void main()
{
//extract fragment data from fbo
vec3 pos = texture(positionTexture, texCoord).rgb;
vec3 norm = texture(normTexture, texCoord).rgb;
vec4 color = texture(colorTexture, texCoord);
fragColor = lightIntensity * color;
}
Sry for the code spamming but I can't narrow down the error.
#version 150
? That's from GL 3.2. That's not your problem, but you should be clear on what version of OpenGL you're using. – Nicol Bolas