0

I am following the shadow tutorial on http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-16-shadow-mapping/ and I can view the depth value in the depth texture when rendered to a screen aligned quad. The problem is when I sample from this depth texture I get only one value.

This is how I setup the depth texture FBO; the size of the texture is set to the window size. I'm not sure if this is part of the problem, but if I half the dimensions of the depth texture and try to view that, I end up seeing a corner quarter of the view. I thought textures are always accessed from [0,1]?

glGenFramebuffers(1, &FramebufferName);
glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);

glGenTextures(1, &renderedTexture);
glBindTexture(GL_TEXTURE_2D, renderedTexture);
glTexImage2D(GL_TEXTURE_2D, 0,
             GL_DEPTH_COMPONENT,
             fbWidth,
             fbHeight,
             0,
             GL_DEPTH_COMPONENT,
             GL_FLOAT,
             0);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, renderedTexture, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);

if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
    assert(false && "framebuffer NOT OK");

1st pass vertex shader

#version 150 core
in vec3 position;
uniform mat4 model;

void main(){
    gl_Position = model * vec4(position,1.0);
}

1st pass fragment shader

#version 150 core
void main(){       //letting the default gl_FragDepth assignment happen
}

2nd pass vertex shader

#version 150 core
in vec3 position;
out vec4 shadowCoord;
uniform mat4 model;
uniform mat4 camera;
uniform mat4 DepthBiasMVP;

void main() {
    gl_Position = camera * model * vec4(position, 1.0);
    shadowCoord = DepthBiasMVP * vec4(position, 1.0);
}

2nd pass fragment shader: the stuck at 1 or 0 problems are in the comments, along with the variations I've tried

#version 150 core
in vec4 shadowCoord;
uniform mat4 model;
out vec4 outColor;

//tried both types
//uniform sampler2D shadowMap;
uniform sampler2DShadow shadowMap;

void main() {
    vec3 finalColor = ...

    float visibility = 1.0;
    vec3 P = shadowCoord.xyz / shadowCoord.w;  //doesn't work
//    vec3 P =vec3(shadowCoord.x, shadowCoord.y, shadowCoord.z); //no difference
//    vec3 P = vec3(shadowCoord.xy, shadowCoord.z / shadowCoord.w); //also no difference

    visibility = texture( shadowMap, P); // always 1

//    //when shadowMap is set to sampler2D
//    vec3 textureCoord = shadowCoord.xyz/ shadowCoord.w;
//    if (texture(shadowMap, shadowCoord.xy).z ==0) //always 0
//    if (texture(shadowMap, shadowCoord.xy).x ==0) //always 1
//    if (shadowCoord.z == 0) //always 0
//        visibility = 0.06;  //

    finalColor *= visibility;
    outColor = vec4(finalColor, 1.0);
}

This is how I call the passes, the object I am looking at is located at the origin

glm::vec3 srcPerspective(0,0,-4);
glm::mat4 depthProjectionMatrix = glm::ortho<float>(-1,1,-1,1,-10,10);
glm::mat4 depthViewMatrix = glm::lookAt(srcPerspective, glm::vec3(0,0,0), glm::vec3(0,1,0));

//pass 1
glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shadowMap.shaderProgram);
depthMVP = depthProjectionMatrix * depthViewMatrix * modelMatrix;
shadowMap.drawIndexed(world, camera, depthMVP, shapes[shipIdx].mesh.indices.data());

//pass 2
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, renderedTexture);
glm::mat4 biasMatrix(
                     0.5, 0.0, 0.0, 0.0,
                     0.0, 0.5, 0.0, 0.0,
                     0.0, 0.0, 0.5, 0.0,
                     0.5, 0.5, 0.5, 1.0
                     );
glm::mat4 depthBiasMVP = biasMatrix * depthMVP;
glUniformMatrix4fv(loc, 1, GL_FALSE, &depthBiasMVP[0][0]);
ship.drawIndexed(world, camera, lightPos, mvp, shipColor, shapes[shipIdx].mesh.indices.data());
omikun
  • 273
  • 1
  • 2
  • 14
  • 1
    Textures are always accessed from 0 to 1. Have you adapted the glViewport when you decreased the shadow-map resolution? – BDL Oct 17 '14 at 20:47
  • I've explained this problem numerous times. I'm just going to point you [here](http://stackoverflow.com/questions/22419682/glsl-sampler2dshadow-and-shadow2d-clarification/22426507#22426507) and tell you that the problem has to do with `sampler2DShadow` and *texture comparison*. – Andon M. Coleman Oct 17 '14 at 22:33
  • I followed your steps but I am still getting only 1 from the comparison. I have the texture compare mode set to GL_COMPARE_REF_TO_TEXTURE, the compare func to GL_LEQUAL (also tried GL_GEQUAL and got all 0's), multiply light matrix, perspective divide, scale and bias the result, and I have not called glDepthRange. I don't know what else I am missing. – omikun Oct 18 '14 at 04:51
  • You should not be using comparison at all if you don't want a value of exactly **1.0** or **0.0** as your question implies. – Andon M. Coleman Oct 18 '14 at 18:08
  • I did not word my question correctly. My problem is the comparison will only return 1.0 for all comparisons. When I sample the depth directly w/o comparison, it returns only 0. When I view the texture on the screen aligned quad, I can see the depth is correct. – omikun Oct 19 '14 at 13:29

0 Answers0