Upgrading from 3.1 alpha5 to 4.03, take 12, multiple issues

Coolio, thanks for looking. No the pg is working correctly but in my actual project I’m having the issue with my meshes disappearing, but the code I posted to freeze the meshes is the same as in my local project. I’ll dig into it tomorrow and report if I figure it out.

As an update to #4, no good news to report, unfortunately. I am however optimistic that upon solving this, I may be able to match performance of 3.1 alpha, as before it breaks, I can see a very noticeable performance gain, just on the smoothness of the card hover animations alone. That said, the issue is more confusing than I initially though:

I can’t reproduce the issue outside of my actual game scene. The freeze strategy does seem to be working in my other scenes, however, something in the actual game scene is breaking it. Also to expound on the original problem:

Calling $$initializeFreezeCallbacks(), while there is nothing going on, seems to be working. It’s only after doing something, whether hovering on a mesh or progressing the game, that it breaks, BUT: it’s not right after, sometimes I can hover on a few, sometimes I can hover on all of them, and then at some point while progressing the game state it breaks – I generally can reproduce it after triggering hover states on X=random number of meshes in my scene, but not always.

Either way, it leads me to believe it’s somehow related to creating instance meshes, and/or cloning meshes, as my hover states create new instanced meshes when triggered if no hover state exists for the card. – It almost seems like some operation is failing to complete in its entirety before babylon starts to render, causing an invalid render that it is unable to recover from? The strange part is that it doesn’t break the entire scene, only the rendering of the instanced meshes, and they still seem to be there, just no longer getting rendered.

edit: actually may have finally isolated

False alarm, did not isolate, still completely broken

@Deltakosh – I still can’t reproduce in pg, BUT, I found the source of where things are breaking and I’m not sure what to make of it. – It is in _activate method of instanced mesh. I can confirm if I replace the method with the following, trigger the bug so everything disappears, then set $$force_true on one of the disappeared meshes, call unfreezeActiveMeshes(), mesh shows up again.

Object.defineProperty(BABYLON.InstancedMesh.prototype, "_activate", {
  value: function(renderId, intermediateRendering) {
    if (this._currentLOD) {
        this._currentLOD._registerInstanceForRenderId(this, renderId);

        if(this.$$force_true) { return true }

        if (intermediateRendering) {
            if (!this._currentLOD._internalAbstractMeshDataInfo._isActiveIntermediate) {
                this._currentLOD._internalAbstractMeshDataInfo._onlyForInstancesIntermediate = true;
                return true;
            }
        } else {
            if (!this._currentLOD._internalAbstractMeshDataInfo._isActive) {
                this._currentLOD._internalAbstractMeshDataInfo._onlyForInstances = true;
                return true;
            }
        }
    }
    return false;
  }
})

Any ideas what could be causing this? Also what is “intermediate rendering”?

Intermediate rendering is used when rendering into render targets

Progress on #4 @Deltakosh – Remember this issue Performance optimization for activeMeshes / memory leak issue with freezeActiveMeshes

?

I noticed this while debugging today, I thought it had gone away but memory leaking was back when trying to freeze. I assumed these two issues were linked before, as they are executing same code path, but I am not so sure anymore, because I figured out that issue and removed the leak, but freezeActiveMeshes still makes my scene disappear. Here is playground reproducing the memory leak/calling _activate even though scene is frozen issue. (It is godrays, so I removed them for now and it’s fine).

https://playground.babylonjs.com/indexStable.html#W2ZA5S#12

The meshes disappearing is still an issue, that I cannot reproduce outside my main scene, but I’ve been now debugging this for over a week and a half, not to mention the other 2+ weeks of time I spent trying to upgrade previously, so I could really use some help even though I can’t repro via playground. I need ideas on things to try or understanding as to why a mesh would stop rendering even though it didn’t leave the activeMeshes array. Stepping through it alone is very difficult because there are so many different render related methods in different classes/places, so it’s hard to know if I’m even looking in the right place.

The things I’ve narrowed down (which may or may not be totally accurate) are:

It seems to be occurring in _activate method of instanced mesh.

    InstancedMesh.prototype._activate = function (renderId, intermediateRendering) {
        if (this._currentLOD) {
            this._currentLOD._registerInstanceForRenderId(this, renderId);
        }
        if (intermediateRendering) {
            if (!this._currentLOD._internalAbstractMeshDataInfo._isActiveIntermediate) {
                this._currentLOD._internalAbstractMeshDataInfo._onlyForInstancesIntermediate = true;
                return true;
            }
        }
        else {
            //I THINK THIS IS CULPRIT, it's already marked as active so it returns false, and never render again?
            if (!this._currentLOD._internalAbstractMeshDataInfo._isActive) {
                this._currentLOD._internalAbstractMeshDataInfo._onlyForInstances = true;
                return true;
            }
        }
        return false;
    };

Which if I’m understanding it correctly, is to prevent a mesh that is already in activeMeshes array, from being rendered again? But that also seems to be what is causing it not to render if so, as if I mark the instanced mesh mesh._currentLOD._internalAbstractMeshDataInfo._isActive=false, it will render again when I unfreeze active meshes. However: It will only render itself, not any children, even though they should be active as well.

I was able to “fix” the issue (make things worse, but at least get meshes to show up again), by overriding this in _evaluateActivemeshes

        if (mesh.isVisible && mesh.visibility > 0 && ((mesh.layerMask & this.activeCamera.layerMask) !== 0) && (mesh.alwaysSelectAsActiveMesh || mesh.isInFrustum(this._frustumPlanes))) {
            this._activeMeshes.push(mesh);
            this.activeCamera._activeMeshes.push(mesh);
            if (meshToRender !== mesh) {
                meshToRender._activate(this._renderId, false);
            }
            if (mesh._activate(this._renderId, false)) {
                if (!mesh.isAnInstance) {
                    meshToRender._internalAbstractMeshDataInfo._onlyForInstances = false;
                }
               //forcing to false causes meshes to show up again. But it created 200+ more draw calls in the process
                meshToRender._internalAbstractMeshDataInfo._isActive = false;
                // meshToRender._internalAbstractMeshDataInfo._isActive = true;
                this._activeMesh(mesh, meshToRender);
            }
            mesh._postActivate();
        }

Any new ideas based on this?

You must understand that I cannot help with partial code. This is why a repro in the plyaground is mandatory. If I was you, I would have spent all the time you mention to build a sample in the playground that demonstrates the issue. Not being able to repro means it is in your code.

Worse case, if you can share a running example somewhere that reference babylon.max.js, I could try to dig into your code. But honestly. put yourself in my shoes if I asked you to help me with just a few lines of code without a repro

1 Like

Why do you say this one is leaking? How do you see it?

Pinging @julien-moreau as he is the author of the godrays (FYI)

Haven’t read the code yet (on my phone) but I can see the sphere disappearing some few seconds when I:

  • rotate the camera enough so the sphere is culled
  • return to the previous rotation and target the sphere

Once I re-target the sphere, the sphere is not visible and reappears like 1s later.

Reading the post it looks like it is the issue you are looking for. Have you reproduced @Deltakosh? I’m on an iPhone 7+ now

1 Like

The leak and the disappearing issue I believe are two separate issues. You can see the leak by looking at the console log, I am summing the items in sourceMesh.visibleInstances array. Normally only 1 array is kept around, the most previous renderId. When godrays are in scene, the number of arrays grow with every render, a new array added each time. And will grow exponentially by the number of source meshes in the scene I believe. But I don’t think it’s causing the disappearing act. –

@julien-moreau that sounds similar, except I never see the meshes again after they’ve disappeared unless I manually force that internalAbstractMeshData.isActive value to false and unfreeze manually.

I think I finally have a reproduction of the disappearing issue however.

@Deltakosh

I believe this replicates what I am seeing. Two different ways to replicate, first is more realistic probably. (realistic as in I’m not actually adding meshes in the afterRender callback like in second playground).

In this one, click the center sphere fast enough/enough times, and it should cause all the meshes to disappear eventually.
https://playground.babylonjs.com/indexStable.html#W2ZA5S#29

In this one, I can trigger consistently by doing before render/after render. You should see the meshes appear initially, but disappear very quickly after.
https://playground.babylonjs.com/indexStable.html#W2ZA5S#22

I finally narrowed it down in my own app to be pure timing based which is why it was so hard to reproduce, and why nothing made sense. But basically once you trigger it, all the instanced meshes will disappear unless you force that value back to false so that it reevaluates

both PG does not load for me because of a missing _ function

Just hit run twice

You really don’t want to ease the process right? :slight_smile:

1 Like

The same without lodash…
https://playground.babylonjs.com/indexStable.html#W2ZA5S#30

Seriously importing a lib for a for loop :smiley:

lol, actually I mispoke, hit run once, I know it’s difficult :slight_smile: – It was for _.random, and I start all my playgrounds with it because it’s pretty much stuff I think should be built into js core (and some of it has with es6 but still not nearly enough) and I find myself missing it immediately without it. it’s not that I’m trying to make your life difficult :slight_smile:

Well…at least I have a repro…So I can start helping you

1 Like

I’m gonna clean your code because it is impossible to test with your code changing the prototype all the time.

Give me a few minutes to get a cleaner repro

1 Like

here we are: https://playground.babylonjs.com/index.html#W2ZA5S#33

And now I clearly see the bug! Will be fixed quickly

Stay tuned!

1 Like