Many objects caused low fps, can we optimize it without losing control over individual Mesh

In my three.js project. I need to render thousands of individual meshes(e.g. 10k or more). From some sources, I realized that rendering a large number of objects(THREE.Mesh) increases draw calls and therefore, drops FPS and can get Violation message like ‘requestAnimationFrame’ handler took ms. And they provide a solution with InstanceMesh.
I am not sure, using InstanceMesh aligns with my requirements.

My requirements:

  1. I need a plane and grid helper on it on my scene.
  2. When double click on the plane, I need to generate a Mesh, one that I select from a list. I should have Cube, Cone and Cylinder.
  3. When double click on a face of a Mesh, it should generate another selected Mesh on the clicked face of the Mesh.
  4. I should also be able to select a Mesh and change color and position of individual Mesh, not all the Mesh.
  5. I should also be able to rotate/flip using quaternion each mesh individually.
  6. And most importantly, I should be able to generate thousands of objects like this. Having control over each one of the Mesh.
  7. When we have a large number of objects, renderer should be able to render those objects and I dont want frame drop. Normally it is 60FPS.

When you need thousands of objects with individual transforms, colors, and interactivity, normal Mesh instances become costly because each one adds a new draw call. You should consider InstancedMesh, which lets you render many copies of the same geometry/material in a single draw call. Here’s how to meet your requirements:

  1. Separate InstancedMesh per geometry type: One for cubes, one for cones, and one for cylinders.
  2. Per-instance transform and color: Update each instance’s transform (instanceMatrix) for individual positioning/rotation, and use instanceColor to apply per-instance colors.
  3. Raycasting/picking: Three.js supports picking on an InstancedMesh. The raycast result includes the instanceId, so you know which instance was clicked and can update it (move, recolor, etc.).
  4. Grid/plane: You can keep the grid helper and plane as normal meshes; they’re just one or two objects.

This method combines minimal draw calls with full per-object interactivity. If you must have unique materials for each object, you’d either need multiple InstancedMeshes or a more advanced batching approach.

1 Like

I agree that InstancedMesh or BatchedMesh are both fine choices for this use case. You can manipulate the transform matrix (position, rotation, scale) and color for each instance independently, or control more than just if you use custom shaders.

I tried those approach using InstancedMesh, but it was slightly different from what I need.

Let’s say I have 3 Red Cubes (Instance 0) and 2 Blue Cubes (Instance 1). With InstancedMesh, I can change the color of Instance 0 (all three Red Cubes) to another color, (for example Green).

But my requirement demands the ability to change the color, position and rotation of just one Red Cube , without affecting the remaining other 2 Red Cubes of Instance 0. In short, I need control over a single Cube(Mesh) within the same Instance.

Classically, instancedMesh of antiquity required a person (or persons) to instantiate its instancedColor immediately! That is, the assignment of colours – presumably a buffer of sorts – must fill the maximum count. This was true with early versions, if you were unfortunate enough to neglect updating promptly and appropriately. My team assigned a proper THREE.Color via an array loop.

Note the casual ‘o’ which transliteration may conflate.

I’m not sure why the 3 red cubes would be a single instance in this situation. Make an InstancedMesh containing 5 cubes (5 instances). Then set 3 to red and 2 to blue, and you can continue to manage the cubes’ position/rotation/scale/color individually. This would work with either InstancedMesh or BatchedMesh.

Also for what it’s worth you can put any kind of per instance data in a texture then read that using the instance id. Works for merged meshes, instanced meshes and batched meshes.