Mesh with custom shader material does not cast shadow

I’m trying to create a custom wind shader for foliage and have encountered some problems.
I have a plane with custom shader material and this material has transparent texture.
The mesh does not cast shadow if needAlphaBlending property is set to true. If I set needAlphaBlending property to false, it casts shadow of whole plane but the shadow does not move.
Here’s playground with example Babylon.js Playground. What am I missing?

If you set needAlphaBlending on your material, you must set transparencyShadow = true on the shadowGenerator.

However it is not enough in your case because you use a custom shader on your plane: the shadow will be back but as a big square.


The system will enable alpha testing during shadow depth map generation if the call to material.getAlphaTestTexture() returns a non null texture. However, as you created a custom ShaderMaterial, this call will return null.

So, I have added this function so that it returns your foliage texture:

However, the shadow stays still even when the foliage is flapping… That’s because the shadow generation code uses its own shader to generate the depth map, and it can’t handle the specific operations that you do in your vertex shader (it does not know them). You need to provide your own shadow depth map shaders for your custom material to work.

I have done it in this PG:

https://playground.babylonjs.com/#ENPTI9#5

You must use the shadowGenerator.customShaderOptions property to instruct the shadow generator that you want to use your own shader to render shadows. Regarding the shaders, I have taken the standard ones used by the shadow generator and simply added your custom instructions (in the vertex shader only, so the fragment shader is just copied from the standard one).

The tricky part was to update the time uniform: I have used the onBeforeShadowMapRenderMeshObservable and onBeforeShadowMapRenderObservable observables, that are triggered just one after the other. The first one allows you to know which mesh is going to be rendered in the depth map, and the second one gives you the effect that will be used, hence provides the mean to update the time uniform.

2 Likes

Wow! Thank you very much. You dropped some really useful info. I have to learn a lot.
And it looks very nice. Perfect! :slight_smile:

I have updated the PG provided in post #2 because of the naming changes that occurred to implement the new ShadowDepthWrapper class (can’t edit my post, must be too old):

https://playground.babylonjs.com/#ENPTI9#7

Also, here’s the same PG using the new class:

https://playground.babylonjs.com/#ENPTI9#8

1 Like