Pages

Dynamic Shadows with SDFs

 For dynamic shadows I use SDF volumes, they are generated at runtime for each dynamic object.

Storage support: f16, u8 or BC4

 Can toggle between these formats at runtime to compare them, there isn't much difference, although obviously fp16 has the overall best quality.

 Performance is quite good, the tracing is done during visibility buffer shading pass, with each draw call ID having an associated list of  shadows to process.  

There is a fast shadow mode that uses nearest point on line from sphere to give us a quick sample location, this only requires a single volume read, but is very approximate.

Or you can enable tracing, where it loops and traces the SDF, 8 loops gets a solid result, but 16 is better.

 It exits early once a shadow is 0, or we have traveled to a point where no further shadowing can occur. The early exits are very important, without them perf is *not* good.

 There is also an option to enable screen space shadows to augment the SDF shadows, but it is mostly only useful for objects with really skinny bits that aren't well captured by the SDF. 

 It uses the SDF closest hit location as the starting point for screen space tracing.

Perf is worse for screen space shadows than SDF shadows, and it doesn't do much overall so it is off by default.

 The dynamic shadows are intended to look very similiar to the baked shadows, so they use a nearly identical method to produce results. 

The reason they should look similiar is that when a dynamic stops moving, after some time it gets baked into the world, this transition is less noticeable if the lighting & shadows match up.

In this image the left shadow is baked while the right shadow is dynamic.

 

Other tidbits:

A hash of of the program used to generate the SDF is computed, this is used to share the SDF between identical dynamic objects.   

 If the first hash fails, after generating the SDF and encoding it, a hash of the encoded SDF is also computed, this is to share the uploaded GPU SDF slot,  as it is possible that the program was different but after range normalization and compression that the final results are identical. This primarily comes about from changes in scaling size to the shape or one of the ops-mostly BC4 benefits form this, as it is far more likely to end up identical.