Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenGL Shadow Mapping with FBO - multiple trailing draw

Tags:

opengl

glsl

I am trying to implement shadow mapping in our game project. I am using render to texture technique with two pass rendering. I have created a FBO first and bound a texture for depth component only. In the first pass, I enable this FBO, disable texture and render my scene from light POV. In the second pass, I pass the depth texture to the shader and render the scene normally. I perform the shadow related calculation in the shader.

But, my code is not working correctly. I am not able to see any shadow. Also, when I render both pass, I see a multiple drawing of the whole world trailing one after another if my camera is looking above a certain angle : 45. If I look below that angle, the rendering looks ok. What may be the source of this problem? . If I disable the first pass, the world looks darker but the trailing scene is gone. I have also attached my codes below.

Multiple Drawing

I have also another confusion. I have disabled texture for the first shadowmap pass. But I send the texture coordinates with my vertex coordinates to the VBO. Will that cause any problem?

FBO Initialization

LightPosition = glm::vec3(50.0f, 40.0f, 50.0f);  
upVector = glm::vec3(0.0f, 1.0f, 0.0f);  

glGenTextures(1, &m_shadowMap);  
glBindTexture(GL_TEXTURE_2D, m_shadowMap);  
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_TEXTURE_WRAP_S, GL_CLAMP);  
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);  
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);  
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);  
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);  
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32,  
        WindowWidth, WindowHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);  
glBindTexture(GL_TEXTURE_2D, 0);  

glGenFramebuffers(1, &m_fbo);  
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);  
glDrawBuffers(0, NULL);  
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_shadowMap, 0);  
glBindFramebuffer(GL_FRAMEBUFFER, 0);  

glEnable(GL_DEPTH_TEST);  
glEnable(GL_CULL_FACE);  


GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER);  

if (Status != GL_FRAMEBUFFER_COMPLETE) {  
    printf("FB error, status: 0x%x\n", Status);  
    return false;  
}  

return true;  

Shadow Map Pass:

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, 0);


glViewport(0, 0, windowWidth, windowHeight);

glBindFramebuffer(GL_FRAMEBUFFER, shadowMapFBO.m_fbo);

glClear(GL_DEPTH_BUFFER_BIT);


glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glm::mat4 lightProjection = glm::perspective(45.0f,
        1.0f * windowWidth / windowHeight, 0.125f, 1000.0f);
glGetFloatv(GL_PROJECTION_MATRIX, shadowMapFBO.LightProjectionMatrix);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glm::mat4 lightModelView = glm::lookAt(shadowMapFBO.LightPosition,
        glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
glGetFloatv(GL_MODELVIEW_MATRIX, shadowMapFBO.LightModelViewMatrix);

glm::mat4 lmvp = lightProjection * lightModelView;

glCullFace(GL_FRONT);

glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);

glUniform1i(Shader::id_uniform_layer, 0);
world->render(lmvp);
printGLError();


glBindFramebuffer(GL_FRAMEBUFFER, 0);

Render Pass:

static glm::vec3 cCameraPosition = glm::vec3(0.0f, 5.0f, 10.0f);
static glm::vec3 cLightPosition = glm::vec3(50.0f, 40.0f, 50.0f);

glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, windowWidth, windowHeight);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glm::mat4 modelView = player->getView();

float viewAngle = 45.0f;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glm::mat4 projection = glm::perspective(viewAngle,
        1.0f * windowWidth / windowHeight, 0.01f, 1000.0f);
glm::mat4 mvp = projection * modelView;


glEnable(GL_TEXTURE_2D);

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, shadowMapFBO.m_shadowMap);

glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glTranslatef(0.5f, 0.5f, 0.5f);
glScalef(0.5f, 0.5f, 0.5f);
glMultMatrixf(shadowMapFBO.LightProjectionMatrix);
glMultMatrixf(shadowMapFBO.LightModelViewMatrix);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, id_texture_blocks);

glUseProgram(Shader::id_program);

glUniform3fv(Shader::id_uniform_lightPosition, 1,
        glm::value_ptr(cLightPosition));
glUniform3fv(Shader::id_uniform_CameraPosition, 1,
        glm::value_ptr(*(player->getCoordinates())));

//Enabling color write (previously disabled for light POV z-buffer rendering)
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glUniform1i(Shader::id_shader_shadow, 1);

glUniformMatrix4fv(Shader::id_uniform_mvp, 1, GL_FALSE, glm::value_ptr(mvp));

glEnable(GL_POLYGON_OFFSET_FILL);
glEnable(GL_CULL_FACE);

glCullFace(GL_BACK);

glUniform1i(Shader::id_uniform_layer, 0);
world->render(mvp);
printGLError();

Vertex Shader:

attribute vec4 coordinates;
uniform   mat4 mvp;

//Fragment shader forward variables.
varying vec4 voxel;

//shadow map
// Used for shadow lookup
varying vec4 ShadowCoord;

uniform vec3 LightPosition, CameraPosition;

varying vec3 LightDirection, LightDirectionReflected, CameraDirection, Normal;

void main(void) {

//shadow map
LightDirection = LightPosition - gl_Vertex.xyz;
LightDirectionReflected = reflect(-LightDirection, gl_Normal);
CameraDirection = CameraPosition - gl_Vertex.xyz;
Normal = gl_Normal;
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_TexCoord[1] = gl_TextureMatrix[1] * gl_Vertex;

voxel = coordinates;
//Calculates projection on xyz.
gl_Position = mvp * vec4(coordinates.xyz, 1);
}

Fragment Shader:

#extension GL_EXT_gpu_shader4 : enable  


//Rendering layer.  
uniform int layer;  


//Colors.  
uniform float colorRed;  
uniform float colorGreen;  
uniform float colorBlue;  
uniform float colorAlpha;  

//Fog density.  
uniform float fogDensity;  

varying vec4 voxel;  

uniform sampler2D texture;  

const float N_TEXTURES = 32.0;  

//////////////////////shadow map  
uniform sampler2DShadow ShadowMap;  

varying vec4 ShadowCoord;  

varying vec3 LightDirection, LightDirectionReflected, CameraDirection, Normal;  

void main(void) {  

vec2  coord2d;  
float intensity;  

vec4 color = texture2D(texture, coord2d);  

float z = gl_FragCoord.z / gl_FragCoord.w;  
float fog = clamp(exp(-fogDensity * z * z), 0.2, 1.0);  

color.xyz = color.xyz * intensity;  

//shadow map  
float Shadow = shadow2DProj(ShadowMap, gl_TexCoord[1]).r;  

float NdotLD = max(dot(normalize(LightDirection), Normal), 0.0) * Shadow;  
float Spec = pow(max(dot(normalize(LightDirectionReflected), normalize(CameraDirection)), 0.0), 32.0) * Shadow;  
color.xyz = color.xyz * (0.25 + NdotLD * 0.75 + Spec);  

//Final color.  
vec4 fogColor = vec4(colorRed, colorGreen, colorBlue, colorAlpha);  
gl_FragColor = mix(fogColor, color, fog);  


}  
like image 385
user2028566 Avatar asked Jan 31 '13 10:01

user2028566


1 Answers

At a glance it looks like you're not using glClear so the sky is whatever was in the last frame, or at least its not working. What's the alpha value of the glClearColor?

like image 80
Tom Avatar answered Oct 05 '22 15:10

Tom