'Trying to implement shadow using OpenGL; depth texture seems correct but shadow is not displaying
trying to implement shadow. I checked my depth texture on a quad, and it seems correct, but the shadow is not displaying. I check my shadow vertex and fragment shaders, and I believe I have done the light space transformation correctly.
Here are my code.
directional light source matrix setup:
//light source states
glm::vec3 Window::lightColor = glm::vec3(0.9f, 0.9f, 0.9f);
glm::vec3 Window::lightDir = glm::vec3(-1.f, -1.f, 0.f);
glm::mat4 Window::lightView = glm::lookAt(glm::vec3(0.f) - glm::normalize(lightDir) * 15.f, glm::vec3(0.0f), glm::vec3(0.f, 1.f, 0.f));
float Window::near_plane = 0.01f;
float Window::far_plane = 50.1f;
float camWidth = 10.f;
glm::mat4 Window::lightProj = glm::ortho(-10.f, 10.f, -10.f, 10.f, Window::near_plane, Window::far_plane);
glm::mat4 Window::lightProjView = lightProj * lightView;
shadow drawing logic:
void Renderer::drawWithShadow(Object* obj) {
//set shader uniforms
Shader* shader = shadowShader;
shader->bind();
shader->setUniformMat4("model", obj->model);
shader->setUniformMat4("projView", projView);
shader->setUniformVec3("viewPos", eyePos);
//need another projection matrix
shader->setUniformMat4("lightSpaceMatrix", shadowProjView);
glcheck(glActiveTexture(GL_TEXTURE0));
glcheck(glBindTexture(GL_TEXTURE_2D, textID));
//light uniforms
shader->setUniformVec3("directionalLightDir", directionalLightDir);
shader->setUniformVec3("lightColor", lightColor);
glcheck(glBindVertexArray(obj->vao));
for (auto i = 0; i < obj->meshList.size(); i++) {
Mesh* mesh = obj->meshList[i];
prepMaterial(mesh->material, shader);
glcheck(glDrawElements(GL_TRIANGLES, mesh->size, GL_UNSIGNED_INT, (GLvoid*)(sizeof(GLuint) * mesh->vertexOffset)));
}
}
vert and frag shaders to prepare shadow depth textures
//vertex shader
#version 330 core
layout (location = 0) in vec3 position;
uniform mat4 projView;
uniform mat4 model;
void main() {
gl_Position = projView * model * vec4(position, 1.0);
}
//fragment shader
#version 330 core
void main()
{
}
vert and frag shaders to draw shadows with Phong lighting //vertex shader
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec2 texCoord;
out VS_OUT {
vec4 fragPos;
vec3 normal;
vec2 texCoord;
vec4 fragPosLightSpace;
} vs_out;
uniform mat4 projView;
uniform mat4 model;
uniform mat4 lightSpaceMatrix;
void main()
{
vs_out.fragPos = model * vec4(position, 1.0);
vs_out.normal = transpose(inverse(mat3(model))) * normal;
vs_out.texCoord = texCoord;
vs_out.fragPosLightSpace = lightSpaceMatrix * vs_out.fragPos;
gl_Position = projView * vs_out.fragPos;
}
//fragment shader
#version 330 core
uniform vec3 viewPos; //just the eye pos
uniform vec3 diffuseFactor; //kd
uniform vec3 ambientColor; //ka
uniform vec3 specColor; //ks
uniform float specHighlight; //ns, the larger this value is, the more apparent the light dot on the surface
uniform float dissolve; //d
//lights
uniform vec3 directionalLightDir;
uniform vec3 pointLightPos;
uniform vec3 lightColor;
uniform sampler2D shadowMap;
//uniform sampler2DShadow shadowMap;
in VS_OUT {
vec4 fragPos;
vec3 normal;
vec2 texCoord;
vec4 fragPosLightSpace;
} fs_in;
out vec4 fragColor;
float ShadowCalculation(vec4 fragPosLightSpace)
{
vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
vec2 shadowCoords;
shadowCoords.x = projCoords.x * 0.5 + 0.5;
shadowCoords.y = projCoords.y * 0.5 + 0.5;
float closestDepth = texture(shadowMap, shadowCoords).r;
float currentDepth = projCoords.z * 0.5 + 0.5;
float shadowValue = currentDepth + 0.00001 > closestDepth ? 1.0 : 0.0;
//if(currentDepth < 0.0)
//shadowValue = 0.0;
return shadowValue;
}
void main()
{
vec3 lightDir = normalize(-directionalLightDir);
vec3 norm = normalize(fs_in.normal);
//diffuse lighting
float diffStrength = max(dot(norm, lightDir), 0.0); // this calculates diffuse intensity based on angle
vec3 diffuse = lightColor * diffStrength * diffuseFactor;
//specular
vec3 viewDir = normalize(viewPos - fs_in.fragPos.xyz);
vec3 reflectDir = reflect(-lightDir, norm);
float spec = 0.0;
if(specHighlight > 0.0) { // if specHighlight is < 0, pow might produce undefined result if base is also 0
spec = pow(max(dot(viewDir, reflectDir), 0.0), specHighlight);
}
vec3 specular = spec * specColor * lightColor;
float shadow = ShadowCalculation(fs_in.fragPosLightSpace);
//float shadow = textureProj(shadowMap, fs_in.fragPosLightSpace);
//vec3 result = ambientColor * 0.05 * lightColor + (diffuse + specular)*(1-shadow);
vec3 result = (diffuse + specular)*(1.0 - shadow);
fragColor = vec4(result, 1);
}
with just Phong shading, the scene looks like this: Phong shading
when the scene is seen from the light source as depth value: depth texture on quad
when I finally render the scene, it is mostly black; I made sure the far plane covers all of the bunnies: render shadow
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|