Advertisement

Shadowmapping DX11 - shadowmap return white texture in subresource

Started by June 24, 2020 08:58 AM
2 comments, last by Thibault Ober 4 years, 7 months ago

Hello,

I've tried to implement shadowmapping technique but I am failing to get correct values from shadowmap texture to compare it with current (.z / .w) value.

Here is how I am initializing my shadowmap texture:

Shadowmap texture initialization - using R24_UNORM_X8_TYPELESS

Here is the result:

Rendered shadowmap to texture from sun POV

Here is UVs from top of view:

UVs of rendered scenes. These UVs are used to sample shadowmap texture

And here is rendered scene with shader code below:

Rendered scene with shader code below
float4 ShadowCalculation(float3 normal, float4 lightPos, float3 pointToLight)
{
    const float bias = 0.001f;
    float2 projectTexCoord;
    projectTexCoord.x = lightPos.x / lightPos.w / 2.0f + 0.5f;
    projectTexCoord.y = -lightPos.y / lightPos.w / 2.0f + 0.5f;
    
    if (saturate(projectTexCoord.x) == projectTexCoord.x && saturate(projectTexCoord.y) == projectTexCoord.y)
    {
        float depthValue = shadowMapTexture.Sample(baseSampler, projectTexCoord.xy).r;
        float lightDepthValue = lightPos.z / lightPos.w;
        lightDepthValue -= bias;

        return depthValue;
    }
}

This code is used only to checking projected texture value. UVs presented above are in fact just “projectTexCoord.xy”. Also, they're correct. I was comparing values of UV to determine coordinates in shadowmap texture and it seems fine.

By modifying last line to

return depthValue < 0.99989 ? 0.0 : 1.0;

I am getting different results and I think there might be some clue to be found.

Projected shadowmap with “return depthValue < 0.99989 ? 0.0 : 1.0;”
Shadowmapping fixed

I managed to fix that by finding out that my bias value was to high. I changed that to 0.00001f because for some reason, my shadowmap value and z value from light perspective were very close to 1.0f.

Advertisement

There is no error in your code, the depth value stored inside your depth buffer belongs to [0,1] range but in a non linearized way.

Your final depth after applying the projection matrix and the passage to ndc will be equal to this equation:

\begin{equation} F_{depth} = \frac{1/z - 1/near}{1/far - 1/near} \end{equation}

if near = 1, far = 1000

f(2) =$\dfrac{1/2 - 1 }{1/1000 - 1}$ = 0.5

f(100) = $\dfrac{1/100 - 1 }{1/1000 - 1}$ = 0.991

The idea behind this equation is to have more float availables near the camera and so a much higher precision

If your want your original value, I suggest to look at code like this one

float linearize_depth(float z,float zNear,float zFar) 
{ 
	return zNear * zFar / (zFar + z * (zNear - zFar)); 
}

I would suggest to have an idea about the average world unit of your scene it will help you tune your bias

This topic is closed to new replies.

Advertisement