Description: The idea behind PCSS is simple: smooth out the edges of the shadows created by basic shadow maps.
Hard Shadows from Shadow Maps Alone
Soft Shadows with PCSS
PCSS mostly takes place entirely in the fragment shader, allowing for relatively quick implementation.
First, the width of the penumbra is calculated by using the distance of the fragment to the meshes occluding it.
Next, a simple PCF function is run using the determined width as the sample radius.
Finally, the result is subtracted from one, allowing for a range of shadow values rather than a simple "shaded or not".
Blocker Distance:The largest problem I ran up against was the calculation of the blocker distance. The core of this project revolves around finding the average distance to all blockers and using this to estimate a search width.
Banding:The PCF function uses a series of pseudo-random vectors to calculate its shade value. As not all vectors will be weighted equally, this results in "bands" being formed around the image. To counter this, a Poisson distribution can be used, but this can result in spotted shadows instead of bands.
Balancing Constants:There were an amazing amount of constants I found adjustable. In the end, I believe I found a comfortable balance, but allowed throughout the project the ability to tweak on the fly. Orthographic far plane, light size, and orientation were some of the most finicky constants.