I am trying to implement shadow mapping for a few days now and I think I am starting to see the real issue at hand: I have an FBO with a Depth Texture attached to it, for the light pass of shadow mapping, however nothing is being rendered in it. Not even hardcoded values.
I have double checked the part of the program that visualizes the depth texture, and that is working with regular textures, moreover I see no shadows appearing in my scene, so I think something is definately wrong.
init:
//shadow FBO and texture
depthFBO = new FrameBufferObject().create().bind();
depthTexture = new Texture2D().create().bind()
.storage2D(12, GL_DEPTH_COMPONENT32F, 4096, 4096)
.minFilter(GL_LINEAR)
.magFilter(GL_LINEAR)
.compareMode(GL_COMPARE_REF_TO_TEXTURE)
.compareFunc(GL_LEQUAL);
depthFBO.texture2D(GL_DEPTH_ATTACHMENT, GL11.GL_TEXTURE_2D, depthTexture, 0)
.checkStatus().unbind();
depthTexture.unbind();
render:
depthFBO.bind();
glViewport(0, 0, 4096, 4096);
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(4.0f, 4.0f);
glDrawBuffer(GL_NONE);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClearDepthf(1f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Drawable.drawAllLightPass(drawables, lightNormalProgram, lightTessellationProgram);
glDisable(GL_POLYGON_OFFSET_FILL);
depthFBO.unbind();
Code in direct gl*
calls.
init:
int frameBufferObjectId = GL30.glGenFramebuffers();
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, frameBufferObjectId);
int textureId = GL11.glGenTextures();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureId);
GL42.glTexStorage2D(GL11.GL_TEXTURE_2D, 12, GL_DEPTH_COMPONENT32F, 4096, 4096);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL14.GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL14.GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL11.GL_TEXTURE_2D, textureId, 0);
if (GL30.glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER) != GL30.GL_FRAMEBUFFER_COMPLETE) {
throw new RuntimeException(this + " is not complete.");
}
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, 0);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
render:
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, frameBufferObjectId);
glViewport(0, 0, 4096, 4096);
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(4.0f, 4.0f);
glDrawBuffer(GL_NONE);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClearDepthf(1f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//appropiate calls to glDraw* are being done, this is confirmed to work as it works for displaying data
glDisable(GL_POLYGON_OFFSET_FILL);
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, 0);
Now the most important shaders:
light-normal.vs.glsl
#version 430 core
layout(location = 4) uniform mat4 light_model_matrix;
layout(location = 5) uniform mat4 light_view_matrix;
layout(location = 6) uniform mat4 light_projection_matrix;
layout(location = 0) in vec4 position;
void main(void) {
gl_Position = light_projection_matrix * light_view_matrix * light_model_matrix * position;
}
light-normal.fs.glsl
#version 430 core
layout(location = 0) out float depth;
void main(void) {
depth = gl_FragCoord.z;
}
Also even hardcoding depth
to either 0.0f
, 0.5f
or 1.0f
neither work.
Just to clarify if my expectations are correct: When I move my camera close to an object that is being rendered on the screen, then the color of the depth buffer should change? As depth will be close to 0.0f then, and far away from 1.0f?
Also another clarification: What I see as the depth-values, is a rectangle that is colored white everywhere.
As per request, shaders to visualize the depth texture data:
depth-box.vs.glsl
#version 430 core
void main(void) {
const vec4 vertices[6] = vec4[](
vec4(-1.0, -1.0, 1.0, 1.0),
vec4(-1.0, 1.0, 1.0, 1.0),
vec4(1.0, 1.0, 1.0, 1.0),
vec4(1.0, 1.0, 1.0, 1.0),
vec4(1.0, -1.0, 1.0, 1.0),
vec4(-1.0, -1.0, 1.0, 1.0)
);
gl_Position = vertices[gl_VertexID];
}
depth-box.fs.glsl
#version 430 core
layout(location = 7) uniform int screen_width;
layout(location = 8) uniform int screen_height;
layout(binding = 0) uniform sampler2D shadow_tex;
out vec4 color;
void main(void) {
vec2 tex_coords = vec2(
(gl_FragCoord.x - 100) / (screen_width / 5),
(gl_FragCoord.y - (screen_height - (screen_height / 5) - 100)) / (screen_height / 5)
);
color = vec4(vec3(texture(shadow_tex, tex_coords).r), 1.0);
}