When dealing with bigger indoor rooms and don't have setup the whole environemnt probes needed. You can see in this screen:
The last (unreachable space) is marked with pink in this screenshot, As you can see the shadows don't cover the whole cave / level in view. Instead (after what i have found out)
it just covers (with a default cascade size of 4.0) a range of 64.0. So the first cascade goes from near to 4.0, the second from 4.0 to 8.0 and the last covers a range from 8.0 to 64.0. The rest just can never receive shadow as long as the camera to far away. One way to fix this would be to raise the initial cascade distance to something much higher like 40 an above. this leads to artifacts and ugly shadows for the near shadows because they are at a too low resolution for the covered area.
From a previous research (years ago) I remembered a logarithmic approach mentioned by nvidia about PSSM (https://developer.nvidia.com/gpugems/gpugems3/part-ii-light-and-shadows/chapter-10-parallel-split-shadow-maps-programmable-gpus) to calculate the cascade sizes.
Josh, maybe you should try this apporach or add the ability to configure the whole cascade sizes by ourself.
float get_cascade_split(float lambda, UINT current_partition, UINT number_of_partitions, float near_z, float far_z)
{
// https://developer.nvidia.com/gpugems/gpugems3/part-ii-light-and-shadows/chapter-10-parallel-split-shadow-maps-programmable-gpus
float exp = (float)current_partition / number_of_partitions;
// Logarithmic split scheme
float Ci_log = near_z * std::powf((far_z / near_z), exp);
// Uniform split scheme
float Ci_uni = near_z + (far_z - near_z) * exp;
// Lambda [0, 1]
float Ci = lambda * Ci_log + (1.f - lambda) * Ci_uni;
return Ci;
}
Vec2 camera_range = camera->GetRange();
float lambda = 1.0; // full log (0.0 = linear)
int total_cascades = 3;
for (auto cascade = 0; cascade < 3; cascade++)
{
float cascade_near = get_cascade_split(lambda, cascade, total_cascades, camera_range.x, camera_range.y);
float cascade_far = get_cascade_split(lambda, cascade + 1, total_cascades, camera_range.x, camera_range.y);
Print("Cascade:" + WString(i) + " --> " + WString(cascade_near) + "-" + WString(cascade_far));
}
this returns something like this:
Cascade:0 --> 0.1-2.15443
Cascade:1 --> 2.15443-46.4159
Cascade:2 --> 46.4159-1000