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\$
      • 1
        \$\begingroup\$ So whats the question? \$\endgroup\$ – UDXS Oct 23 '16 at 16:12
      • \$\begingroup\$ Yes excuse me, i'll place it more clear. \$\endgroup\$ – Haruko Oct 23 '16 at 16:26
      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\$
      • \$\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 Oct 23 '16 at 21:07

      Your Answer

      By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

      Not the answer you're looking for? Browse other questions tagged or ask your own question.