THREE.StaticMesh - Less memory, render faster

This is a lightweight scene object class saving memory and giving a better performance for large scenes. It makes several optimizations without requiring core modifications.

You can archive up to 50% better performance regarding computations and culling compared to meshes with matrixAutoUpdate set to false. The benefit increases by the number of meshes and complexity in the scene. This plugin runs out of box without core modifications.

Transforming a static mesh like a regular object and using compound culling:


This isn’t about instancing or accelerating the GPU side, it is about reducing calculations, saving memory and improving culling.

When do i benefit?

Generally you save a lot computations and memory, you get the most benefit in a large scene with several thousand objects, with many being outside/beyond the camera frustum far plane. With all objects visible on screen you can still gain several FPS, around 5-10%.

Saving memory

The THREE.Object3D class creates a lot objects in it’s constructor, some you probably not even require such as an individual up vector or layers object, many matrices and also 2 callbacks are created to synchronize euler rotation with the quaternion property what is more of a legacy issue.

StaticMesh is reduced to a few primitives and the worldMatrix, children array only if necessary. For a large scene this has a huge impact. Especially if you have multiple maps/levels you already hold in memory.

Better performance

Culling is improved with less computations and compound culling, this means if the static mesh with it’s children isn’t visible, the children are discarded already. This is specifically useful for assets consisting of sub-meshes, for example a tree with a separate trunk and crown mesh and to group some meshes such as a building with it’s interiors.

Moving static meshes

To move or rotate a static mesh or one of it’s children, you can use them like regular objects or restore the state to the source and apply the hierarchy then again (recommended for multiple changes)

staticMesh.position.x = 10;
staticMesh.rotateY( THREE.Math.DEG2RAD * 90 );

Restore and save:

// Restore hierarchy transformation to source, apply manipulations then save it back to the static mesh

const source = staticMesh.restore();

source.position.x += 100;;

To create a static mesh. Avoid using the original mesh if you want to transform any of the static meshes created from it again (use a clone if required), the source is used to restore and update the transformation.

const staticMesh = regularMesh.toStatic();

If you want to really crank it up, checkout the IndexedVolume component i introduced there, it will be available soon with auto-instancing and more.


Is it also possible to move the static mesh by modifying/replacing the model matrix?

Currently no, but i’ll separate the bounding sphere cache update then you only need to update this, children need the original mesh for hierarchy to get updated though.

I’ve made an update, a static mesh can be treated like a regular mesh now.

If the static mesh has no children you can just directly use it’s world matrix to transform it, that’s the most efficient case.

The position, rotation, quaternion and scale properties are now available singletons that restore the state when accessing and save it when writing to them automatically. This is for easier use of less frequent transformations like a opening or closing door. But restoring the state once and making all manipulations is best practice to only update the hierarchy and matrices once.

The sphere shows the bounding sphere for the static mesh.

1 Like

Hi @Fyrestar, the repo link is broken, could you please update it?

This is also a problem in the Collection of examples from
The extended examples are only links.
THREE.StaticMesh - @author Fyrestar

Sorry for late update on this, moved it now.

1 Like

This looks great. Before I purchase it, does it also work if the objects under the static hierarchy have different materials?

Ah, I see. Then it is not for our needs, as we have a lot of very small meshes that are on-screen, so culling is not the issue. Batch reduction is the main target.

I see, i made something in regard of mesh packing as well, but didn’t released here yet. Since it’s done since years i probably should :grinning_face_with_smiling_eyes: