Environment texture reflections behaviour in PBR scenes

Hi guys,

I have a question regarding environment texture reflections behaviour, because it’s default behaviour seems to give a somewhat wrong visual result. Although I understand that from the engine core perspective it works properly.

The thing is when we have such an environment texture, its reflections on objects in a PBR scene will not count the scene objects at all, thus giving ridiculous lighting results sometime. Have a look at the screenshot below, here we clearly see that the env. texture reflection overrides the shadow cast from the objects onto the ground plane:

While this is understood as a default and correct behaviour from the engine perspective, this is totally incorrect from a viewer perspective. So my question is: what is the best and correct way to count scene objects in such reflections calculations for those reflections and the whole scene to look more realistic?

Here is the repro in the playground:
https://playground.babylonjs.com/#4F33I3#46

Thank you!

First, you need directional lights to do shadows. You should place these lights on the opposite side of where you want the shadows to show.

In addition to setting the mesh(es) to receive shadows, you probably want to reduce the environmentIntensity of the material being used by those meshes, or the shadows can appear very faint. Or you can just use a std material for the mesh receiving.

If you wish the lights for the shadows to only be on the receiving mesh(es), you can include only the ones you wish.

light.includedOnlyMeshesIds = ['ground', 'something'];

https://playground.babylonjs.com/#4F33I3#48

1 Like

Yes, thanks, I already have a directional light in the scene and it has a shadow generator.

But what I’m trying to say, is that reducing environmentIntensity is not a valid way to solve this problem. I want environment reflections to be present in the scene, but I want them to be visually correct, otherwise there’s no much sense in having them. The valid way would be to count scene objects in environment reflections calculation somehow, otherwise we will get visualy incorrect lighting all the time.

Do you agree with that?

Um, I think you are in the wrong section. You probably want to change to ‘Feature Requests’. I was answering based on this being a question.

One thing I will add for those searching the forum, which I forgot in the first reply, is if the orientation of the environment texture does match up with where you want it, the texture can be rotated via

envTex.rotationY(radians)

I really do not use shadows in my stuff, so I have not thought much about this. I think your example of using the studio env texture should not really produce any shadows, since there is light coming from 3 sides.

I am not sure a count of meshes sound feasible. The color of a particular pixel is calculated in the fragment shader of the GPU, not the CPU, which is where the environment texture is used. A fragment shader does not even know the mesh this pixel is a part of, much less other meshes & where they are.

Alright, so does anybody know if there are any legit ways of dealing with this, or it should really be a new feature in the engine for that?

Your material has metallic = 1 and roughness = 0.2 so is highly reflective. You can try to lower the metallicness:

https://playground.babylonjs.com/#4F33I3#49

The env texture can’t take into account the objects in the scene and light less objects that would be in the shadow of other objects, if that’s what you mean by “its reflections on objects in a PBR scene will not count the scene objects at all”.

Ok, thank you, but what if I need it to be metallic? Anyway the problem is still there, and we see an unnatural env map glare under the objects which is not a realistic behaviour.

So there should be a way to take into account scene objects when calculating those reflections or at least make reflections to not affect shadows (although this is also not a completely correct way of doing this) for the scene to look more natural.

Do you have any ideas of how this can be achieved?

You can try to use a node material to make the environment texture affects less the parts in shadow:

https://playground.babylonjs.com/#4F33I3#51

Use the ShadowFactor parameter to make the contribution more or less visible.

Well, that’s interesting of course, thank you, but the reflections behaviour is still not correct. The glares can still be visible under the objects which looks very unnatural.

And one more thing is that I’m actually not speaking about one exact scene. The app I’m working on needs to take different scenes from different users, so I can’t set up materials and environmentIntensity each time on each separate scene manually, rather than I need a feature in the engine which can be activated and make those reflections look good and natural.

So can we speak of a legit feature request then in that case?

I’m not sure which feature you request… From what I understand, you would need to replace the environment texture by hundreds/thousands of lights far away that would cast shadows… That’s not going to work for realtime purposes. Or maybe you need global illumination, but that’s also a hard problem to solve in dynamic worlds (for static meshes and lights you can bake lighting).

Maybe others will understand better than me and will have some solutions for you.

Yeah, alright, thank you. No matter which way, I just see the problem and IMHO it should be solved. I’m not an engine developer, but I see that the engine gives a wrong visual result, so I’m pointing to that, seeking for any kind of a solution. In the end what sense is there in having the environment reflections feature if it gives such a wrong and unnatural result?

So I hope Babylon developers won’t just close their eyes to this problem and will offer at least something for that.

By the way, Evgeni, earlier you’ve offered this solution:

But this is not enough as the reflections are still visible in shadowed areas. But if we exclude those reflections from shadows completely, that would give a 90% desired result. So maybe we could implement such an option in the engine? What do you think?

That’s what you get if you set ShadowFactor = 1 in my PG, except I had forgotten that all inputs but lighting are in linear space. Here’s the corrected PG:

https://playground.babylonjs.com/#4F33I3#52

Yeah, thank you, it works, but only if shadow darkness is set to 0 and the shadow is completely black. Any other value makes the reflections in the shadow visible again, so it’s not very useful again.

So it would be better not to just darken shadows to completely black, but to exclude only env reflections from them, so they could have any darkness value and still be blended with the underlying object’s diffuse color. That would make much more sense. Do you think it’s possible?

I tried to fake it:

https://playground.babylonjs.com/#4F33I3#56

You can change the shadow color by using theShadowColor input.

Yeah, visually it works, absolutely, thank you! Especially if you make the shadow darker. Only that it would be great to have alpha blending working, for the shadow to blend nicely with the underlying ground texture. I mean, there is no texture in this exact scene of course, but any other scene with textured ground. Is it possible?

You can use a texture as the albedo color in the node material:

https://playground.babylonjs.com/#4F33I3#57

Yes, super, thank you! So it would only be needed to make that shadow transparent now, so it could be blended with that texture, but only without the env reflection in it. That would solve the problem almost completely, 95%. How is it possible in Babylon?

A multiply should do it:

https://playground.babylonjs.com/#4F33I3#58

Yeah, seems to look almost as intended, thank you! It’s much better than with glares or only black shadow. I will dig deeper into it, I think this can be used as a 85% solution for this issue for now.