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:

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);
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;
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;

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

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);
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);

• So whats the question?
– UDXS
Oct 23, 2016 at 16:12
• Yes excuse me, i'll place it more clear. Oct 23, 2016 at 16:26

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.

• 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 Oct 23, 2016 at 21:07