0
\$\begingroup\$

Question:

What am i doing wrong in the CalcShadowFactor method? It looks like the depth check is not working correctly.

Body:

I'm using deferred rendering in my engine and i have generated the following shadow map: enter image description here

Which is draw by the following fragment:

void main()                                 
{                                                           
    gl_FragColor = vec4(texture(gColorMap, TexCoord0).x);

}

The position texture is generated like this:

WorldPos0      = (gWorld * vec4(Position, 1.0)).xyz;

Where gWorld is the transformation of the object being draw(translation * rotation* scale)

Finally, in the light pass, i want to generate the shadow produced from this spotlight with the following code:

float CalcShadowFactor(vec3 WorldPos)
{
    vec4 ShadowCoord = gLightWVP  * vec4(WorldPos,1);      
    ShadowCoord /= ShadowCoord.w;
    vec2 UVCoords;                                                                          
    UVCoords.x = 0.5 * ShadowCoord.x + 0.5;
    UVCoords.y = 0.5 * ShadowCoord.y + 0.5;
    float z = 0.5 * ShadowCoord.z + 0.5;                                         
    float Depth = texture(gShadowMap, UVCoords).x;                                          
    if (Depth < z + 0.00001)                                                                 
        return 0;                                                                         
    else                                                                                    
        return 1.0;         
}

It returns a float which multiplicates the color output. I know, im just returning 0 to set the color to complete transparent, it is intensional. The variables used were:

    • gLightWVP: It is the ProjectionView of the camare set at the light:

      Projection * LightCameraRotation * LightCameraTranslation

    • WorldPos: It is the position got from the Position Texture:

      vec3 WorldPos = texture2D( gPositionMap, TextCoord0 ).xyz;

    • gShadowMap: It is the shadow map texture sampler.

    This is what is displayed(notice how the spotlight looks at the first image):

    enter image description here

    The engine passes are:

      • Shadow pass: Render the scene for every light using a alternative camera which is placed in their position with their orientation. It generates the shadow maps for every light. Currently i just have one shadow map for that spot light.
      • Render pass: It renders all the scene using the main camera. It generates the position map, normal map, diffuse map and a specular map.
      • Light pass: It uses all the textures generated to place the illumination. Here is where the shadow map is being checked for generate the shadows.

      EDIT: I'll also leave here the shadow map texture definition.

      glGenTextures(1, &m_shadowMap);
      glBindTexture(GL_TEXTURE_2D, m_shadowMap);
      glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, WindowWidth, WindowHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
      
      glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
      glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_shadowMap, 0);
      
      \$\endgroup\$
      2
      • 1
        \$\begingroup\$ So whats the question? \$\endgroup\$
        – UDXS
        Commented Oct 23, 2016 at 16:12
      • \$\begingroup\$ Yes excuse me, i'll place it more clear. \$\endgroup\$
        – Haruko
        Commented Oct 23, 2016 at 16:26

      1 Answer 1

      2
      \$\begingroup\$

      Normally the 0.5 bias should have been included in the matrix (so I don't think it should be after the division by w) so this shouldn't appear:

      UVCoords.x = 0.5 * ShadowCoord.x + 0.5;
      UVCoords.y = 0.5 * ShadowCoord.y + 0.5;
      float z = 0.5 * ShadowCoord.z + 0.5;    
      

      So instead you should do something like

      gLightMWPBiased = gLightMWP * 
      (
      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
      );
      

      And use glLightMWPBiased.

      Shadow mapping is tricky so there might be other problems, but that's all I saw.

      \$\endgroup\$
      1
      • \$\begingroup\$ I have used it like this (ScaleTransf(0.5f)*TranslationTransf(1.0f)) and i have found the problem. It was so stupid: if (Depth < z + 0.00001) return 0; This must be negative, and also not that small. Thank you very much, it was one of the things that were wrong <3 \$\endgroup\$
        – Haruko
        Commented Oct 23, 2016 at 21:07

      You must log in to answer this question.

      Not the answer you're looking for? Browse other questions tagged .