Unfortunately, I am unable to reproduce the issue in the Playground due to the complexity of the project. While I acknowledge that the problem likely originates from my code, I would still appreciate your professional insights and recommendations.
In my project, there are two distinct scenarios: one is a relatively intricate scenario referred to as preScene, and the other is a simpler scenario named nextScene. I implemented fadeOut and fadeIn transitions between these two scenarios using post-processing techniques.
However, during continuous switching, the FPS of the preScene progressively decreased. Upon investigation, I examined the draw calls of the preScene and confirmed that they did not increase. Additionally, it is worth noting that the preScene utilizes glowLayer, UV animation, numerous material plugins, and Observers.
The onExit method is called whenever a scene exits, and the OnEnter method is called when entering another scene
This is the method of fadeOut:
this.scenes.set(SCENE_TYPE.PRE_SCENE, new PreScene());
this.scenes.set(SCENE_TYPE.NEXT_SCENE, new NextScene());
private setupTransitionEffect(): void {
Effect.ShadersStore["fadeFragmentShader"] = `
precision highp float;
varying vec2 vUV;
uniform sampler2D sceneSampler;
uniform sampler2D textureSampler;
uniform float fadeLevel;
void main(void) {
vec4 sceneColor = texture2D(sceneSampler, vUV);
vec4 baseColor = texture2D(textureSampler, vUV);
gl_FragColor = mix(sceneColor, baseColor, fadeLevel);
}
`;
}
public async transitionToScene(targetSceneType: SCENE_TYPE): Promise<void> {
return new Promise(async (resolve) => {
const targetScene = this.scenes.get(targetSceneType);
if (!targetScene) {
throw new Error(`Target scene ${targetSceneType} not found`);
}
if (this.activeScene === targetScene) {
console.warn(`Already in scene ${targetSceneType}`);
return;
}
if (this.activeScene) {
await this.applyFadeTransition(
this.activeScene.scene,
targetScene.scene
);
this.activeScene.onExit();
}
this.activeScene = targetScene;
targetScene.onEnter();
Inspector.Hide();
Inspector.Show(this.activeScene.scene, {
embedMode: true,
});
resolve();
});
}
private async applyFadeTransition(
fromScene: Scene,
toScene: Scene,
duration: number = 1000
): Promise<void> {
return new Promise((resolve) => {
const startTime = Date.now();
const postProcess = new PassPostProcess(
"currentSceneRTT",
1,
fromScene.activeCamera
);
const fadePostProcess = new PostProcess(
"targetSceneRTT",
"fade",
["fadeLevel"],
["sceneSampler"],
1.0,
toScene.activeCamera
);
toScene.meshes.forEach((mesh) => {
mesh.setEnabled(false);
});
toScene.autoClear = false;
fadePostProcess.onApply = (effect) => {
effect.setTextureFromPostProcess("sceneSampler", postProcess);
effect.setFloat("fadeLevel", this.fadeLevel);
};
const renderLoop = () => {
const elapsed = Date.now() - startTime;
this.fadeLevel = Math.min(elapsed / duration, 1.0);
if (this.fadeLevel < 1.0) {
fromScene.render();
}
toScene.render();
if (this.fadeLevel >= 1.0) {
postProcess.dispose();
fadePostProcess.dispose();
toScene.autoClear = true;
resolve();
}
};
this.engine.runRenderLoop(renderLoop);
});
}
...
// change to the nextScene:
transitionToScene(nextScene)
onExit:
this.scene.meshes.forEach((mesh) => mesh.setEnabled(false));
this.scene.particleSystems.forEach((system) => system.stop());
this.scene.materials.forEach((material) => material.freeze());
onEnter:
this.scene.meshes.forEach((mesh) => mesh.setEnabled(true));
this.scene.particleSystems.forEach((system) => system.start());
this.scene.materials.forEach((material) => material.unfreeze());
What else can I do in the applyFadeTransition, onEnter,onExit methods to keep the FPS at a high level?
This FadeOut effect is really needed,looking forward to your suggestions
It was inspired by this PG