Shadow mapping issue in Vulkan with orthographic projection

Started by
2 comments, last by snoken 1 week, 3 days ago

Hi all,

I have been trying to implement shadow mapping using Vulkan but have been experience an odd issue which I cannot seem to understand the cause of. The issue I am facing is that when applying shadows to my scene, it seems to think that the top of the sphere is in shadow but it is not.

I am using FRONT face culling with depth set to LESS_OR_EQUAL for the shadow pass.

I was wondering if anyone might know what might be causing this and could provide some insight into where I might be going wrong. Thanks in advance.

r/GraphicsProgramming - Scene render with shadows enabled ( top of sphere is thought to be in shadow )
Scene render with shadows enabled ( top of sphere is thought to be in shadow )
r/GraphicsProgramming - Shadow map (Orthographic)
Shadow map (Orthographic)

Shadow + Light related code

// C++ light set up 
Light ret = {};
auto dir = glm::vec3(0.191, 1.0f, 0.574f);
ret.m_direction = glm::vec4(dir.x, dir.y, dir.z, 1.0);
glm::mat4 proj = glm::ortho(-50.0, 50.0, -50.0, 50.0, 1.0f, 96.0f);
glm::mat4 view = glm::lookAt(position, glm::normalize(glm::vec3(dir.x, dir.y, dir.z)), glm::vec3(0.0f, 1.0f, 0.0f));
ret.LightSpaceMatrix = proj * view;
return ret;
// Fragment shader to calculate shadows based on learnopengl 
float Shadow(vec3 WorldPosition)
{
	vec4 fragPosLightSpace = LightUBO.LightSpaceMatrix * vec4(WorldPosition.xyz, 1.0);
	vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;

	projCoords.xy = projCoords.xy * 0.5 + 0.5;

	float closestDepth = texture(shadowMap, projCoords.xy).r;

	float currentDepth = projCoords.z;

	float bias = 0.005;
	float shadow = currentDepth > closestDepth + bias ? 1.0 : 0.0;

	return shadow;
}
Advertisement

I'd try adjusting the last two arguments to glm::ortho() so that they enclose the scene when viewed from the light perspective. A range of 1 to 96 seems not right.

You should also setup your shadow map to use hardware depth comparison, and not use the ternary operator (use texture().r directly, and apply bias to world coordinates along normal, not using sampled depth). This will give you softer shadows (bilinear filtered).

@Aressera Thanks for the reply! I've tried playing with the near and far for the light but doesn't seem to improve the situation at all. I really have no idea what's causing the shadow on top of the sphere.

Advertisement