This should basically work, i can’t tell right now why the fecc it’s showing just one baked instance even though all data is present and numbers right, but maybe it’s related to the breaks codepen adds in the code. Might look into it later again when i have time, now it’s lunchtime
THREE.InstancedMesh.prototype.bakeGeometry = function () {
const target = new THREE.BufferGeometry;
const _v3 = new THREE.Vector3;
const _m4 = new THREE.Matrix4;
const {
geometry,
count,
instanceMatrix
} = this;
if ( geometry.index ) {
const index = target.index = geometry.index.clone();
index.array = new geometry.index.array.constructor( geometry.index.array.length * count );
index.count = geometry.index.count * count;
for ( let i = 0; i < count; i ++ )
for ( let ii = 0, l = geometry.index.count; ii < l; ii ++ )
index.copyAt( i * l + ii, geometry.index, ii );
}
for ( let name in geometry.attributes ) {
const srcAttribute = geometry.attributes[ name ];
const dstAttribute = target.attributes[ name ] = srcAttribute.clone();
const applyMatrix = name === 'position' || name === 'normal';
const isNormal = name ==='normal';
dstAttribute.count = srcAttribute.count * count;
dstAttribute.array = new srcAttribute.array.constructor( srcAttribute.array.length * count );
for ( let i = 0; i < count; i ++ ) {
if ( applyMatrix ) {
_m4.fromArray( instanceMatrix.array, i * 16 );
// Per instance transformation
for ( let ii = 0, l = srcAttribute.count; ii < l; ii ++ ) {
_v3.fromBufferAttribute( srcAttribute, ii );
isNormal ? _v3.transformDirection( _m4 ) : _v3.applyMatrix4( _m4 );
dstAttribute.setXYZ( i * l + ii, _v3.x, _v3.y, _v3.z );
}
} else {
// Shared attributes
for ( let ii = 0, l = srcAttribute.count; ii < l; ii ++ ) {
dstAttribute.copyAt( i * l + ii, srcAttribute, ii );
}
}
}
}
return target;
}
Another but more garbage generating approach is cloning geometries per instance and merging it all with BufferGeometryUtils as some example does, but this direction of an approach here would be more efficient especially when being baked more frequently and larger number of instances.
For the other approach you clone the original geometry in a loop and apply each instanceMatrix to it, and then merge all of them with BufferGeometryUtils .
I probably misread about that color part, you mean the same color as “all the same” or the same as each individual instance color?
Thanks for the code, that helped!
Here’s the fix for the index computation
const l = geometry.index.array.length;
const nbVertices = geometry.attributes.position.count;
for (let i = 0; i < count; i++)
for (let ii = 0; ii < l; ii++)
index.array[i * l + ii] = geometry.index.array[ii] + i * nbVertices;