Best practice during scene changing

Hi there,
my application starts with a very basic scene and then, when the user click on some mesh, the current scene is disposed and then assigned to a new one. The problem is that the new scene could be more heavy to load (depending on its dynamic content) and the result is that the user could be waiting fot the new scene loading some seconds and the current scene is freezed until the new one is not loaded (so the final effect is that is all stuck for some seconds).
Is there any best practice to avoid this behaviour?
I’d like to load the new scene in background and show a sort of splash screen during loading or directly inside the scene, and then when the new scene is ready for display, to change the scene.

At the moment i do something like that in my code:

scene.onPointerObservable.add(async function(pointerInfo){
    if (pointerInfo.type === BABYLON.PointerEventTypes.POINTERPICK){    
        // We try to pick an object   
        try{
            let pickResult = pointerInfo.pickInfo;
            let nome = pickResult.pickedMesh.name;
            if (nome.includes('Mag') || nome.includes('Tetto')){                      
                let numMag = pickResult.pickedMesh.metadata['datiMag']['Codice'];
                if(mag!==null){                                                
                    mag = null;
                }                                                               
                map = null;                    
                mag = new Magazzino(engine,0,0,numMag);                    
                scene.dispose();
                scene = null;
                scene = await mag.createMag();                    
            }
        }catch(evt){
            console.log("Click su nessuna mesh ->"+evt.toString());
        }            
    }
});

Thanks in advance

Hi @Mercurio

I’m not sure if this answers your question but to prevent the “freeze” problem I simply render a black frame on the old scene via a post proccess:

Effect.ShadersStore['dEffectFragmentShader'] = `void main(void) { gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); }`;
new PostProcess("dEffect", "dEffect", null,  null, 1, camera);
scene.render(); // render one black frame
// remove all renderloops
engine.stopRenderLoop();
scene.dispose();

// ... load assets and initialize new scene here ...

Maybe this helps

Thanks i’ll try.
And what about switching to the new (empty) scene and fill it with meshes after the is created? Is it possible? I was thinking to create a scene with a base set of meshes and then complete the scene step by step adding the remaining meshes. Is it possible or the scene has to be created with all the meshes at once?

you also have the loading screen,
which is basicly a HTML overlay on the canvas :slight_smile:

engine.displayLoadingUI();
engine.hideLoadingUI();

which can be customized quite simply

1 Like

Thank you @aWeirdo,
it could be the best solution. I only had to put a sleep after engine.displayLoadingUI(); because it was too fast and the scene stucks before the splashScreen was visualized.

    engine.displayLoadingUI();
    await new Promise(r => setTimeout(r, 100));
    // here comes the heavy part
    map = null;                    
    mag = new Magazzino(engine,0,0,numMag);                         
    scene.dispose();
    scene = null;                                              
    scene = await mag.createMag();
    // heavy loading finished
    engine.hideLoadingUI();