Physically based scene with dark skybox

Hello BabylonJS folks

I’m setting up a fully PBR scene, all materials are PBR ones, i use physical light units and falloff, aswell as physical exposure computations based on ISO, aperture and shutter speed.

It looks great, and seems physically correct. Unfortunately the old StandardMaterial skybox is really dark, almost black, due to the exposure computations.

I changed the reflection texture to use a HDR one, with the idea that if the luminance stored in the HDR is the same as in a real life scene, it would behave correctly, but the skybox remains almost black.

So i was wondering were is my mistake, did my assumption about a HDR with real life luminance value is false, did i load it in correctly, or maybe the texture values in Babylon are automatically remapped to [0; 1] range.

I would like to bring a playground to show you what it looks like, but in order to make things physically correct i had to remove the clamp(finalcolor.rgb, 0.0, 30.0) done in `pbrBlockImageProcessing.fragment.fx. This part of the shader totally breaks the luminance values received by the camera. Otherwise is there a way to ignore this part of the shader ?

Thanks in advance

Why not using a PBRMaterial on the skybox ?

1 Like

I just tried with a .dds, a .env and a .hdr as reflection textures for a PBRMaterial and the result is the same. The scene looks correctly exposed, but the skybox looks like it’s night time.

This is what i get

And here what the skybox is supposed to look like

Maybe i load those textures incorrectly

new BABYLON.CubeTexture(url, scene, undefined, false, undefined, resolve, reject, undefined, undefined, undefined, false, 1.0, 0.0, undefined, true);

BABYLON.CubeTexture.CreateFromPrefilteredData(url, scene);

new BABYLON.HDRCubeTexture(url, scene, 1024, false, true, undefined, true, resolve);

The 3rd one should work with a .hdr file.

If you could setup a repro in the Playground it would help a lot.

I would like to bring a playground to show you what it looks like, but in order to make things physically correct i had to remove the clamp(finalcolor.rgb, 0.0, 30.0) done in `pbrBlockImageProcessing.fragment.fx. This part of the shader totally breaks the luminance values received by the camera. Otherwise is there a way to ignore this part of the shader ?

Have you tried to simply disableLighting in your skybox standardMaterial? In this playground it works: Babylon.js Playground (line 18)

You can overwrite the pbrBlockImageProcessing shader block:

BABYLON.Effect.IncludesShadersStore['pbrBlockImageProcessing'] = `
#if defined(IMAGEPROCESSINGPOSTPROCESS) || defined(SS_SCATTERING)
    // Sanitize output incase invalid normals or tangents have caused div by 0 or undefined behavior
    // this also limits the brightness which helpfully reduces over-sparkling in bloom (native handles this in the bloom blur shader)
    //
    // Subsurface scattering also requires to stay in linear space
    //finalColor.rgb = clamp(finalColor.rgb, 0., 30.0);
#else
    // Alway run to ensure we are going back to gamma space.
    finalColor = applyImageProcessing(finalColor);
#endif

    finalColor.a *= visibility;

#ifdef PREMULTIPLYALPHA
    // Convert to associative (premultiplied) format if needed.
    finalColor.rgb *= finalColor.a;
#endif
`;
1 Like

Thank you, i’m gonna setup a repro asap.

Here is a playground : https://playground.babylonjs.com/#DG842Q#16

You can choose between two hemispherical lights emitting 20k lux (see this for my source on the sky/sun intensity), and an HDR/env texture to do image based lighting.

  1. The light emitted by the textures is not powerfull enough compared to the hemi lights.

  2. The skybox is darkenned as the values present in the textures are not real luminance values, so the exposure darken it a lot.

Ok i think i got it. I am just extremely stupid. In a HDR, env or dds texture, the luminance values are already post processed (rexposed, tonemapped, …).
So in order to have absolute luminance values, i have to invert the transformations done by the camera that captured the textures. In my case setting the environmentIntensity to maxLuminance works well.

2 Likes