Hello. I am writing a simple shadowmapping algorithm with one directional light. I understand the basics but I can't make it work. Can you look at my code snippet and tell me what am I doing wrong?
Shadowmap is correct (1024x1024, one directional light looking at (0,0,0) from (0,10,0)).
float3 PositionFromDepth(in float depth, in float2 pixelCoord, float aspectRatio, float4x4 invView, float4x4 invProj)
{
float2 cpos = (pixelCoord + 0.5f) * aspectRatio;
cpos *= 2.0f;
cpos -= 1.0f;
cpos.y *= -1.0f;
float4 positionWS = mul(float4(cpos, depth, 1.0f), invProj);
positionWS /= positionWS.w;
positionWS = mul(positionWS, invView);
return positionWS.xyz;
}
float GetShadow(float3 posWS)
{
float4 lpos = mul(float4(posWS, 1), gLightViewProj);
//re-homogenize position after interpolation
lpos.xyz /= lpos.w;
//if position is not visible to the light - dont illuminate it
//results in hard light frustum
if (lpos.x < -1.0f || lpos.x > 1.0f ||
lpos.y < -1.0f || lpos.y > 1.0f ||
lpos.z < 0.0f || lpos.z > 1.0f) return 0.0f;
//transform clip space coords to texture space coords (-1:1 to 0:1)
lpos.x = lpos.x / 2.0f + 0.5f;
lpos.y = -lpos.y / 2.0f + 0.5f;
//sample shadow map - point sampler
float shadowMapDepth = ShadowMap.Sample(Sampler, lpos.xy).r;
const float bias = 0.001f;
if (shadowMapDepth < lpos.z - bias) return 0.0f;
return 1.0f;
}
float4 ps_main(PixelShaderInput pin) : SV_Target
{
float2 pixelCoord = pin.texcoord.xy;
float depth = Depth.SampleLevel(Sampler, pixelCoord, 0).x;
// Outgoing light direction (vector from world-space pixel position to the "eye").
float3 posWS = PositionFromDepth(depth, pixelCoord, gScreenDim.w, gInvView, gInvProj);
float shadow = GetShadow(posWS);
return float4(shadow.xxx, 1);
}
The results I get are on the attached image. To me it looks like world space position extracted from depth is not really world space position but I don't know if that's the case.
I'll appreciate any kind of help on this.