Hi @syuilo, this is an architectural limitation of FAST snapshot rendering rather than a bug in your code.
In FAST mode, the WebGPU bundle is recorded once and replayed every frame, so each draw call (including its instanceCount) is baked into the snapshot. updateMesh() can refresh per-mesh data already in the bundle (matrices, uniforms), but it can’t add or remove draws — so it can’t actually hide a mesh or an instance.
In your repro, the snapshot was recorded with sphere + sphere2 both visible, so instanceCount = 2 is locked in. Toggling isVisible on either one only affects what updateMesh writes into the buffer; the bundle still issues 2 instances and reads stale matrix data, which is why the instance keeps appearing.
To toggle visibility (or any other “structural” change) you need to re-record the snapshot via the disable/enable pair:
The updateMesh JSDoc is misleading on this point — it lists “visibility” as a supported property, which isn’t true in FAST mode. I’ll send a small PR to fix the doc comment.
In my use case, I need to toggle visibility frequently, and switching the SR each time incurs a performance cost.
So instead of changing the isVisible property, I plan to achieve this by changing the position to move the mesh far away or by changing the scale to shrink it to zero.
Follow-up: I discovered that if you start SR with the mesh scaling set to 0, the mesh will not be displayed even if you later reset the scaling to 1; therefore, offsetting the mesh to a distant position is an effective solution.