How to fake mid range dynamic AO

I have to come up with a dynamic AO solution in the ~1 meter (3 feet) range for gameplay purposes: I have to indicate how far the dynamic hero item is from the static geometry even when in shadow from direct light sources. (Lightmapped environment with a stationary sun.)

Doesn’t have to work for more than one item in the scene. (Although that would be nice.)
Doesn’t have to be physically correct, so I don’t care if it darkens directly lit areas.
Should affect static geometry. (Affecting dynamic actors is a plus.)
The effect’s strength should be tweakable.

So far I tried negative lights but while I can clamp negative colors in post I can’t fix the pitch black hotspots and can’t exclude the hero item from the effect.

Would it be possible to use the mesh distance field for this? I’m not afraid of some light C++ use but definitely not ready to write some new component or something. :slight_smile:

To get simple contact shadows on mobile I created the following fake AO that could easily be scaled up to work on mid range distances, so it might work for you.

Here’s the end result on mobile:

And here’s the material function:

Note that it generates two blobs, if you want just one bigger one you could remove the highlighted nodes. Or if performance is not an issue and you want more detail you could add more of them by copying the highlighted part and adjusting the multiply to -1 / number of shadow generators. Also to get different sizes adjust the 1.002 value, the closer to 1 you get the bigger the effect.
You should add this function to every material that should receive the effect. Add it to the AO node for more correct results or just multiply it into your base color and spec to also influence direct lit areas (and have it work on mobile).

Finally add this to your player controller to update the locations based on the bone locations in a material parameter collection:

Again: delete or duplicate the selected part to adjust the number of blobs.

Note that this adds a couple of instructions to every surface that is potentially shadowed, not just the ones you’ll actually see the effect on. If that’s an issue you might want to also add a material LOD system that switches to a version without this function further away from the player.

Very good idea Arnage thank you. I’ll try to come up with different primitive shapes (beside the sphere) to better match the weird shape of my hero mesh. If I get anything usable then I’ll post it here for future reference.

So I came up with a solution which supports arbitrary shapes:

The core idea is baking a 64x64x64 volume of occlusion values and mapping them using transformed world coordinates. It works as a usual material, decal like on the video or as a post process. Each solution has different caveats. The biggest problem right now is that only simple, single axis rotations are supported, more complex ones make the mapping go weird. Here are the details on AnswerHub, I’d appreciate any help. :slight_smile: