SPS lag during starting of movement

Ok here is something that I just can’t seem to figure out, no matter what I try.
I have a SPS with 800 “face particles” and another 800 “sub particles”.
When I click on the menu, the camera and light rotates around the cube, and the SOME of the walls cubes extend.

But there is always slight delay just as the animation starts, and I have done almost all optimizations that I know about, such as setting unused ones to alive=false, disabling all sps features, freezing meshes etc.

I am using the registerBeforeRender loop to do the animation, is there somewhere here a problem that causes setParticle to be called too many times per frame?

scene.registerBeforeRender(() => {
if (DoWallAnimation){
SPS.setParticles();
}
});

My update function has been reduced a lot, but still the exact same performance issue:

var updateParticle = function§ {

if (p.isAnimating === true && p.idx < TotalFaceBlocks){

p.position[p.activeAxis] += p.changeRatio;
p.updateTracker++;
if (p.linkedMenuBlock != null){
  p.linkedMenuBlock.position[p.activeAxis] = p.position[p.activeAxis];
  p.linkedMenuBlock.position[p.activeAxis] += p.direction;
}

if (p.updateTracker === p.countPerUpdate){
  p.updateTracker = 0;

  if (p.retracting){
    p.phaseCounter--;

    // Reached end of retracting cycle
    if (p.phaseCounter === 0 && p.retracting === true){
      p.isAnimating = false;
      DoWallAnimation = false

  } else {
    p.phaseCounter++;

    // Reached end of extending cycle
    if (p.phaseCounter === p.numberOfPhases){
      p.changeRatio = p.changeRatio * -1;
      p.retracting = true;
    }
  }
}

}
}

Pinging @jerome

When you call sps.buildMesh() many of intermediate arrays used when adding particles in the previous
steps and when constructing the global final geometry are freed and probably cleaned by the garbage collector at this moment.
This operation happens only once and is useful to keep only the necessary amount of required memory, especially when dealing with high number of vertices. Then nothing is allocated nor released any longer until your call buildMesh() again in the case of an expandable SPS for instance. This helps to keep the SPS performance constant then.

Unfortunately we can’t predict when and how much the GC will impact the main loop (if it’s the culprit).

Maybe could you build the SPS a moment before you need to start the rendering loop ?

From what I see on the performance analyzer (chrome), I don’t notice a large GC happening.
In the screenshot I posted, you can see that setParticle is called many times within the first frame, and many of the setParticle calls seem to be slower than usual.
After this initial lagging, everything goes smoothly, and there is only one setParticle per frame, which indicates to me its not my function calls doing this.
I took extra care not to have any local variables in my update function also.

I tested a little bit more now, its definitively something happening on the first setParticle after some time
I did the buildMesh again right before the first call and the results are still the same.
Strange thou, on the performance tool it shows multiple calls to setParticle, but on the debugger it only stops once? I might not be understanding those graphs correctly.

Ok nevermind I solved it by just having NOT having a conditional in registerBeforeRender function, and just having it spam setParticle even if nothing is happening, and then using the conditional within the update function.
It removed all the lag from the start of the animation this way… Question still remains, why…!?

I read back the code of setParticles() and it’s strictly the same whatever it’s called for the first time or the next ones. Nothing is created nor allocated on the first call, no extra computation, etc.
So no idea why you get this behaviour about setParticles()…

A repro could definitely be useful (as usual)

1 Like

I think I figured it out what causes this lag.
I set some properties to particles just before I want a animation, so it looks something like this:

function applyAnimationProperties(particle) {
particle.numberOfPhases = 6;
}

This causes a fairly large delay as seen below.

BUT NOW, if we declare this variable before we call the function, like this pseudo code:

function initializeParticles() {
foreach particle particle.numberOfPhases =0;
}

Lag gone!

Might be helpful to include this in the documentation that updating the particle properties without initialization causes quite a slow-down initially.

Nevermind that wasn’t it…

Maybe is it because this modify the prototype of the SolidParticle object afterwards, so recompilation and reoptimization.
Perhaps can you use the property props of the solid particle so you can link your own objects/values to the particle without modifying its prototype :
https://doc.babylonjs.com/api/classes/babylon.solidparticle#props

particle.props = {myProp1: val1, myProp2: val2};