Deferred Rendering Lighting Problem

Started by
1 comment, last by 3TATUK2 10 years, 6 months ago

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

Advertisement

hey ;)

so i think, i solved it now... to me it looks alright now..

could someone confirm the same? if it shows to be right, i'll post the updated code smile.png

[attachment=17859:Bildschirmfoto 2013-09-10 um 17.18.20.png][attachment=17860:Bildschirmfoto 2013-09-10 um 17.20.14.png][attachment=17861:Bildschirmfoto 2013-09-10 um 17.26.09.png][attachment=17862:Bildschirmfoto 2013-09-10 um 17.26.25.png]

(i know that the textures look like crap..^^)

[attachment=17918:BUEyq5wCMAAIIyM.png_large.png]

Please update code :) - have you figured out how to do *many* lights "fast" ? Something to do with light volumes that restrict the number of screen space pixels that are effected?

This topic is closed to new replies.

Advertisement