hi there,
i am trying to implement a basic deferred renderer in opengl 3.2.
i managed (at least i think), to store all necessary data into a g-buffer. but when i try to implement a lighting model, i get really weired and wrong results. i uploaded a video to youtube, where you can see my stored data. normals + position.
i don't know if i store those in the right space.
as for the important code:
// openGL Init Params
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthFunc(GL_LEQUAL);
// creating the G-Buffer
glGenFramebuffers(1,&fboID);
glBindFramebuffer(GL_FRAMEBUFFER, fboID);
/**** G-Buffer ****/
/* Depth-Buffer */
glGenRenderbuffers(1, &depthBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
/* Position-Texture */
glActiveTexture(GL_TEXTURE0);
posTex = TextureHelper::create32FTexture(width, height);
/* Normals-Texture */
glActiveTexture(GL_TEXTURE1);
normTex = TextureHelper::create32FTexture(width, height);
/* Diffuse(Color)-Texture */
glActiveTexture(GL_TEXTURE2);
diffTex = TextureHelper::createRGBTexture(width, height);
/**** Attach G-Buffer-Components to FBO ****/
/* Attach Depth-Buffer */
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer);
/* Attach Textures to FBO */
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, posTex, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, normTex, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, diffTex, 0);
GLenum drawBuffers[] = {GL_NONE, GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2};
glDrawBuffers(4, drawBuffers);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// "Render FBO-Quad to Screen"-Pass
/* Bind Textures, G-Buffers */
unsigned int shaderProgram = phongShader->getShaderID();
glBindVertexArray(vaoID);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, posTex);
glUniform1i(glGetUniformLocation(shaderProgram,"posTex"), 2);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, normTex);
glUniform1i(glGetUniformLocation(shaderProgram,"normTex"), 0);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, diffTex);
glUniform1i(glGetUniformLocation(shaderProgram,"diffTex"), 1);
/* Render Quad Setup */
int vertexpos = glGetAttribLocation(shaderProgram,"vertexpos");
int uvPos = glGetAttribLocation(shaderProgram,"uvPos");
glBindBuffer(GL_ARRAY_BUFFER, vertexHandle);
glEnableVertexAttribArray(vertexpos);
glVertexAttribPointer(vertexpos, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
glBindBuffer(GL_ARRAY_BUFFER, uvHandle);
glEnableVertexAttribArray(uvPos);
glVertexAttribPointer(uvPos, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
/* Update Scene if needed ! */
Scene::instance()->updateLights(shaderProgram);
glDrawArrays(GL_TRIANGLES, 0, 3 * 2);
glDisableVertexAttribArray(vertexpos);
glDisableVertexAttribArray(uvPos);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glBindVertexArray(0);
// Shaders
Rendering Mesh-Data to Texture
Vertex Shader
#version 150 core
/**** Pass-Through Shader ****/
/* Converts data to texture/buffer */
in vec3 vertexPosition;
in vec3 normalPosition;
in vec2 uvPosition;
out vec3 OUTposition;
out vec3 OUTnormal;
out vec2 OUTuv;
/* Normal Map Matrix */
out mat3 tangentToWorld;
//openGL 3.2 Matrizen
uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;
uniform mat4 modelViewProjectionMatrix;
uniform mat3 normalMatrix;
void main(){
/* Passes all data to fragment shader */
OUTposition = vec3(modelViewMatrix * vec4(vertexPosition, 1));
OUTnormal = normalize(normalMatrix * normalPosition);
OUTuv = uvPosition;
gl_Position = modelViewProjectionMatrix * vec4(vertexPosition, 1);
/* Calculating the NormalMap-Normal-Matrix */
/* http://gamedev.stackexchange.com/questions/34475/deferred-rendering-and-normal-mapping */
vec3 n = OUTnormal;
vec3 t = normalize(normalMatrix[0]);
vec3 bn = normalize(normalMatrix[1]);
tangentToWorld = mat3(t.x, bn.x, n.x, t.y, bn.y, n.y, t.z, bn.z, n.z);
}
Fragment Shader:
#version 150 core
/* Model-Textures */
uniform sampler2D diffuseTex;
uniform sampler2D normalMapTex;
uniform float hasNormalMap;
in vec3 OUTposition;
in vec3 OUTnormal;
in vec2 OUTuv;
in mat3 tangentToWorld;
out vec4 positionData;
out vec4 normalData;
out vec4 colorData;
out vec4 FragColor;
void main(){
FragColor = vec4(0,0,0,0);
positionData = vec4(OUTposition, 1);
/* If Mesh has a Normalmap, than it gets calculated ! */
if(hasNormalMap > 0.5){
normalData = vec4((texture(normalMapTex, OUTuv).rgb * 2.0 - 1.0) * tangentToWorld,1);
}else{
normalData = vec4(OUTnormal, 1);
}
colorData = texture(diffuseTex, OUTuv);
}
// Rendering Quad to Screen / Lighting - Pass
Vertex Shader
#version 150 core
/* Pass through FBO Renderquad Vertices & UVs*/
in vec2 vertexpos;
in vec2 uvPos;
out vec2 outUV;
//openGL 3.2 Matrizen
uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;
uniform mat4 modelViewProjectionMatrix;
uniform mat3 normalMatrix;
void main(){
/* Transform the Quad - vertices into Screen space */
gl_Position = modelViewProjectionMatrix*vec4(vertexpos,0,1);
outUV = uvPos;
}
Fragment Shader
#version 150 core
uniform vec2 pixelsize;
uniform sampler2D posTex;
uniform sampler2D normTex;
uniform sampler2D diffTex;
in vec2 outUV;
out vec4 FragColor;
/**** Lighting Variables ****/
const int MAX_POINT_LIGHTS = 1024;
const int MAX_SPOT_LIGHTS = 1024;
/**** Lighting Structs ****/
struct Light{
vec3 color;
float intensity;
};
struct DirectionalLight{
Light light;
vec3 direction;
};
struct PointLight{
Light light;
vec3 attenuation;
vec3 position;
float range;
};
struct SpotLight{
PointLight pointLight;
vec3 direction;
float cutoff;
};
/**** Lighting Uniforms ****/
uniform Light ambientLight;
uniform DirectionalLight directionalLight;
uniform PointLight POINTLIGHTS[MAX_POINT_LIGHTS];
uniform SpotLight SPOTLIGHTS[MAX_SPOT_LIGHTS];
uniform vec3 eyePos; //camera Position
/**** Lighting Calculations ****/
vec3 calcAmbientlight(vec3 pixelColor){
return vec3(ambientLight.color * ambientLight.intensity * pixelColor);
}
vec3 calcDiffuseLight(vec3 eyePosition, vec3 normal, vec3 materialDiffuse, vec3 lightDiffuse, vec3 lightPosition){
vec3 s = normalize(lightPosition - eyePosition);
float sDotN = max(dot(s, normal), 0.0);
vec3 diffuse = 0.8 * materialDiffuse * sDotN;
return diffuse;
}
void main(){
vec2 texel = vec2(gl_FragCoord) * pixelsize;
vec4 diffuse = texture(diffTex, texel);
vec4 normal = texture(normTex, texel);
vec4 position = texture(posTex, texel);
vec3 color = vec3(diffuse);
vec3 result = calcDiffuseLight(vec3(position), vec3(normalize(normal)), color, POINTLIGHTS[0].light.color, POINTLIGHTS[0].position);
FragColor = vec4((result), diffuse.w);
}
i tried various other implementations of lighting. for example, pointlights, spotlights.. but i always get weired results like this:
[attachment=17841:Bildschirmfoto 2013-09-08 um 16.55.04.png]
[attachment=17842:Bildschirmfoto 2013-09-08 um 17.08.34.png]
btw: i also tried to convert the lightsources into view and modelspace.. but nothing..
i'd appreciate every bit of help :)
thank you very much in advance