Jump to content
  • Advertisement
Sign in to follow this  
_RAW_

OpenGL Deferred Rendering Lighting Problem

This topic is 2141 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
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]

Edited by _RAW_

Share this post


Link to post
Share on other sites

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?

Edited by 3TATUK2

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!