-2

I am trying to implement shadow-mapping in my scene, but all I get is zeros in my fragment shader when I call texture() (I've tested it with == 0.0). My question: Am I sending the depth texture to the shader correctly?

Here is my fragment shader code:

bool getShadow() {
    vec4 lightProjPositionScaled = lightProjPosition/lightProjPosition.w;
    vec2 texCoords = lightProjPositionScaled.xy*0.5 + 0.5;  // bias
    return lightProjPositionScaled.z + 0.0005 > texture(shadowMap, texCoords).x;
}

Here is my relevant java code
Init (edited due to BDL's comment)

gl.glEnable(GL2.GL_TEXTURE_2D);

// generate stuff
IntBuffer ib = IntBuffer.allocate(1);
gl.glGenFramebuffers(1, ib);
frameBuffer = ib.get(0);

ib = IntBuffer.allocate(1);
gl.glGenTextures(1, ib);
shadowMap = ib.get(0);

gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, frameBuffer);
gl.glBindTexture(GL2.GL_TEXTURE, shadowMap);
gl.glTexImage2D(GL2.GL_TEXTURE_2D, 0, GL2.GL_DEPTH_COMPONENT, 1024, 1024, 0, GL2.GL_DEPTH_COMPONENT, GL2.GL_FLOAT, null);
gl.glDrawBuffer(GL2.GL_NONE);
gl.glReadBuffer(GL2.GL_NONE);
gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, 0);


// prevents 'shadow acne'
gl.glPolygonOffset(2.5f, 0);
// prevents multiple shadows
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_WRAP_S, GL2.GL_CLAMP_TO_EDGE);
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_WRAP_T, GL2.GL_CLAMP_TO_EDGE);
// prevents (or expects!!!) pixel-y textures
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_NEAREST);
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_NEAREST);
// store one value in all four components of pixel
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_DEPTH_TEXTURE_MODE, GL2.GL_INTENSITY);

Display (1st pass, for shadows):

// render shadows
gl.glUseProgram(shadowProgram);

gl.glUniformMatrix4fv(lightMatrixLocShadow, 1, false, lightMatrix.getMatrix(), 0);  // yep (haha change viewMatrix -> lightMatrix)
gl.glUniformMatrix4fv(projMatrixLocShadow, 1, false, projMatrix.getMatrix(), 0);

gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, sha.frameBuffer);

gl.glViewport(0, 0, 1024, 1024);
gl.glClear(GL2.GL_DEPTH_BUFFER_BIT);
renderScene(gl, sunMatrix);
gl.glCopyTexImage2D(GL2.GL_TEXTURE_2D, 0, GL2.GL_DEPTH_COMPONENT, 0, 0, 1024, 1024, 0);
gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, 0);

Display (2nd pass, for rendering the scene):

// render display (regular)
gl.glUseProgram(displayProgram);
gl.glDrawBuffer(GL2.GL_FRONT);
gl.glReadBuffer(GL2.GL_FRONT);

gl.glUniformMatrix4fv(viewMatrixLoc, 1, false, viewMatrix.getMatrix(), 0);
gl.glUniformMatrix4fv(projMatrixLocDisplay, 1, false, projMatrix.getMatrix(), 0);
gl.glUniformMatrix4fv(lightMatrixLocDisplay, 1, false, lightMatrix.getMatrix(), 0);
gl.glUniform4fv(sunPositionLoc, 1, sunWorldPosition, 0);    // send sun's position to shader
gl.glUniform1f(sunBrightnessLoc, sunBrightness);
gl.glUniform1i(shadowMapLoc, 0);

gl.glViewport(0, 0, screenWidth, screenHeight);
// day-night cycle
float[] color = SkyManager.getSkyColor(time);
gl.glClearColor(color[0], color[1], color[2], 1);
gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
gl.glActiveTexture(GL2.GL_TEXTURE0);
gl.glBindTexture(GL2.GL_TEXTURE_2D, sha.shadowMap);
renderScene(gl, sunMatrix);

Another strange outcome is that only fragments on the z=0 plane relative to the light matrix (the light's rotating, and the plane rotates with it) are lit. All other fragments, behind and in front of the light, are shadowed.

clabe45
  • 2,354
  • 16
  • 27
  • 1
    Are you checking somewhere for OpenGL errors? I see from the first view at least two of them happening. `GL_RENDERBUFFER` is not a supported target for `glBindTexture`. You are never attaching the texture to the framebuffer (`glFramebufferTexture2D`), so it will most probably not be complete. Check `glCheckFramebufferStatus`. – BDL Jun 27 '17 at 13:52
  • Ah I switched to using a render buffer and then switched back to using a texture.. When using `glCheckFramebufferStatus` I get `GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT`. – clabe45 Jun 27 '17 at 13:57
  • Yes, because you are never attaching the depth texture... And you'll have to call `glDrawBuffer(GL_NONE)` before checking, otherwise a color attachment is required. – BDL Jun 27 '17 at 14:05
  • I did call `glDrawBuffer(GL_NONE)` before checking. How would I attach the depth texture to the frame buffer? – clabe45 Jun 27 '17 at 14:08
  • Use `glFramebufferTexture2D`. – BDL Jun 27 '17 at 14:09
  • Weird I put `gl.glFramebufferTexture2D(GL2.GL_FRAMEBUFFER, GL2.GL_DEPTH_ATTACHMENT, GL2.GL_TEXTURE_2D, shadowMap, 0);`in before `glTexImage2D` in the initiation code. It still has the `GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT` error. – clabe45 Jun 27 '17 at 14:16

1 Answers1

0

One issue was with the line gl.glBindTexture(GL2.GL_TEXTURE, shadowMap);

I was binding the texture to GL_TEXTURE instead of GL_TEXTURE_2D.

clabe45
  • 2,354
  • 16
  • 27