How to enable snapshot rendering with WebGPU?

Hi everyone, I’m new to Babylon.js and I need your help, please. In my scene, where I’ve already enabled WebGPU, I’m trying to activate snapshot rendering to improve the performance of my scene, like in this YouTube video : https://www.youtube.com/watch?v=gKTQ3VWn0cU. The performance when using WebGL is around 15fps.

However, even though I’m trying to follow the documentation or code examples in the playground, I’m still encountering a buffer issue and a WebGPU uncaptured error. Yet, my scene is mainly static with only a dynamic sky (sun movement, skybox with SkyMaterial, and shadow effects with ShadowGenerator).

Here’s the source code of my current scene:
"“use strict”;

import { to_move_sun } from “./src/sun”;
import { createSky } from “./src/sky”;
import { create_assets } from “./src/assets”;
import { xrController } from “./src/xrController”;
import { cloud_generation } from “./src/cloud”;

var canvas = document.getElementById(“renderCanvas”);
var loadingScreen = document.getElementById(“loadingScreen”);
var engine;

//Instruction de personnalisation de l’écran de chargement
var customLoadingScreen = {
displayLoadingUI: function() {
loadingScreen.style.display = “flex”;
canvas.style.display = “none”;
},
hideLoadingUI: function() {
loadingScreen.style.display = “none”;
canvas.style.display = “flex”;
}
};

//Fonction permettant de vérifier WebGPU
async function createSceneWithWebGPUorWebGL() {
let webGPUSupported = await BABYLON.WebGPUEngine.IsSupportedAsync;
if (webGPUSupported) {
console.log(“WebGPU is supported!”);
let engine = new BABYLON.WebGPUEngine(canvas);
await engine.initAsync();
return (engine);
} else {
console.log(“WebGPU not supported, using WebGL fallback.”);
return (new BABYLON.Engine(canvas, true));
}
}

//Fonction pour activer le mode de rendu instantané
const setSnapshotMode = (mode) => {
switch (mode) {
case “disabled”:
engine.snapshotRendering = false;
break;
case “standard”:
engine.snapshotRenderingMode = BABYLON.Constants.SNAPSHOTRENDERING_STANDARD;
engine.snapshotRendering = true;
break;
case “fast”:
engine.snapshotRenderingMode = BABYLON.Constants.SNAPSHOTRENDERING_FAST;
engine.snapshotRendering = true;
break;
}
};

//Fonction de création de la scene 3D
var createScene = async function () {
let size = 310.0;
var scene = new BABYLON.Scene(engine);

// Crée la lumière directionnelle (soleil)
var light = new BABYLON.DirectionalLight(“light”, new BABYLON.Vector3(0, -1, 0), scene);
light.diffuse = new BABYLON.Color3(1, 0.9, 0.8);

// Crée la lumière hémisphérique
const hemisphericLight = new BABYLON.HemisphericLight(“hemisphericLight”, new BABYLON.Vector3(0, 1, 0), scene);
hemisphericLight.intensity = 0.1;
hemisphericLight.diffuse = new BABYLON.Color3(0.5, 0.5, 0.5);
hemisphericLight.specular = new BABYLON.Color3(0, 0, 0);
hemisphericLight.groundColor = new BABYLON.Color3(0.1, 0.1, 0.1);

// Création de la caméra orbitale
var camera = new BABYLON.ArcRotateCamera(“Camera”, 0, Math.PI/2, 50, new BABYLON.Vector3(0, 10, 0), scene);
camera.attachControl(canvas, true);

// Crée le ciel
var sky = BABYLON.MeshBuilder.CreateBox(“skyDay”, { size: size }, scene);
sky.position.y += size / 2;
sky.material = createSky(scene);
to_move_sun(light, scene, sky.material, sky);

// Active les collisions
scene.gravity = new BABYLON.Vector3(0, -1, 0);
scene.collisionsEnabled = true;
sky.checkCollisions = true;

// Configuration VR avec WebXR
/*const xrHelper = await BABYLON.WebXRDefaultExperience.CreateAsync(scene, {
floorMeshes: [sky]
});
// Accède à la caméra WebXR
const xrCamera = xrHelper.baseExperience.camera;
xrController(xrHelper, xrCamera);

//Création des assets de la scene 3D*/
create_assets(light, scene, camera);

return new Promise((resolve) => {
scene.executeWhenReady(() => {
//setSnapshotMode(“fast”);

    resolve(scene);
});

});
};

window.addEventListener(“DOMContentLoaded”, async function () {
engine = await createSceneWithWebGPUorWebGL();
engine.loadingScreen = customLoadingScreen;
engine.displayLoadingUI();

var scene = await createScene();

scene.executeWhenReady(function() {
engine.hideLoadingUI();

  engine.runRenderLoop(function () {
      scene.render();
  });

  window.addEventListener("resize", function () {
      engine.resize();
  });

  scene.debugLayer.show();

});
});"

What should I do? Thank you.

Welcome to the community !!!

Could you repro the issue in the playground ? it makes it way easier for us to test

Thank you for your reply. Yes, I could do it, but after some research, I realized that WebGPU is not yet well supported by WebXR, since I’ll be testing my scene with a Meta Quest 2. So I’ll stick with WebGL2 instead.

1 Like

However, I would like to improve the performance of my scene (15 fps to 60 fps), which is why I had considered using WebGPU. My problem is that I’m using rather complex and bulky graphic assets, so WebGL has rendering difficulties. In your opinion, how can I optimize my scene if I can no longer reduce the quality of graphics assets on Blender? Thank you for your help.

This is hard to tell without specifics of your use case but this is full of tips that could help Babylon.js docs

Okay, thanks :blush:, I’ll see what I can do with it. I’ll let you know when I hear something.