Sign in to follow this  

Shadow Map artifacts

Recommended Posts

The first run always fails. Though, I am happy with the fact that I see something that looks like a shadow. I visualized the shadow factors (and some fog as well) obtained after PCF filtering at one position only. This results in three noticeable artifacts. First, a bright (high shadow factor) plane seems to subdivide my scene at the spotlight's origin. This seems to be related to the positioning of my default near z-plane (0.01f). I tried to reduce the near value, resulting in the disappearance of that bright plane. For some near values, flickering can still be noticed (especially while moving). Unfortunately, reducing the near value seems to let my shadow disappear (perspective matrix is kind of broken due to divisions by low near value). 

Second, I notice an anti-symmetric shadow appear on the other side of my scene (pinhole camera principle). I don't know if this is actually problematic or can become problematic, since the light contribution, which still needs to be multiplied with the shadow factor, will be zero anyway.

Third, both shadows seem to disappear when I move close to them with the camera? Of course, a camera dependence on a static light is mathematically not possible. In my code, however, there is a small connection. My shading is performed in camera view space (cview), so my positions in camera view space need to be transformed to light projection space in the PS. I use the following matrix chain for creating this cview-to-lprojection matrix on the CPU:

cview_to_lprojection  = view_to_world * world_to_lview * lview_to_lprojection

For my shadow map depth passes, I perform the same transformations to avoid numerical issues. This means that vertices are transformed to camera view space first and then to light projection space in the VS (so not a combined transformation matrix).

 

 

Clipboard01.png

Clipboard02.png

Edited by matt77hias

Share this post


Link to post
Share on other sites

Actually, all shadow factor artifacts do not seem to result in light artifacts (since the light contribution will be zero outside the light volume). My falloff distance was very aggressive towards the wall. I also forgot to multiply my umbra angle by two to obtain the FOV, which resulted in some small square instead of a large circle projection on the wall. This also solves the camera dependency issue.

Solid render:

Clipboard06.png.de5210fb760d77aa6cbf1cd3e4c7f9e8.png

Furthermore, my depth pass uses a correct DepthStencilState, but I seem to break through walls (i.e. I have multiple stacked projections on consecutive walls)?

Clipboard07.png.70c48f5569fe4e2db0a9647dc19a0d98.png

Edited by matt77hias

Share this post


Link to post
Share on other sites

I solved the strange dynamic behavior of my shadows. I specified a D3D11_DSV_DIMENSION_TEXTURE2D instead of a D3D11_DSV_DIMENSION_TEXTURE2DARRAY, while using the member variables of D3D11_DEPTH_STENCIL_VIEW_DESC::Texture2DArray. So in the presence of multiple lights, all lights map to the same DSV of the resource (although creating multiple DSVs). The first light dominates the DSV the most, but other lights can still rewrite depth values if their fragments get closer since each light still has a correct camera. This results in (1) shadows becoming thicker while moving and (2) the appearing and disappearing of shadows, since lights can be culled, changing the offset of the lights for which a shadow map needs to be generated.

C style OO ;)

// Create the DSV descriptor.
D3D11_DEPTH_STENCIL_VIEW_DESC dsv_desc = {};
dsv_desc.Format        = dsv_format;
dsv_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
dsv_desc.Texture2DArray.ArraySize = 1u;

 // Create the DSVs for each texture element.
for (UINT i = 0u; i < texture_desc.ArraySize; ++i) {
       dsv_desc.Texture2DArray.FirstArraySlice = i;

       ...    
}

// Create the SRV descriptor.
D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc = {};
srv_desc.Format        = srv_format;
srv_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
srv_desc.Texture2DArray.MipLevels = 1u;
srv_desc.Texture2DArray.ArraySize = texture_desc.ArraySize;

I still, however, don't understand how the same (but enlarged) shadow could appear on two consecutive walls? Idd. for an omni light (only the shadow factor is shown!):

Clipboard02.png.b1cdf256e8087fecaa70561f470e2e5a.png

If I set the far plane much closer to the omni light's origin (4m to 1m), the back still results in a large contribution after PCF although this area is positioned behind the red light volume (far z planes)?

Clipboard03.png.2f95080ea15c229ccca6f408c88bb92d.png

Maybe this is due to the non-linear spread of Z-values? My Z far values are set to the end of the light volume. I can, however, use that Z far value for view frustum culling only and use a larger Z far value for my depth pass?

Edited by matt77hias

Share this post


Link to post
Share on other sites

Some extra results for omni lights (I put a single-sided sphere around the center of the light for clarity).

In the close vicinity, the shadow factor (shadow of the leaves) looks ok (without using ray casting to check :) ) : Clipboard02.png.66f9e7a52a981e52c46dd2b9cf482109.png

But behind the curtains, it looks wrong (how could the shadow of the leaves be visible so close to the curtain itself?):

DepthBias: 400 -> 400/(2**16) = 0.006

Clipboard03.png.a9912e0b86befd66bf157807b492980f.png

DepthBias: 100 -> 100/(2**16) = 0.0015

Clipboard01.png.fa7f7feac8ba2012cbf5f4b9de9785df.png

Edited by matt77hias

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this