Jump to content

Performance thoughts


Recommended Posts

Hi there,


I've got some performance issues on the javascript (CPU) side. Chrome profiler gives me this :




It seems that as soon as I get some decent number of objects on my scene, the bounding box computation is dominating the costs.


But since my scene is mostly static, is there a way I can get things updated manually (boundingBoxes and world matrices), so when nothing moves I can get a decent framerate ?


Also, it seems StandardMaterial.isReady is pretty significant in the CPU business. Any thoughts on how to cut it ? (I do exactly know when a material needs to be ready-tested) 


Link to comment
Share on other sites

The boundingBox should not be updated if your object is not moving. There is a cache system preventing updates.

Could you check why boundingBox is updated?


For your isReady question there are two ways:

- mat.checkReadyOnEveryCall: you can set this value to true if you want to check the status of your material just once per frame (could be a good option here)

- mat.checkReadyOnlyOnce: Once this is set, the material is tested just once! Beware, because materials are shared so if two objects use the StandardMaterial they can have differents options activated and if you do not check is ready for each object only the options of the first one will be taken in account.

Link to comment
Share on other sites

It seems that this.isSynchronizedWithParent always returns false whenever a mesh has a parent.

    BABYLON.Node.prototype.isSynchronizedWithParent = function() {        return this.parent ? !this.parent._currentRenderId === this._currentRenderId : true;    };

Shouldn't it be

this.parent._currentRenderId === this._currentRenderId



I also fail to understand why this would work, if the parent is updated before its children in a render pass, this.parent._currentRenderId will be higher than this._currentRenderId, right ?

Link to comment
Share on other sites

You're right it should be:

BABYLON.Node.prototype.isSynchronizedWithParent = function() {        return this.parent ? this.parent._currentRenderId === this._currentRenderId : true;    };

I'll fix it

if the parent is updated before its children in a render pass, this.parent._currentRenderId will be higher than this._currentRenderId and thus the children should be updated

Link to comment
Share on other sites

Yes sure but, in computeWorldMatrix, which is called every frame for every mesh, you have this chunk of code :


        if (!force && (this._currentRenderId == this._scene.getRenderId() || this.isSynchronized(true))) {            this._currentRenderId = this._scene.getRenderId();            return this._worldMatrix;        }

This implies, even if the parent hasn't moved, its _currentRenderId will always match the current frame's render id, so the children will be forced to recompute their worldMatrix/bounding box even if they haven't moved either (since this.isSynchronized will be false if they are updated after their parent). Am I right on this, or am I missing something ?

Link to comment
Share on other sites

I suggest this patch :


in BABYLON.Mesh.computeWorldMatrix :

        if (!force && (this._currentRenderId == this._scene.getRenderId() || this.isSynchronized(true))) {            return this._worldMatrix;        }        this._currentRenderId = this._scene.getRenderId();

And in BABYLON.Node.isSynchronizedWithParent : 

        return this.parent ? this.parent._currentRenderId <= this._currentRenderId : true;
Link to comment
Share on other sites

I may be wrong but I still see a problem with your patch.


Say we update the parent on frame 100, parent._currentRenderId will be set to 100.

Then we move the child on frame 200, this._currentRenderId will be set to 200.


Now, in all the subsequent render frames, BABYLON.Node.isSynchronizedWithParent will return false, and the child will be force updated in every frame, setting its _currentRenderId to 201, 202, 203, etc..



That was why I suggested :

return this.parent ? this.parent._currentRenderId <= this._currentRenderId : true;

- If the parent _currentRenderId is strictly greater than its children, then the children MUST be updated to move along with the parent.


- But if the parent _currentRenderId is lower the child's _currentRenderId, it just means that the parent has not moved for a certain amount of frames, the synchronization is fine

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...