How to combine tone mapping, IBL, and layers?

I’m trying to match a scene background to a background that’s used for the rest of the page in HTML. Babylon is set up with tone mapping, so the background color would be affected by tone mapping - not ideals.

I’ve been using inspiration from How to prevent postprocess effects from affecting background color - #4 by Anupam_Das which works (worked) great.

However, when adding IBL pipeline things don’t play well together.

Here’s PG: https://playground.babylonjs.com/#8R5SSE#525

It seems that using layerMask on camera/layers messes thing up:

// This renders BG layer.
// scene.activeCameras = [bgCamera];

// This renders IBL scene.
// scene.activeCameras = [camera];

// This renders no BG layer, and no IBL in the scene o_O
scene.activeCameras = [bgCamera, camera];

Is there way to use layers properly? Or… is there a more modern way to avoid applying tone mapping to the background?

You miss two things when both cameras are active:

  • you must clear the scene with the (0,0,0,0) color
  • you must enable alpha mode on the last post-process, so that the layer can be properly blended with the scene

In your case, you also need an additional step, which is to force clearing the first post-process of the chain. Clearing the first post-process is enabled by default, but only if the post-process has no alpha. In the PG you linked, this step was not needed, because DoF is the first post-process and has no alpha, but in your case you only have the image processing post-process, and this one has alpha. To force clearing a post-process with alpha, you must set forceAutoClearInAlphaMode to true.

Here’s the PG with these corrections:

IBL shadows still don’t work, though. cc @MiiBond, maybe the effect is not fully supported when there are multiple cameras in the scene?

One (unrelated) thing I noticed, is that camera.onViewMatrixChangedObservable keeps having new observers added each frame. It is because of code lines 796 and 1083-1085, which adds a new observer each time the active camera changes (which happens every frame). I think it could be replaced with this code (?):

        this._cameras.forEach((camera) => {
            camera.onViewMatrixChangedObservable.add(() => {
                this._accumulationPass.isMoving = true;
            });
        });
3 Likes