Yep, it's time for even more shadow mapping issues on my end...
I'm encountering a rather weird artifact with my omnidirectional light's shadow mapping, as can be seen in the following image:
It appears to align with the corners where the shadow cube's faces meet. I'm sampling the skybox (also a cubemap) in the same way though, so I don't think my sampling direction is faulty:
#if SHADER_MODEL >= 41 float4 moments = ShadowCubeEV.SampleGrad( ShadowMapEVSampler, float4(shadowVector, arraySlice), shadowVectorDDX, shadowVectorDDY ); #else float4 moments = ShadowCubeEV.SampleGrad(ShadowMapEVSampler, shadowVector, shadowVectorDDX, shadowVectorDDY); #endif
The shadow "direction" vector (it is actually a non-unit vector, which works fine with TextureCube sampling) is simply computed as the world-space distance between the light source and the pixel being shaded:
float3 shadowVector = -(PointLight[lightId].wPos - P); // World-space distance between light source and fragment being shaded float3 shadowVectorDDX = ddx(shadowPos); // These may possibly be wrong, but shouldn't cause the afforementioned issues? float3 shadowVectorDDY = ddy(shadowPos); // Need to be supplied as different code branches provide manual partial derivatives
Furthermore I'm using exponential variance shadow maps. The shadow maps are generated from normal depth maps, rendered using a 90° FOV perspective camera with its range set to the radius of the light source and generated for each cardinal direction in the scene (east, west, north, south, up and down). I'm translating the shaded pixel's world-space coordinate into the light space of these maps like so:
float lightSpaceDepth = (light.matProj._43 / length(shadowVector)) + light.matProj._33;
light.matProj is the projection matrix used when rendering the depth maps as described above.
There is nothing in the shadow maps that to me would hint at the experienced artifact either; feel free to have a look for yourself (click on the images to view higher resolution versions):
Positive moment (x component)
Range: ~1.85x1017 .. 2.35x1017
Negative moment (y component)
Range: ~6.94x10-3 .. 6.74x10-3
Positive quadratic moment (z component)
Range: ~3.42x1034 .. 5.54x1034
Negative quadratic moment (w component)
Range: 4.50x105 .. 5.00x105
So my question then is whether anybody happen to recognize the artifact and / or have any ideas what may be causing it? More code / images can be provided on request.
Update 1: It appears that this is a self-shadowing issue near the edges of the cubemap faces. If the ground object is excluded from the shadow pass, the floor artifacts go away, however the digit meshes aligning with these corner directions (1/4/6/9) then show severe self-shadowing as well. It is not (realistically) rectifiable by using various depth / variance biases.