Manual Group matrix with InstancedBufferGeometry

I’m trying to use threebox code to sync 3d objects on top of mapbox map.
I’m using a “world” Group object and adding multiple InstancedBufferGeometry into it.
But somehow, the matrix manipulation of the group doesn’t affect it’s children.
This is the sync code: https://github.com/peterqliu/threebox/blob/master/src/Camera/CameraSync.js#L62
And my InstancedBufferGeometry is:

const cubeGeo = new InstancedBufferGeometry().copy(new BoxBufferGeometry(2, 2, 2) as any);
cubeGeo.addAttribute( 'cubePos', new InstancedBufferAttribute( new Float32Array( offsets ), 3 ) );
const material = new RawShaderMaterial({
   vertexShader: require('raw-loader!./vertex.glsl'),
   fragmentShader: require('raw-loader!./frag.glsl'),
});

this.world = new Group();
this.world.add(new Mesh(cubeGeo, material));

offsets is an array of each xyz position of every cube instance.
The code works find if I add multiple BoxBufferGeometry into the world
but somehow the matrix calculations don’t work for InstancedBufferGeometry.

And my vertex shader is:

precision highp float;

uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
 
attribute vec3 position;
attribute vec3 cubePos;

void main() {
   gl_Position = projectionMatrix * modelViewMatrix * vec4( position + cubePos, 1.0 );
}

I’d also love to have a simple explanation about the Group matrix vs worldMatrix.

Thanks!

An instance of Group makes it easier to apply a certain transformation to a group of objects. So the worldMatrix of the individual objects also contains the transformation of the superior group.

Example: https://jsfiddle.net/f2Lommf5/1776/

BTW: It’s not clear to me what you understand under the term “group matrix”. Do you refer to the model or world matrix of the group object?

Do you mind to create a live example that illustrates your problem? I can’t see an error in your provided code.

So what I want to achieve is a fully synced map with three.js objects, here is a working demo (zoom in a bit and you will see 5 boxes in their correct positions on the map):
http://jsfiddle.net/hs2jbbo0/46/

Now, I essentially have thousands of those boxes and on each zoom levels there are new ones which I’m replacing and animating into their final positions, so I’m attempting to convert this demo into an Instanced geometry since multiple meshes is too slow for me:
http://jsfiddle.net/hs2jbbo0/56/

So I have few problems here:

  1. I can’t get the second demo working
  2. I’m having hard time understanding the difference between world matrix and camera matrixWorld
    why is it being set differently?
  3. I want to disable the scale of each object, when the user zooms in the object should stay in the same size

I’ve updated your code so it works with instanced rendering. There were two problems:

  • You have to use ShaderMaterial instead of RawShaderMaterial otherwise uniforms like projectionMatrix are undefined.
  • You have to disable frustum culling on your instanced mesh.

http://jsfiddle.net/hs2jbbo0/92/

Wow this is amazing, so simple yet I’ve been bashing my head around it for quite some time!

Any input perhaps on the scaling question?
Since the world is scaled, do I need to somehow scale the instances so their size stays the same while I zoom?
If so I’d appreciate a bit of help on the jsfiddle with that…

Thanks a lot for your replies btw, really helped me a lot there!

Any input perhaps on the scaling question?

Unfortunately, i don’t know an answer on this right now. Maybe someone else of the community can help here.

I was wondering, is it somehow possible to offload this camera calculations to the GPU?
Using something like ShaderMaterial for meshes but specifically for the camera?