Realistic contact shadow / ambient occlusion

I’ve just seen some very realistic ground contact shadows in some models of Sketchfab and it seems that is generated realtime as a post process. Is it possible to get something similar with the built in babylon post processes?

I’ve tried modifying the playground of the AO post process but it is not near that one:
https://www.babylonjs-playground.com/#N96NXC#22

This would only usually work on a plane.

I guess to efficiently do those, either you bake offline a texture looking like this:
image

or you would need to render from the top on a rendertargettexture the depth to the plain then make a special blur (probably 2-3 passes) depending on the previous result. This might be a bit slow and it looks like sketchfab generates it on the server.

Thanks for your answer. I think I may try something like your second option, as it needs to be created on the fly and not baked beforehand, but it seems complex to get that blurred shape :wink:
But if you look closer at the edges of that shadow, it seems that flickers a bit and it’s being updated as the camera moves, so it may be some screen space post process, but also taking into acount the zdepth. It’s a really good effect by the way, so congrats to the developer.

The flickering is probably linked to the TAA and super sampling techniques they are using in their render.

Hi again @sebavan, I’ve got back to this task and I’m almost there I think, but I’ve got some trouble getting the depth map as a texture. I’m using scene.enableDepthRenderer(camera).getDepthMap() but I’m getting an all reddish texture like in these playgrounds:
https://www.babylonjs-playground.com/#T5YWJQ#4
https://playground.babylonjs.com/#NH8QH5#1
image

Is it possible to get a black and white image from that depthRenderer and convert it to a base64 image or jpg, png…?

You can use texture.readPixels to read the values in an ArrayBuffer and use a canvas2D to create a png from it ?

Thanks @sebavan, it worked! I had some trouble figuring out the conversion of the float32array and the fact that the zdepth info was stored only in the red channel. I’ve modified the playground with an almost working sollution for getting the texture out as a base64 (but it’s skewed and clamped, so I need to work that part out):
https://www.babylonjs-playground.com/#T5YWJQ#12

EDIT: I solved that part and I’m getting the right depthmap texture (it was the rendercanvas not sizing properly)
https://www.babylonjs-playground.com/#T5YWJQ#13

Note that there is a new helper function that let’s you get a texture as a base64 string:

https://www.babylonjs-playground.com/#T5YWJQ#18

Note: clear the cache of your browser if you get an error.

Thanks for the info Eugeni. It works but the image is red, so I need to process it to remove the color:
image
And also I needed to open an anonymous browser window in order for it to work (clearing the cache didn´t work in my case)

Anyway, using the helper function you mention provides a cleaner and shorter code (no need to mess with temprary canvases and 2d contexts), the only real concern here is the red tinting but it’s something that is related on how the depthmap is created in the first place I think :slight_smile:

Yes, the depth map only updates the red component as it is a single float.

Following! this is great progress. I just posted about a similar question. Please keep us updated as to your progress.