Under certain conditions, Snapshot Rendering stops working and can never be re-enabled. In some cases, it also causes rendering glitches such as materials being swapped with others.
There are probably multiple conditions that can cause SR to stop or trigger rendering glitches, and they have not been fully identified yet. However, I discovered one of them and created a repro.
This repro does not reproduce the material swapping issue, but it does reproduce the problem where SR stops working and can never be re-enabled again.
As described in the documentation, this repro calls disableSnapshotRendering when a canvas resize is detected, and then calls enableSnapshotRendering shortly afterward.
The scene contains a moving cube so that the SR state is easy to observe (its movement is reflected only when SR is disabled).
Additionally, enableSnapshotRendering is exported to window so that SR can also be re-enabled manually.
Now, if resizing is performed continuously, eventually SR remains disabled permanently, and even if enableSnapshotRendering is called again afterward, it never becomes active again.
Hi @syuilo, thanks for the detailed repro and the video — that made it very easy to confirm.
This is an engine bug. Internally, WebGPUSnapshotRendering temporarily switches _mode to STANDARD while it’s recording the bundle list (it’s restored to the user-requested mode at endFrame). If disableSnapshotRendering() lands while a recording is still in flight (very easy under continuous resizes), _mode stays at STANDARD, and the next enableSnapshotRendering() saves STANDARD as the “intended” mode — at which point the engine permanently falls back to STANDARD for the rest of the session. That matches what you observed: engine.snapshotRendering === true but engine.snapshotRenderingMode === 0.
The same race had been fixed for engine.snapshotRenderingReset() in #15633, but the protection was missing on the enabled setter.
Workaround until it lands: debounce your resize-driven disable/enable so they don’t fire during the snapshot recording window (a setTimeout(..., 100) or requestAnimationFrame debounce on the resize handler is usually enough).