UpdateMatrixWorld Performance

So I’ve kinda been obsessing about my apps #1 performance issue, updateMatrixWorld.

I have matrixAutoUpdate set to false on all objects and only update as needed and still have performance issues.

One thing I’ve noticed is that matrixWorld updates get called on objects with visible = false.

This is important in my app as I control SkinnedMesh visibility by the objects distance from camera.

I added if( !this.visible ){ return false; } to Object3D.updateMatrixWorld and my apps performance increased by about 50% on my Ryzen 1600X/Geforce GTX 1060 desktop. On mobile I went from an avg fps of 30 to 55. Not exactly insignificant.

Since projectObject returns false on invisible objects, is it necessary to do all the extra matrix math? It seems not.

Also, this kinda makes me think that even though matrixAutoUpdate is set to false on my objects (both skinned and regular meshes), updateMatrixWorld is being called anyway. Is this to be expected?

Yes, because matrixAutoUpdate just regulates the update of the local matrix which represents the transformation of an object in model space. It’s still necessary to calculate the world matrix in order to ensure a correct world transformation. Otherwise you would miss transformations of superior objects which are at a higher level of the scene hierarchy.

BTW: Here is the link to the github discussion about possible performance improvements of .updateMatrixWorld().

1 Like

Otherwise you would miss transformations of superior objects which are at a higher level of the scene hierarchy.

According to the code, updateMatrixWorld goes down the hierarchy, not up. Which explains why my patch (of not updating world matrices of hidden objects) works well without any negative consequence.

I think WestLangley has mentioned fixing this (years ago), but nothing has been done yet. In the meantime, would it not be helpful for others to share the performance benefit of less unnecessary matrix math?

I have no problem patching three.js each release, but my performance issue was huge and now it is solved. Would hate for others to miss out (even though its only beneficial if you have hidden meshes).

Also, I wonder how many (if any) unnecessary bone matrix updates (on skinnedmeshes) are happening do to the downward traversal of object hierarchy in updateMatrixWorld.

That’s right and it is a conceptual issue in three.js (WestLangley mentioned this several times). The thing is, the correct world transformation of objects is ensured in the way WebGLRenderer utilizes .updateMatrixWorld(). In any event, I suggest you continue the discussion at github since it the better place for this topic.

Turns out three.js contributors do not care much about this particular performance issue. Hidden objects are considered “pollution” in three.js.

Just remember, if you have a more than a few dozen models (especially skinned meshes) hidden at any one time in your scene, follow WestLangley’s advice and copy/modify the updateMatrixWorld function in Object3D for a possible massive performance improvement.

4 Likes

Ow, if you came back from three.js github, you need a hug.

/me sends virtual hug

4 Likes