https://catlikecoding.com/unity/tutorials/rendering/part-15/
2.7 fading shadows
the shadow map is finite. it can not cover the entire world.
the larger an area it covers, the lower the resolution of the shadows.
uniy has a maximum distance up to which shadows are drawn. beyond that, there are no real-time shadows.
this distance can be adjust via Edit/Project Settings/Quality.
when shadows approach this distance, the fade out.
To fade the shadows, we must first know the distance at which they should be completely gone. This distance depends on how the directional shadows are projected. In Stable Fit mode the fading is spherical, centered on the middle of the map. In Close Fit mode it’s based on the view depth.
The UnityComputeShadowFadeDistance function can figure out the correct metric for us. It has the world position and view depth as parameters. It will either return the distance from the shadow center, or the unmodified view depth.
the shadows should begin to fade as they approach the fade distance, completely disappearing once they reach it.
the UnityComputeShadowFade function calculates the appropriate fade factor.
float shadowFadeDistance =
UnityComputeShadowFadeDistance(worldPos, viewZ);
float shadowFade = UnityComputeShadowFade(shadowFadeDistance);
What do these functions look like?
They are defined in UnityShadowLibrary. The unity_ShadowFadeCenterAndType variable contains the shadow center and the shadow type. The _LightShadowData variable’s Z and W components contain the scale and offset used for fading.
float UnityComputeShadowFadeDistance (float3 wpos, float z) {
float sphereDist = distance(wpos, unity_ShadowFadeCenterAndType.xyz);
return lerp(z, sphereDist, unity_ShadowFadeCenterAndType.w);
}
half UnityComputeShadowFade(float fadeDist) {
return saturate(fadeDist * _LightShadowData.z + _LightShadowData.w);
}
the shadow factor is a value from 0 to 1, which indicates how much the shadows should fade away.
the actual fading can be done by simpling adding this value to the shadow attenuation, and clamping to 0~1.
float shadowFade = UnityComputeShadowFade(shadowFadeDistance);
shadowAttenuation = saturate(shadowAttenuation + shadowFade);