Create shadows from environment lighting

Hello guys,

I try to set up a realistic studio. To achieve this I added the environment to my scene which is used in sandbox.

Initially I thought that the models will be totally black until I add some light to the scene and the environment is just for reflections. But I noticed that the environment is kind of a light source itself. The sandbox has no light too but the model is still visible. This is due to the environment irradiance of the PBR, am I right?

To make the scene more realistic I want to add shadows. But here I encountered the problem that there is no light which I can add to my shadowGenerator. So is it possible to create shadows with the environmental lighting? Or do I have to create a light at the positions of the lamps? If yes, will the light conflict with the light of the environment? What would be the best practice?

I am very curious about your answers.

Thank you!

Yes, the environment map is used as an indirect lighting.

You do need to create a light to generate shadows from this light, environment map can’t create shadows. The (direct) light(s) you will create will simply add to the environment light.

Thanks for your reply.

Am I able to hide the directionallight or spotlight but to create shadows from it? I am pretty happy with the lighting from the environment texture and I don’t want to increase the intensity with additional lights.

No it’s not possible because shadows are the differences between places that receive light (from a light source) and places that don’t. If there’s no light source or the intensity of the source is 0, there can’t be any differences between those two cases.

However, you can fake it by creating a material in the NME:


https://playground.babylonjs.com/#Y1L4MD

In this screenshot, I have setup a light with a 0 intensity. Because the sphere has a standard material (not a PBR), it is all black. The ground however has a PBR node material for which I used the “shadow” output of the PBRMetallicRoughness block to modulate the final color.

Ah, I understand. After playing around with your example I saw the option to disable the light on the pbrMaterial. I added the environment and changed the sphere material to pbr. With this I was able to create something similar without using a material created in the NME. https://playground.babylonjs.com/#Y1L4MD#2

Is one of these two methods preferable?

As result I try to create a scene like this:

There should be a decent shadow below the model. Do you have some recommendations to accomplish that?

Thanks for your support :slight_smile:

It’s not really similar, you do have a light with a non zero intensity, something you did not want in the first place (the ground is still affected by the light).

There are soft shadows in this picture, something that can’t be achieved with point sources. You can fake them a little by blurring the shadows, using blur exponential or PCSS as the filtering method:

https://playground.babylonjs.com/#RMJLYE

You could also try to use materials with ambient occlusion, notably to darken the base of the cube.

Sure, that’s right. With my method the light has a non zero intensity.

I like that blurred shadow. I think I will go with blur exponential as filter method.

I was able to create a consistens shadow using 3 directionalLights above the model. The model and the ground are PBR but the model recieves its light from the environment while the ground receives its light from the directionalLights. It doesn’t look too bad in my opinion:

Otherwise I try to get rid of the ground, because it souldn’t be visible. The edge shouldn’t be visible to be more precise. My idea was to make the ground transparent. Is that possible?

I found the shadowsOnly material which would solve my problem perfectly. But it can only handle one source of light, or am I wrong? I have to get rid of the ground transparency without loosing the shadows or I have to make the shadowMaterial capable of using multiple lights. Or is there another options?

1 Like

Nice effect indeed!

You can perform a little change to the background material to make it usable as a “shadow only” material with multiple lights:

https://playground.babylonjs.com/#RMJLYE#1

Relevant lines:

var gmat = new BABYLON.BackgroundMaterial("gmat", scene);

gmat.alpha = -0.01;
gmat.primaryColor = new BABYLON.Color3(0.7, 0, 0);

ground.material = gmat;

BABYLON.Effect.ShadersStore["backgroundPixelShader"] = 
    BABYLON.Effect.ShadersStore["backgroundPixelShader"].replace(
        /gl_FragColor=color;/g, 
        "gl_FragColor=vec4(vPrimaryColor.rgb, (1.0 - clamp(globalShadow, 0., 1.)) * 1.);");

gmat.alpha = -0.01 is to make the material render with alpha blending => there’s a bug in the class, it should be gmat.alpha = 0.99, I will make a PR for that. But because the alpha value is not used in the (modified) shader, setting the value to a negative value is not a problem.

Use the gmat.primaryColor to change the shadow color:


I wonder if we could add a shadowOnly property to the BackgroundMaterial class to make this easier: @Deltakosh / @sebavan ?

1 Like

This is exactly what I wanted to achieve. I love it!

Thank your for your help and explanation!

I do not see any problems in supporting them but do not forget the main goal of background material is efficiency hence the limitation to only one light at the moment :slight_smile:

But the BackgroundMaterial is not limited to one light :slight_smile:

ShadowOnlyMaterial is.

What is lacking in BackgroundMaterial is a way to behave like ShadowOnlyMaterial. Going to make a PR about this.

PR:

Doc PR:

1 Like

with help of :

scene.imageProcessingConfiguration.exposure = 0.6;

where 0.6 is the power of how much the influence or how strong the light will be in the scene, I suggest to use both environment lightning and some kind of direct/spot light to create some shadow

1 Like