Rotate each buffer geometry that's merged by 'BufferGeometryUtils.mergeBufferGeometries' around each own center?

I have a mesh made like this:

  var cubes = []
  const boxGeometry = new THREE.BoxGeometry(1,1,1);
  const boxBufferGeometry = BufferGeometryUtils.mergeVertices(new THREE.BufferGeometry().copy(boxGeometry))

  var geometry1 = boxBufferGeometry.clone();
  var geometry2 = boxBufferGeometry.clone();

  var matrix1 = new THREE.Matrix4().makeTranslation(0, 0, 0);
  var matrix2 = new THREE.Matrix4().makeTranslation(0, 0, 3);

  geometry1.applyMatrix4(matrix1);
  geometry2.applyMatrix4(matrix2);

  cubes.push(geometry1);
  cubes.push(geometry2);

  var mergedGeometry = BufferGeometryUtils.mergeBufferGeometries(cubes);
  var mesh = new THREE.Mesh(mergedGeometry, new THREE.MeshStandardMaterial());

  scene.add(mesh);

The mesh is made this way to avoid having multiple calls.

I’m trying to rotate each cube around each own center Y-axis with just one draw call but I can’t figure out how.

Currently rotating them like this: mesh.rotation.y += 0.01;

The cube that’s located at (0,0,0) rotates around its own center Y-axis which is the same as the world’s origin but the other one at (0, 0, 3) rotates around the world’s origin Y-axis.

I want the one at (0, 0, 3) to stay at (0, 0, 3) and rotate its own center Y-axis.

I’d appreciate if you could provide some working code example.

Thanks in advance.

Hi!
Seems you’re looking for BatchedMesh from @donmccurdy

1 Like

@prisoner849
Thank you so much for taking your time.
Hmm. Looks like there’s no specific working code yet.

Is there any other approach, including making mesh in a different way to reduce the draw call?

InstancedMesh: three.js webgl - instancing - performance

Thank you.
I know there’s that, but don’t know how to rotate around the local center y-axis.
As I wrote in the topic’s description, a working example is appreciated.
Would you be able to provide some code?

Maybe just recreate geometry each frame.

Maybe just recreate geometry each frame.

That’s a horrible idea.

2 Likes

A very rough and perfectly imperfect attempt :sweat_smile: : https://jsfiddle.net/prisoner849/8krouz01/

MergedMesh

Feel free to modify it at your will :slight_smile:

3 Likes

Also you can merge geometry and into vertex shader check distance to point.
If distance<10 then not rotate, else rotate or move.

You’ll get weird results, if objects kind of side by side.
Like a tiny sphere right next to a huge box.

uniform mat4[${gs.length}] instanceMatrices;

Hey @prisoner849 how would you do this without mat4 being sent as a uniform. What would be the change here to put this on the InstanceAttribute on the shader and avoid 256 max_vertex limit? Would you just need to add a UV Buffer to the matrix of the BatchedMesh and then pass to the shader?

@D13 I would go with DataTexture in a uniform


The keyboard is a bunch of merged buffer geometries. DataTexture is kind of a mediator for interaction.

1 Like

I wanted to use instancedAttribute. Not uniform. My case was a thousands of words. I dont even think calling them words is really appropriate because technically they are just a lot of unique geometries. Instanced was a much cleaner solution.

I think so :slight_smile:

But I had fun, making that keyboard: Keyboard of merged geometries

1 Like

That keyboard is cool as hell! :yum:

You really should do a section on Shaders for InstancedAttributes and using merged bufferGeometries with InstancedAttributes. By far one of the more complex usecases that really doesn’t get enough attention.

Thanks for all fish btw. You guys are awesome.