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;
}
}
}
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()…
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