Transparent shadows Issue - Stained Glass

Hi everyone !

I have an issue for which I do not find a solution.

I reproduced it in following PG with minimalist scene.

Let’s say there is 2 shadow-casting-meshes in the scene. First one is opaque and the second has alpha.
I try to cast shadows for these 2 meshes, and because I need to play with the shadows color, I have 2 planes with ShadowOnlyMaterial.

What I did first is :

  • Create a light used for scene illumination, and its shadowGenerator for opaque mesh
  • Create a light with minimal intensity and its shadowGenerator for transparent mesh.
  • Add respectivly the opaqueMesh as caster to the opaque ShadowGenerator and the transparentMesh as caster to the transparent ShadowGenerator. Only the transparent shadowGenerator has transparencyShadow attribute set to true.
  • Set the corresponding active light for grounds with colors on ShadowOnlyMaterials : “transparent shadows” appears Blue and “opaque shadows” appears Red.

Because I don’t want the shadows to be too dark (to see a textured ground in my real scene), I set the darkness to 0.5 for both shadowGenerator.

Here is the PG : https://playground.babylonjs.com/#6OP9XW#1

As you can see, unfortunatly, the opaque mesh seems to be completly ignored during the transparentMesh shadow computation, which leads to a too big Blue Shadow, and results into a purple (Blue + Red) part.

Changing the renderingGroups of the meshes helped, but it was still purple.

I then tried to add the opaqueMesh in the transparent shadowGenerator:
https://playground.babylonjs.com/#6OP9XW#2
It looks better, but still the “red part” is logically affected by the blue part.

What I would like to achieve, is the same result as
https://playground.babylonjs.com/#6OP9XW#3
but with transparency in both shadows.

I guess, if I could add the opaqueMesh to the transparent shadowGenerator, not to cast a shadow but to “occlude” correctly the transparentMesh an its transparentShadow, it would be perfect.

But I do not know how to do this.

Any help will be really appreciated

Thanks a lot !

cc @Evgeni_Popov

Unfortunately, I don’t see how to do it simply…

One (complicated) way would be to write to another texture when we generate the depth texture, to record the mesh that this texel in the texture correspond to. Then, when rendering the plane, we would check which object is between the pixel currently shaded and the light, and we would not consider the pixel to be in shadow in case the object is the opaque object… It’s quite involved, and I don’t know if it would scale well with your use case.

Hi @Evgeni_Popov and thanks for you answer.

I get what you wrote, even though I do not have any clue on how to implement this solution.

Could it be easier to achieve it by using the shadowMap from the opaque shadowGenerator as a mask on the shadowMap from the transparent shadowGenerator (maybe with a threshold ?)

Once again, I don’t have a clear vision of the cycle of life and I am not even sure that we can modify shadowMap directly.

Thanks for all advices or ideas !

Yes, I think it would be possible to check in the opaque shadows map if the value is not the clear value, which means that the opaque object is between the pixel and the light, and not to apply the shadow calculation in this case. This would be simpler than my solution, but still not easy.

The problem is that we can’t inject/modify code into the ShadowOnly material, you’ll have to write your own shader / a new ShadowOnly2 class. Also, the existing lighting code doesn’t handle an additional lookup in another shadow map, so that’s something you’ll have to take into account.