WebGPU Snapshot Rendering
Snapshot rendering is a new rendering mode available starting with Babylon.js v5.0. Only WebGPU supports it: activating this mode in WebGL has no effect.
The snapshot rendering (SR) feature improves performances in some specific scenarios described below.
It works by recording the draw calls during one frame and by replaying this recording for all subsequent frames. So, the scene should be mostly static for this mode to work as expected. Note that this mode can be enabled or disabled whenever you want. So, if at some point something must change in the scene that is not supported by SR, you can disable the mode, apply the changes and re-enable SR afterwards.
The perf improvements can be quite large, especially when using the fast SR mode (see below for explanations regarding the SR modes). Here are some figures collected with the first PG listed in the Examples section:
|SR disabled||Standard mode||Fast mode|
Enabling snapshot rendering mode
The snapshot rendering mode is enabled by setting:
engine.snapshotRendering = true;
When doing this, the next frame will be recorded (and of course also displayed as usual!) and the recorded snapshot will be replayed in all subsequent frames until you either disable the mode or use
engine.snapshotRenderingReset(). If calling the latter, a new snapshot will be created the next frame that will replace the current snapshot.
engine.snapshotRenderingReset() is the way to apply changes not supported by the SR current mode (see available modes in the next section): apply your changes and call this function. That will destroy the current snapshot and instruct the system to create a new snapshot by recording the draw calls of the next frame (which will contain your changes). In effect, it is the same than doing
engine.snapshotRendering = false; engine.snapshotRendering = true;. The first assignment will stop/destroy the current snapshot and the second will ask the system to record the draw calls when rendering the next frame. Of course, for this to work, your changes should be in effect right at the next frame! If, for eg., you import a new mesh, it will probably take more than a frame to be added to the scene. So, you should make sure to call
engine.snapshotRenderingReset() once you know the next frame will render the scene with the new state.
Standard and Fast modes
There are two different modes available when SR is enabled:
- Standard mode (
Constants.SNAPSHOTRENDERING_STANDARD). In this mode, the uniform buffers are still updated so some kind of
dynamicityare still supported: you can update some parameters of a material, for eg, and it will work.
- Fast mode (
Constants.SNAPSHOTRENDERING_FAST). In this mode, only the scene uniform buffer is updated automatically by the system (meaning moving the camera works as expected). You can still update the uniform buffers of meshes "by hand", so moving/rotating meshes are also supported (see examples below).
Whatever the mode, as the draw calls of a given frame are recorded and replayed for all subsequent frames, adding or removing meshes won't work. You will need to disable the SR mode if you want to add/remove meshes and re-enable it afterwards.
Given how SR works, you will probably always want to set
alwaysSelectAsActiveMesh = true to all your meshes because if this property is
false (default value) and the mesh is not displayed when recording the snapshot, no draw calls will be recorded for this mesh, meaning that if you move the camera later on that should make this mesh visible, it still won't be visible.
Statistics in the Inspector
When to use
It's hard to list everything that will work/won't work depending on the mode, so the easiest way to use this new feature is to enable it and see if everything works as expected once enabled (try first fast mode, then stardard mode). As explained above, if you need to update something at some point in time and the current SR mode can't handle it, you can always disable SR, apply the changes and re-enable SR.
eCommerce sites may greatly benefit from this feature as the scene is normally quite small with everything visible on screen. Also, there's generally not a lot dynamicity and when something needs to be updated it's a "one shot" update, so either calling
snapshotRenderingReset or disabling temporarily the feature should work.
In fast mode, animating light / updating the bias would not work for the reasons explained above. When you update:
- the bias, the PG calls
engine.snapshotRenderingReset()so that the bias is taken into account for the next frame and the snapshot is recreated at that time too
- the Animate light checkbox, the PG switches to standard SR mode until you uncheck the box. It happens moving the light does work in standard SR mode: had it not work, we would have switched to SR disabled mode instead.
Note also that in the fast SR mode you must handle the update of the position of the sky yourselves because the uniform buffers are not updated by the system (except for the scene buffer). It is done like this:
const world = sky.computeWorldMatrix();sky.getMeshUniformBuffer().bindToEffect(sky.material.getEffect(), "Mesh");sky.transferToEffect(world);
This PG is using the standard SR mode because the fast mode does not work (try to set the fast mode and see for yourself). Also, when a resize kicks in, we need to disable the SR mode and re-enable it only when the glow layer had time to recreate its internal texture with the new size. That's why we use a
setTimeout(..., 1) to re-enable the SR mode.