I was exploring shadow mapping techniques. I am still new to all this so there might be some issues/errors in what I am about to post!
So, there are different ‘fit’ modes…:
The ‘Stable Fit’ mode, from what I understand, renders the shadow map using a projection matrix that is sized to fit as many shadows as can ever be rendered on to the screen at once, even if there is only a few shadow casters that take up only a few pixels of space.
On the other hand, ‘Close Fit’ attempts to fit the shadow casters exactly. So this means that if you only have a single shadow caster, that shadow casters shadow will get the entire shadow map for itself resulting in higher quality shadows.
This was my experience when I implemented my own shadow mapping.
I noticed that LWRP didn’t support ‘Close Fit’ fit mode. It only support ‘Stable Fit’!
I would argue that Close Fit would be super useful especially for Lightweight Rendering Pipeline, where resources are limited! Shadow casting is expensive, so most games will probably attempt to limit the number of realtime shadow casters. In our case (and certainly can be the case for many games) we only have the single main character renderer as a realtime shadow caster. It would be great if this single shadow caster was given the entire shadow map to itself so it can render higher quality shadows even with a low resolution shadow map. And if we had many shadow casters on screen, scattered all around, then the ‘Close Fit’ algorithm will eventually encompass the entire screen and itll only ever look as bad as ‘Stable Fit’ anyway. It can never look worse than what we currently have.
Sidenote!:
Strangely enough - the Built In renderer seems to have a ‘bug’ (?) where ‘close fit’ will attempt to fit shadow casters AND non shadow casters (With Shadow Receive ticked on) onto the shadow map, even though non shadow casters do not cast shadows. If these renderers never cast shadows, why is Unity allocating space for them on the shadow map? In my own shadow mapping tests, I could safely ignore the giant floor renderer (shadow receiver only) and simply consider my characters renderer (shadow caster) when rendering the shadow map. The floor renderer had no issues mapping the shadowmap onto its surface.
We have plans to do improvements to shadow system in LWRP after getting out of preview. The goal is sometime in 19 cycle. We need a system that allows us to cache shadowmap between multiple frames/cameras and that has the option to generate tighter shadow frustum like Close Fit, but not necessarily the same approach as CloseFit.
Could you comment on the last part of my post? I am not sure if it is a bug!
Using the Built In renderer… A simple repo would be to have a cube in a scene with a plane floor. Position the game camera so that the plane and the cube are taking up maybe 1/4 of the game view. The plane should be a shadow receiver and not a shadow caster. The cube should be a shadow caster. So the plane should receive the shadow of the cube. Set the Fit mode to Close fit. The shadows will look pretty nice!
Now scale up the plane. As it starts to fill your game view, the shadow resolution appears to get worse… because shadow mapper tries to fit more of the plane into the shadow map leaving less room for the cube. You can see this in the frame debugger.
But this is pointless… right? The plane doesn’t cast shadows, it shouldn’t be allocated any space in the shadow map?
So I’m about to submit a bug report unless you tell me otherwise. I hate the idea of cluttering up the bug tracker which is why I figured I’d ask you first.
I ran into a really extreme case of this today, where I’ve got 2 shadow casting characters, close to each other, near the camera, but they’re using a <300x300 region of a 4k shadowmap (the rest is unused, there’s no other shadowcasters in range) and looking super-jagged
Please give us script control over the positioning of the shadow camera!
(I’m not currently using a scriptable render pipeline… would that be possible if I did use one?)