Is there a way to render overlapping shadows correctly with
Currently the only way I have figured how to render multiple shadows is create one shadowOnlyMaterial for each shadow generator, and then assign this shadow material to an exclusive mesh. I couldn’t find other ways since
ShadowOnlyMaterial is not supporting multiple lights at the moment. The only downside of this approach is the blending mode between each shadow is currently “over”. But the actual blending mode should be “multiple” for a realistic visual result.
Here is my PG:
As reference, here are render tests with ray tracing (rendered in Arnold for Maya):
You can see the red and green shadows are “multiplied” instead of “over” on top of each other.
If use a PBR material on ground instead of “ShadowOnlyMaterial”, the render result also match the ray tracing rendering (which shadows are “multiplied”):
Please let know if there are other ways to achieve this.
IMHO the shadows on the Maya render are multiplied as well. Aren’t they?
Yeah, in Maya render they look multiplied on each other.
The main reason I am trying to use “ShadowOnlyMaterial” to render shadows is just trying to control the shadows independently from the scene lighting. I believe “multiply” between shadows in this approach is the best way to mimic how shadows works in real life.
Hope this makes sense.
Basically you can use transparencyMode, alphaMode and the alpha props on the ShadowOnlyMaterial to change the color blending. I suggest you to try out some combinations and find the best values which fits your needs. There are more props which can affect the overall result so I strongly suggest you to read the documentation about transparent rendering.
Hope this helps!
Seems like shadowOnlyMaterial should support more shadows. Maybe @Evgeni_Popov has a trick ?
I’m not sure what is the end result you want to achieve.
Shadows are not multiplied, it’s only light which is added or not depending on the pixel being in shadow or not. In this screenshot:
The red areas are red because the areas receives lights from the red light (r,0,0) but not from the green light (0,0,0). The contributions are added (r,0,0)+(0,0,0)=(r,0,0) and yield to the final result. Same thing for the green areas. The black areas don’t receive any light, that’s why they are black.
I don’t know how the Arnold rendering is generated, as parts in shadow from both lights should be black (or have a default ambient color)…
I tried something in this PG, where I added a
shadowColor to the
DirectionalLight object, and used it as the “shadow color” instead of considering that shadow = no light:
Thanks for the response guys!
@roland Thank you for the trick! Looks this should solve the blending mode need. I will look into it and figure out how it works!
@Evgeni_Popov Thank you for explanation and the PG! Yeah I understand that in physically correct world, it should be a lights adding on each other instead of shadows multiplying each other. I was trying to find a way just to “mimic” the right look with shadows “multiplying” on each other. Arnold just allows you to change shadow color under each light - which looks like what you do in your PG. However when I open your PG its a pure white canvas on my browser. Do I need to install any libraries to make it working?
Ah, I bet you are using a Mac!
We disable uniform buffers (to overcome a bug with Safari I think), and I only updated the shader code for the uniform buffer path.
Here’s the fixed version:
Yayy I can see the render now! And yes I am using Chrome on Mac OS.
And yes allowing lights to control shadow colors is what Arnold does. Looks this could be a handy feature to have. Do you have plan to add this to babylonjs officially?
In general it would be really nice to enable
ShadowOnlyMaterial to support multiple lights instead of only one at the moment. Is it possible for you guys to add this?
We have no plans to update the current standard / PBR materials or the
ShadowOnlyMaterial, but contributions are always welcome if anyone wants to get started!
@Evgeni_Popov Gotcha! thank you very much!!
Thanks everyone again.