I’ve found many implementations and many people discussing this famous technique, so I decided to have my own take at it and to also play around with compute shaders. This is a technique used in many AAA titles that greatly helps with making characters feel more grounded in shadowed areas and allows them to have area light shadows. With my implementation, it seemlessly integrates with the existing light probes system, as the shadows’ directions are sampled per character from its interpolated light probe.
Features:
Uses a single compute shader for everything.
There’s no limit on the number of characters, and the screenspace implementation makes it way more performant than classic shadow mapping.
Easy setup, only 1 component needs to be added to a character gameobject that has capsule colliders as children.
Renders a mask for character meshes so that they don’t have self occlusion artifacts.
Samples the dominant light direction from the interpolated light probe the character is at, and each character works independantly.
Uses an axis aligned bounding box based screen space culling per character to optimize an already very performant shader, while smoothly blending out the shadows as they reach their specified radius.
Allows for rendering ambient shadows only in already shadowed areas by directional light (Built in implementation, forward path only).
Built in render pipeline support (requires no dependencies).
HDRP Support through custom pass, supports VR multipass.
Post Processing V2 custom effect implementation, supports VR multipass and single pass instanced through XR plugin management.
Works in the editor as well with all implementations!
Roadmap:
URP support
Adding spheres and boxes.
Adding more ray marching based shadowing algorithms, maybe even emission.
The option to render at half resolution to support very low end hardware.
Bug fixes and performance optimizations, now it computes 0.25x the pixels it used to so it should theoretically have a 4x performance boost in the GPU part.
I’ve postponed URP support because as of right now there’s no camera normals support, there are workarounds but they seem “too hacky” so I think it’d be a better deal to wait for proper support, if any.
Added Luminance Blend, that controls how much luminance “hides” shadows, can be adjusted so that shadows are only shown in shadowed areas. This is much cleaner than the previous implementation that relied on sampling the shadow map from a single light which in this case was the main directional light.
Rewrote the built-in render pipeline version to work with a command buffer for everything, much cleaner this way and now also works in the scene view.
I’m trying out the 2.1 version on Mac with unity 2022.b13. and after I return to the scene when exiting playmode the scene becomes black. Is this a known error?
Default RP
Metal: Compute shader missing buffer binding at index 1 (capsules)
I have a feeling its actually not working on my computer, because when I change the radius of the capsule shadow in the demo scene nothing changes, I will try it in 2021 and see if that helps, have you had ang users that were able to run on MacOS?
I just tried it on 2022.1.0b13 and it works normally on Windows, I haven’t had someone test it for me on MacOS, but I’ll try to get access to a macbook.
Does the previous version (2.0) work fine?
Edit: actually there’s a weird behaviour with shadow radius on 2022, it updates only when the mouse hovers over scene/game view not interactively with the slider, will look into that as well
Try downgrading to 2.0, the built in RP implementation is fundamentally different, though I don’t see why the current version wouldn’t work on a mac, will get to it as soon as I get my hands on one.
On other news, I just pushed a new minor release 2.1.1 with a fix to a memory leak that was happening in built in RP version caused by CommandBuffer.SetFloatParam.
Sure you can just bump up shadow sharpness value and modify the light direction passed to the shader, however unless your character is a bunch of capsules it will look odd