SkyBox questions, BackgroundMaterial vs PBRMaterial: microSurface blur

My project requires the ability to toggle a skybox - this can be, depending on the situation, with ground projection or without. So I’m writing a function to do this.

Function code
const envTex = new CubeTexture("../res/img/env/" + fileName + ".env", scene, null, false, null, () => {
        scene.environmentTexture = envTex;
        const skyBox = MeshBuilder.CreateBox("skyBox", { size: 2000, sideOrientation: 1 }, scene);
        skyBox.isPickable = false;
        skyBox.infiniteDistance = true;
        skyBox.ignoreCameraMaxZ = true;
        skyBox.disableLighting = true;
        const skyMaterial = new BackgroundMaterial("skyBoxMaterial", scene);
        if(isGround) {
            skyBox.position.y = 950;
            skyMaterial.enableGroundProjection = true;
            skyMaterial.projectedGroundRadius = 200;
            skyMaterial.projectedGroundHeight = 7;
            camera.upperBetaLimit = Math.PI / 2;
        } else {
            skyMaterial.microSurface = 0.93; // Doesn't work
        }
        skyMaterial.backFaceCulling = false;
        skyMaterial.reflectionTexture = envTex.clone();
        skyMaterial.reflectionTexture.coordinatesMode = 5;
        skyBox.material = skyMaterial;
        scene.lights[0].intensity = 0;
}

However, I’ve got two main issues:

  • Firstly: the BackgroundMaterial doesn’t seem to support blur. I’ve seen that the createDefaultSkybox scene helper uses a PBRMaterial to get around this using its microSurface, but I assume PBRMaterials are quite a bit less performant. Is there any way to have blur with the BackgroundMaterial?
  • Secondly: the first time a .env is loaded (so when it’s not already cached) there’s a flash of black on the model due to setting the HemisphericLight’s intensity to zero, as I want it to be lit by the environment. So my assumption is that the skybox material / lighting is taking a moment to load. I can “fix” this by putting the light intensity change in a timeout, however that means that when the .env is already in cache then the model is double-lit for a moment. I’m already using the onload of the CubeTexture, so what could be causing this issue?

Any ideas greatly appreciated - thanks!

Hey there

  1. Using microsurface is the way to go and it is quite fast actually
  2. You can avoid the flash by disabling parallel shader compilation but then it may result in a tiny jump in FPS
1 Like

A similar way to blur in BackgroundMaterial is to use a reflectionTexture and to rely on reflectionBlur parameter to control the blur level. This will only work if you rely on a .env files as your reflectionTexture similar to how PBR materials work.

  1. Unfortunately it seems that PBRMaterial doesn’t seem to support ground projection? It all seems to break when switching to it… :thinking:
  2. Disabling that while adding the environment does indeed fix it, thank you!

@sebavan do you mean reflectionTexture rather than CubeTexture? Would this be less performant / not work for the scene.environmentTexture?

I was trying to avoid needing to bundle BackgroundMaterial as well as PBRMaterial if I could just use e.g. PBRMaterial both with and without ground projection, but of course the size difference isn’t big enough to justify losing performance :sweat_smile: If it complicates things I can just use BackgroundMaterial when I need ground projection, PBRMaterial when I need .env blur.

Thank you both for your ideas!

No sorry, I mean the reflectionTexture property of the BackgroundMaterial. You can put your environmentTexture in.

And yes, you are correct Ground Projection is only available within a BackgroundMaterial.

1 Like