Skybox Reflection on MirrorTexture is darker than metallic PBR material

When I’m using an albedo different from (1, 1, 1, 1), the skybox reflection visible on the mirror material is always darker than the one on the metallic material.

I originally followed the issue Reflection MirrorTexture is not affected by PBRMaterial’s roughness #5146 to get matching roughness result, but then I discovered a lightness difference.

Repro: https://www.babylonjs-playground.com/#1YAIO7#150
Result and expected result:

Hi.

Is there a particular reason you are giving a mirror material albedoColor of 0.5?

Basically as I understand it, this is what is going on.
Let’s take skybox color or white which is (1,1,1).

That color is reflecting in mirror material and it is reflecting that value to be (1,1,1). When you set albedoColor of the mirror material to (0.5,0.5,0.5), the mirror will multiply that albedoColor with the values that it should reflect. So in the case of skybox white value, the result will be
1 (value of the skybox color) * 0.5 ( albedoColor of the mirror) = 0.5 (finalOutput color).
Which obviously turns (1,1,1) to (0.5,0.5,0.5).

So to have mirror reflecting the same thing, you have to set albedoColor of mirror to white (which is already set as default value), so every value which is reflected is multiplied by 1, and remain the same.

https://www.babylonjs-playground.com/#1YAIO7#151

My goal is to put the mirror texture on a metallic planar object so that it can reflect other specific objects close to it. I would like to have self-reflections on an object that have multiple meshes.

The metallic object will have the mirror texture only on a specific mesh, but everything else will have the material without any mirror texture. To do so, I need both materials to visually match, and I know in advance that my object won’t be (1, 1, 1, 1).

To my understanding, MirrorTexture wasn’t designed for this and I’m using it the wrong way. Do you think I can tweak the material that have the MirrorTexture so that it reacts the same way as the metallic material, except that it reflects more objects ?

EDIT:

Event with a (1, 1, 1, 1) albedo, there is a reflection difference on the ground image

Hmm. I am not sure if I properly understand your issue. But it doesn’t matter what your object color will be. As I said, object color will be reflected by mirror with the same values they have. So if you have (1,0,0) color object in the scene, the mirror will reflect (1,0,0) if the albedoColor of mirror is white.

So you can imagine this situation without mirrorTexture at all, you have sphere mesh and the plane/mirror mesh. You have two pbrMaterials. on them. Sphere albedo is red (1,0,0), mirror albedo is grey (0.5,0.5,.0.5) → which is your case pretty much

Now you create mirrorTexture (reflectionTexture) and you put it on the grey plane/mirror mesh. That reflectionTexture contains the data taken from the scene (so it contains the values of the red sphere albedoColor (1,0,0).

But what happens, because you have albedo (0.5,0.5,0.5), every value of reflectionTexture will be multiplied by 0.5. So the values of red sphere that reflectionTexture contains (1,0,0) will be multiplied by (0.5,0.5,0.5).

I hope this makes sense… So basically if you keep your mirror albedoColor as (1,1,1), the objects around ,which mirror reflects, will get their colorValues reflected the same. So blue sphere will be blue, red will be red, and sphere with textures will reflect those texture properly.

And the reason you don’t get the match in your example is because it’s, well, mirror. Basically, you are reflecting the skybox color behind the camera, not behind the plane.

image

The problem is that the mirror texture is generated as a gamma corrected texture by default and the HDR data above 1 are lost because the rgb channels are clamped to 1 in this gamma correction processing.

To fix this, you have first to use a FLOAT or HALF_FLOAT texture for the mirror, as the default one (RGBA8) won’t be able to store HDR data (see 5th parameter of the MirrorTexture constructor).

And to avoid the gamma correction to be applied when the mirror is generated, you need to set scene.imageProcessingConfiguration.applyByPostProcess = true before the texture is generated so that the gamma correction code is not injected in the shaders. You also need to set the gammaSpace property of the mirror texture to false to indicate it is generated in linear space. One small caveat here is that you need to do it after scene.imageProcessingConfiguration.applyByPostProcess is reset (see line 55) because there is an observer in the mirror class that will overwrite the gammaSpace property with the wrong value.

Corrected PG:

https://www.babylonjs-playground.com/#1YAIO7#153

1 Like

Thanks, this is exactly what I was looking for !

Thank you @nogalo as well ! My problem wasn’t very clear, my goal is not to get a mirror result, but actually to get PBR material result when a MirrorTexture is added.