Changing cubemap settings on the fly (via code) not producing desired results

I have the current setup:

  • 1 scene
  • Inside the scene, there are multiple “environments”/“rooms” with an EnvSettings script attached to them. This lets us change things like the skybox texture, mip levels, lightmapper bake settings and more.

What we expect this to do:

  • EnvSettings.apply method updates all rendering/lighting settings as it should

What is currently happening:

  • EnvSettings.apply changes are being ignored, and the ones from the editor settings are being favored/applied instead. The biggest difference lies with the cubemap mip: if it was meant to be set to 2, it would instead look like the setting on 3 or 4.

Note:

  • All cubemaps are prefiltered + preloaded

Here’s a snippet of how the EnvSettings script looks like:

var EnvSettings = pc.createScript('envSettings');

// Cubemap
EnvSettings.attributes.add('ambientLightColor', { type: 'rgb', title: 'Ambient Color' });
EnvSettings.attributes.add('skybox', { type: 'asset', assetType: 'cubemap', title: 'Cubemap' });
EnvSettings.attributes.add('skyboxIntensity', { type: 'number', title: 'Cubemap Intensity' });
EnvSettings.attributes.add('skyboxMip', { type: 'number', title: 'Cubemap Mip' });
EnvSettings.attributes.add('exposure', { type: 'number', title: 'Exposure' });
EnvSettings.attributes.add('fogDensity', { type: 'number', title: 'Fog Density' });
EnvSettings.attributes.add('fogColor', { type: 'rgb', title: 'Fog Color' });

// Lightmapper
EnvSettings.attributes.add('lightmapFilterEnabled', { type: 'boolean', title: 'Lightmap Filter' });
EnvSettings.attributes.add('lightmapFilterSmoothness', { type: 'number', title: 'Lightmap Filter Smoothness' });
EnvSettings.attributes.add('ambientBake', { type: 'boolean', title: 'Ambient Bake' });
EnvSettings.attributes.add('ambientBakeNumSamples', { type: 'number', title: 'Ambient Bake Samples' });

EnvSettings.prototype.initialize = function () {
    this.skybox.loadFaces = true;
};

EnvSettings.prototype.apply = function () {
    const app = this.app;
    const scene = app.scene;

    const applyOnLoad = function () {
        scene.setSkybox(this.skybox.resources);
        scene.envAtlas = pc.EnvLighting.generatePrefilteredAtlas(this.skybox.resources.slice(1));
        scene.skyboxIntensity = this.skyboxIntensity;
        scene.skyboxMip = 1;
        scene.ambientLight.set(this.ambientLightColor.r, this.ambientLightColor.g, this.ambientLightColor.b, 1);
        scene.exposure = this.exposure;
        scene.fogColor.set(this.fogColor.r, this.fogColor.g, this.fogColor.b, 1);
        scene.fogDensity = this.fogDensity;
        scene.lightmapFilterEnabled = this.lightmapFilterEnabled;
        scene.lightmapFilterSmoothness = this.lightmapFilterSmoothness;
        scene.ambientBake = this.ambientBake;
        scene.ambientBakeNumSamples = this.ambientBakeNumSamples;
        app.lightmapper.bake();
    }.bind(this);

    if (this.skybox.loaded) {
        applyOnLoad();
    }
    else {
        // Triggers when the skybox asset finishes loading
        this.skybox.on("load", applyOnLoad);
        app.assets.load(this.skybox);
    }

};

Is there anything I’m doing wrong here?

Hi @timrodz,

I think that’s due to a known issue with loading a cubemap asset. You need to set a flag to true just prior loading the cubemap asset.

Check this post: [SOLVED] Skymap is blurry after setting via script - #3 by slimbuck

1 Like

Thanks for the help. I already set loadFaces to true when the script initializes, but not in the order described in that forum post. If I try it as

EnvSettings.prototype.apply = function () {
    const app = this.app;
    const scene = app.scene;

    const onAssetReady = function(skyboxAsset) {
        scene.setSkybox(skyboxAsset.resources);
        scene.envAtlas = pc.EnvLighting.generatePrefilteredAtlas(skyboxAsset.resources.slice(1));

        // Number from 1-5
        scene.skyboxMip = this.skyboxMip;
    }.bind(this);

    this.skybox.ready(onAssetReady);
    this.skybox.loadFaces = true;
    app.assets.load(this.skybox);
};

I still get the same results - the skybox changes to the one desired, but values like the mip still do not change as desired.

1 Like

@slimbuck any idea what may be wrong?

Hi @timrodz,

Might it be related to this weird thing? engine/scene.js at main · playcanvas/engine · GitHub.

It it a strange, long-standing, (presumably) unintentional bug in the engine, but unfortunately we couldn’t change the behaviour because it might break existing projects.

1 Like

Hey @slimbuck, that’s very interesting!

Do you suggest we simply skip mip level 2 for now? :slight_smile:

Not sure what to suggest @timrodz.