Shadow Contact in Babylon - ambient occlusion

I’d like to do some sort of ambient occlusion on the main plane.
I saw this example in ThreeJS, would it be possible to make it in BabylonJS too?

If so, where should you start?
I think that basically you should create a texture in which to write the z-buffer by taking the scene from below. Then create a shader that uses it to create the shadow and apply a blur effect on it.

You can use an orthographic camera that renders from behind in a render target texture, and use that texture as the emissive texture of the plane:

We don’t have a depth material, so I created a material plugin to emulate it.


Perfect, now I’m going to implement it in my project, you’ve been really helpful.

A thousand thanks

Could this be added as a built in feature? I’ve tried using ssao2 for contact shadows but it was hard for me to get it to look good without messing up the ssao effect in the rest of the scene.

We’ll have to discuss this with the team, but it’s something that could happen!

In the meantime, you can use the PG I’ve provided to take advantage of this feature.


I think if it were integrated into Babylon
it would be nice to be able to define this type of shadow for any plane,
the top of a table, a front face of a wall, etc. Maybe with a flag that allows you to define the shadow texture as static without updating it in real time every time for the entire scene.

Hi, today I implemented your code and I’m really satisfied with the first result.
Thank you.

Now I should try to create this plane on top of any object, for example a table top, by placing the plane above it at a distance of 0.001.

Would it be possible to show only the shadow on the table top and thus let the table material shine through?

This is the idea but there could also be another way.

A thousand thanks

Same as usual, @Evgeni_Popov this looks great !!! I wonder how it can be reused/documented in a way it would benefit others in an easy sharable way ?

Here’s how you can do it on a plane with an opacity texture:

I think we should discuss how we can package it so that it’s easy for users to take advantage of it…


nice work , just thinking ahead , maybe it should also have means to just render it once , less processing for scenes where you know the assets would be static…

1 Like

Hello and thanks,

I think it might be interesting to create a class, for example:

floorPlane = new ShadowPlane( x, y, z, width , height, normal, minZ , maxZ );

floorPlane.renderList.push( mesh )


if the distance of the mesh from the plane is between minZ and maxZ then render mesh

It would be interesting to be able to create multiple planes, and insert the normal of the plane as a method parameter. (see the image with the walls)

Thanks for your feedback!

We’ve added it to our to-do list, but we may not be able to do it for version 7.0, as the release is close and we still have a number of things to finish.


Amazing works folks!! This is exactly what I have been looking for!!

Just wondering, is there a way to tweak the “gamma” value of the depth map? For example:

In the above render, is there way to control the gamma of the gray area in the shadow? Just like the curve tool does in Photoshop.

Or in other words, is there a way to control the detail level of depth map? If I only want the shadow gradient visible for big details and ignoring fine details on the mesh surface, if there is a way to achieve it?

Many thanks,

You can try to apply some transformation to the depth value before it is used to compute the color (see line 254):

1 Like


Thats helps a lot! Thank you so much!!!

Just wondering is it possible we can add some post process or other ways to have extra control besides tweak the vDepth value only? I have been tryin to play different vDepth values but feels like if there are other ways to fine tune it would be great - visual result is not ideal. I was trying to add some post processes to the bottom camera but ended up it affected on render camera. Feels like I didnt do it the right (elegant) way for this post process idea.

See line 117-118:

Many thanks,

You should pass an ImageProcessingConfiguration parameter to the ImageProcessingPostProcess constructor, else the whole scene will use the same image processing configuration than the bottom camera:

Note that your post-process(es) should update the alpha channel of the render target, as the effect is only based on the alpha channel and not on the r/g/b channels.

1 Like


Gotcha. Makes sense. Thank you so much for all the info!! This is a much cooler effects to mimic ground occlusion. Love it! Really hope we can add this to the official release.

Many thanks,