Search code examples
openglglsljogl

Failed to generate the shadow map


I've been struggling with the shadow mapping for two days (with JOGL), yet still couldn't make it work. Now I just want to render a very simple shadow map (grass), where closer looks brighter and further looks darker, from the view of the light point.

Here is my code:

//setting up buffers
gl.glGenFramebuffers(1, framebuff);
gl.glBindFramebuffer(GL4.GL_FRAMEBUFFER, framebuff.get(0));

gl.glGenTextures(2, textureBuff);
gl.glBindTexture(GL4.GL_TEXTURE_2D, textureBuff.get(0));
gl.glTexStorage2D(GL4.GL_TEXTURE_2D, 1, GL4.GL_R32F, displayWidth, displayHeight);
gl.glTexParameteri(GL4.GL_TEXTURE_2D, GL4.GL_TEXTURE_MAG_FILTER, GL4.GL_LINEAR);
gl.glTexParameteri(GL4.GL_TEXTURE_2D, GL4.GL_TEXTURE_MIN_FILTER, GL4.GL_LINEAR_MIPMAP_LINEAR);
gl.glFramebufferTexture(GL4.GL_FRAMEBUFFER, GL4.GL_COLOR_ATTACHMENT0, textureBuff.get(0), 0);

gl.glBindTexture(GL4.GL_TEXTURE_2D, textureBuff.get(1));
gl.glTexStorage2D(GL4.GL_TEXTURE_2D, 1, GL4.GL_DEPTH_COMPONENT32F, displayWidth, displayHeight);
gl.glTexParameteri(GL4.GL_TEXTURE_2D, GL4.GL_TEXTURE_MAG_FILTER, GL4.GL_LINEAR);
gl.glTexParameteri(GL4.GL_TEXTURE_2D, GL4.GL_TEXTURE_MIN_FILTER, GL4.GL_LINEAR_MIPMAP_LINEAR);
gl.glTexParameteri(GL4.GL_TEXTURE_2D, GL4.GL_TEXTURE_COMPARE_MODE, GL4.GL_COMPARE_REF_TO_TEXTURE);
gl.glTexParameteri(GL4.GL_TEXTURE_2D, GL4.GL_TEXTURE_COMPARE_FUNC, GL4.GL_LEQUAL);
gl.glFramebufferTexture(GL4.GL_FRAMEBUFFER, GL4.GL_DEPTH_ATTACHMENT, textureBuff.get(1), 0);
gl.glDrawBuffer(GL4.GL_NONE);

if(gl.glCheckFramebufferStatus(GL4.GL_FRAMEBUFFER) != GL4.GL_FRAMEBUFFER_COMPLETE)
         System.out.println(gl.glCheckFramebufferStatus(GL4.GL_FRAMEBUFFER));

Vertex shader:

"#version 430                                       \n" + 
"layout (location = 3) uniform mat4 mvMatrix;       \n" + 
"layout (location = 4) uniform mat4 proMatrix;      \n" + 
"layout (location = 0) in vec4 position;            \n" + 
"                                                   \n" + 
"void main(void)                                    \n" + 
"{                                                  \n" + 
"   randomize position...                           \n" + 
"                                                   \n" + 
"   gl_Position = proMatrix * mvMatrix * position;  \n" + 
"}"

Fragment shader code:

"#version 430                                       \n" + 
"out vec4 output_color;                             \n" + 
"void main(void)                                    \n" + 
"{                                                  \n" + 
"   output_color = vec4(gl_FragCoord.z);            \n" + 
"}"

drawing command (not sure if it's correct):

//gl.glBindFramebuffer(GL4.GL_FRAMEBUFFER, framebuff.get(0));
gl.glViewport(0, 0, displayWidth, displayWidth);
gl.glEnable(GL4.GL_POLYGON_OFFSET_FILL);
gl.glPolygonOffset(2.0f, 4.0f);

/*IntBuffer frameType = GLBuffers.newDirectIntBuffer(1);
frameType.put(GL4.GL_COLOR_ATTACHMENT0);
gl.glDrawBuffers(1, frameType);
gl.glClearBufferfv(GL4.GL_COLOR, 0, new float[] {0, 0, 0}, 0);
gl.glClearDepth(1.0f);*/

setupMVPMatrix();
gl.glBindVertexArray(vaoBuff.get(0));

gl.glUseProgram(shaderProgram);
gl.glDrawArraysInstanced(GL4.GL_TRIANGLE_STRIP, 0, 5, 512 * 512);

gl.glDisable(GL4.GL_POLYGON_OFFSET_FILL);
//gl.glBindFramebuffer(GL4.GL_FRAMEBUFFER, 0);

added: when I comment the glBindFramebuffer(), the grass appears correctly with the white color (from the light point of view, which shows the matrix should be correct). enter image description here

But if I call glBindFramebuffer() with depth test enabled, everything just disappeared while I expect the closer grass to be brighter and further grass to be darker.(also checked the framebuffer status, nothing wrong) Any help?


Solution

  • Fixed, I didn't understand the meaning of off-screen rendering at the beginning. Just render the depth value stored in the texture into the default framebuffer for display, and everything work just fine. I can't believe I spent 5 days on this. shadow of grass

    gl.glBindFramebuffer(GL4.GL_FRAMEBUFFER, framebuff.get(0));
    draw scene...(storing the depth value into the depth texture)
    
    gl.glBindFramebuffer(GL4.GL_FRAMEBUFFER, 0);
    draw scene...(comparing with the depth texture stored)