Fair ask, but registerScene / unregisterScene are not the pair you think they are:
• unregisterScene(scene) only detaches the scene from its surface’s render list. It’s a “stop drawing this” switch — nothing is rebuilt, nothing is released.
• registerScene / registerSceneWithShadowSupport do the one-time heavy lift: drain the deferred builders, compile the shader permutations, allocate the bind groups, sort renderables, build the frame graph. Once a scene is built, calling them again is essentially just “re-attach”: the build does not run a second time.
That’s very much on purpose in Lite: anything that can be resolved once at build time is baked so the render loop stays allocation-free. The trade-off is that part of the topology is frozen at that point. Your ground’s renderable captured, at build time, both the shadow bind group (pointing at that generator’s map) and the shader permutation, including the index of the shadow-casting light in scene.lights . Remove the spot and add a new one and none of that is updated: the receiver keeps sampling the old generator and looks at the wrong light slot: hence the broken result. Re-registering can’t repair it, because the build step is a no-op once the scene has been built.
(The Destroyed texture (1x1 RGBA8Unorm) used in a submit from your first post is a different path: a refcounted material texture released on mesh removal. I’m tracking that one separately.)
We already have a few ones fully dynamic though:
• Light properties: position, direction, intensity, color, angle… The lights UBO is refreshed whenever one of them changes, and the shadow generator follows its light.
• Adding/removing plain (non shadow-casting) lights: the light count is a uniform (up to MAX_LIGHTS , 16 by default, raisable via setMaxLights ).
• The caster list: setShadowTaskCasterMeshes(sg, [...]) can be called at any time.
So in your playground, the cheapest fix is to keep the same spot + generator and just move it:
spot.position.set(0, 4, 0);
spot.direction.set(0, -1, 0);
No remove/add, no re-register, and the shadow map follows.
If you really need a different shadow topology (new generator, different receivers), the supported route today is a scene swap: build a fresh SceneContext on the same engine, addToScene your entities into it, then disposeScene(old) . Mesh GPU buffers are refcounted per owning scene, so as long as the new scene has claimed them first they aren’t freed. Same pattern as Transitioning Scenes in Lite.
That said, your underlying point stands: “rebuild this scene in place” is a genuinely missing primitive, and the current failure mode (a destroyed texture instead of a clear error) is not acceptable. I’d rather add an explicit rebuild/invalidate step than turn unregisterScene into a full teardown. I’ll work on a PR 