Group And Animate Meshes

Hi, I animate a cone (positions xyz, rotations xyz and scale xyz).
For now I create 4 meshes (external-cyan, base-white, internal-left-red, internal-right-texture) and animate them separately.

geometry.setAttribute(‘position’, new THREE.BufferAttribute( positions, 3));

It works, but now I would like to group these 4 meshes in one only object and animate the whole object in one shot e.g.

cone.rotation.x = rotX;

Can I merge the meshes in one and keep different materials on each single mesh (external, base, internal left and internal right)?

Furthermore I have to animate the cone angle and get geometries like the one here attached. This means that the “external” mesh geometry changes and the “base” mesh geometry changes too.
I guess I can use the vbo draw range method

geometry.setDrawRange = { start: 0, count: lastVertexIndex };

But If I merge the geometries in one only mesh, does it still work? Should I change the start/count index with a mere sum? How to animate the two surfaces (external and base) at the same time?

Which the best structure to give to my cone?

That’s what you get, merging 4 geometries (cone, circle, two triangles):


1 Like

Thank you!
That’s a great improvement. Now I know how to group meshes.
I’m still asking myself how to animate the angle phiLength along the time. Let’s say I have a vector phiLengths[frame] and I get the single value phiLength a the frame x in the animate function.

How to animate the geometries g, cg and eg within the mesh o?
I think about something like = phiLengths[frame]; = phiLengths[frame]; = phiStart + phiLengths[frame];

or something like = { start: 0, count: lastVertexIndex calculated on phiLengths[frame]};

  1. You can re-build a geometry with the new parameters.
  2. Modify material shaders, passing angle parameters in uniforms and processing them there.

Should I re-build the geometry at any frame, which means 60 times per second?
I think this would slow down the rendering performance.

On my OpenGL application I just glDrawRangeElements of the VBO from-to index to draw just the geometry I need on that frame but the whole geometry stays stuck. So at any frame I just set a new “from-to” indexes. That’s really fast.

Is a way to archive this on Three.js?
I saw a similar approach with

geometry.setDrawRange = { start: 0, count: lastVertexIndex };

but how can I access the single geometry once they have been merged? Should I store a pointer for each single geometry before I merge it?

I would build a custom single geometry and used a modified material to control the angle of slice.

Merging BufferGeometries is a great thing, but as you can see it also involves some effort.

But then: 1.You can re-build a geometry with the new parameters.

A completely different approach is to create the entire geometry as a single custom geometry. Then you can make the vertices dynamic.

Examples from the Collection of examples from

I also use this technique in the addon Addon to create special / extended geometries

Sorry, I couldn’t resist and it was fun to build this. :slight_smile:
A hand-crafted custom geometry + modified material:

PS It’s not the ultimate solution. It’s just an idea/concept/option.


Yeah, it seems to run fast. Let me run some test with at least 50 objects like this one. Thanks.

Works well with InstancedMesh (1000 instances):

1 Like

Because you always can not resist, I have a lot of work. But I like to do it. :slightly_smiling_face:

This year you have contributed more than 40 basic examples to the Collection of examples from .
:+1: :+1: :+1:

More than any other author.

You have helped many users with this. For this you deserve great thanks.

There are also excellent things from you in the extended examples.

Thanks, keep it up!


Thanks, Klaus!

Well, it’s all because of our great community :slight_smile:

Everyone is breathtaking

Wow! That’s great. But I can’t change the theta angle on this sample.
Anyway, my very best! :medal_sports:

In the last example, parameters for theta are set in an instanced buffer attribute theta, individually for each instance.

g.setAttribute("theta", new THREE.InstancedBufferAttribute(new Float32Array(theta), 2));