After merging bufferGeomtery is it possible have unique material for each geomtery?

after going through many older topics covering this topic i’m able to successfully merge geometries. Mostly thanks to this fiddle by @Mugen87 Issue with merging objects by its geometries using mergeBufferGeometries() - #5 by Mugen87

Now, can i assign some value/group/attribute to each geometry so that when creating a mesh i can pass a material array ?

or

Even if its the same material , i could also use a color atlas image to put all the uv coords of each geometry on each color grid of the atlas

Reason for merging is when the mesh count goes above ~100 AR sessions and windows’s glb viewer starts to lag but after merging i can add a 1000 cubes without issue.

The fiddle (merging part the is last function)
https://jsfiddle.net/orion_prime/xqLskny5/3/

Fiddle screenshot of three js handling 1000 cubes with MeshPhysicalMaterial like a champ :heart_eyes:

Not separate materials — a merged mesh is a single geometry/shader pair on the GPU. But different vertex colors or UV offsets can create similar effects with the built-in materials, or with custom shaders you can do nearly anything here.

2 Likes

Thanks!
Successfully added vertex color to each of the geometry

https://jsfiddle.net/orion_prime/xqLskny5/6/

output test on updated gltfViewer !

snippet

const color = new THREE.Color();

	for (const mesh of allMeshes) {

		const count = mesh.geometry.attributes.position.count;
		const geometry = mesh.geometry.clone();
		geometry.setAttribute( 'color', new THREE.BufferAttribute( new Float32Array( count * 3 ), 3 ) );

		const colorAttr = geometry.attributes.color;
		color.copy(mesh.material.color)
		
		for ( let i = 0; i < count; i ++ ) {
			colorAttr.setXYZ( i, color.r, color.g, color.b );
		}
		
		geometry.applyMatrix4(mesh.matrix)
		geometries.push(geometry);
	}

	const mesh = new THREE.Mesh(THREE.BufferGeometryUtils.mergeBufferGeometries( geometries ), mergedMaterial)
	mesh.position.z= 2
	scene.add(mesh)

Now how do i do the UV method ? each geomtery’s uv points needs to be offset to a certain color of the atlas image

I do this by passing an array of materials to a Mesh and utilizing the groups property of BufferGeometry to set a material index three.js docs.

This of course creates additional draw calls per material though.

1 Like

You can add a UV offset without adding draw calls very similarly to the colorAttr code above. Access geometry.attributes.uv, and call setXY(...) for the offset into the atlas image. This would require creating the atlas image carefully to keep track of offsets.

2 Likes