Visually hidden instances still present in the "frozen" scene

Hi! I have an issue. When I create/remove objects sometimes my pooled(visually hidden) objects appear on the screen. And it only disappeared if I manually call scene.unfreezeActiveMeshes();.

There are bushes around the yellow arrow:

After scene.unfreezeActiveMeshes(); bushes disappeared:

But it appears again after some time…

My frozen Scene constructor:

this.performancePriority = BABYLON.ScenePerformancePriority.Aggressive;
this.skipFrustumClipping = true;
this.autoClearDepthAndStencil = false;

When I change object’s transform or create a new instance, I call this method:

forceModelToUpdate(model: BABYLON.AbstractMesh): void {
    scene.renderingManager.maintainStateBetweenFrames = false;
    if (model.isAnInstance) {
      (model as BABYLON.InstancedMesh).sourceMesh._unFreeze();

This is how I put the object in my pool (to make it “visually” hidden):

model.position.y = 10000; // <--- this way

This is how I create new instance:

modelInstance = (model as BABYLON.Mesh).createInstance(id);
scene.render(false, true);

I think I just doing something wrong with mesh’s freeze / unfree or I forgot about some buffers clearing… IDK.

I have questions:

  • Do I use freeze/unFreeze right?
  • How to properly add a new instance when I apply freezing to scene with aggressive mode?
  • How to visually hide objects? Right now I use model.position.y = 10000; but maybe there is more suitable way.

Please, help me to investigate and fix the issue.

I found that drawElementsInstanced been called with different count:

Before scene.unfreeze

After scene.unfreeze

115 vs 58.

In scene.meshes:

16:46:58.933 __world.sceneEntity.scene.meshes.filter(m=>'SM_Env_Bushes_03')).length
16:46:58.950 58

this is probably because the root bush of the instances for instance is going out of screen.

A repro would help here.

They are all marked as alwaysSelectedAsActive

Another interesting thing:

visibleInstances contains one element two times for each instance and the mesh itself.

Is it OK or it is an issue?


Found the issue:

scene.render(false, true);

It gives double render into visibleInstances

It will be really hard to fix without a repro. Is that possible ?

Seems like I found the root of problem. I called

scene.render(false, true);

inside Promise callback, so it doesn’t guarantee the order of execution. So I could have two renders for one frame.

There is more suitable way to update scene when add a new instance:

//call it inside onBeforeRender event
activateNewInstance(modelInstance: BABYLON.AbstractMesh) {
    this._activeMeshesFrozen = false;
    this.forceModelToUpdate(modelInstance); // modeInstance._unFreeze() + modelInstance.sourceMesh._unFreeze();

// copy-pasted from freezeActiveMeshes but without evaluation, because Babylon itself does it for us in the render loop.
    this.onAfterRenderObservable.addOnce(() => {
      this._activeMeshesFrozen = true;
      this._activeMeshesFrozenButKeepClipping = false;
      this._skipEvaluateActiveMeshesCompletely = true;