BufferGeometry.merge or BufferGeometryUtils.mergeBufferGeometries: Add support for transformation matrix
See original GitHub issueSummary of feature request
.addScaledVector
but instead of adding a scaled vector, merging a transformed BufferGeometry
Description of feature request
For optimization purposes, I want to render a single buffer geometry instead of rendering each object in my scene separately
const geometry = THREE.BufferGeometryUtils.mergeBufferGeometries(this.children.map(child =>
child.geometry.clone().applyMatrix4(child.matrix) // The issue
));
this.add(new THREE.Mesh(geometry, this.children[0].material));
for (const child of this.children) {
child.visible = false;
}
(simplified code, not tested but should convey my point)
Unfortunately, the existing buffer geometry merge methods don’t support transforming each merged vertex by a custom matrix. That means I have to clone each child’s geometry and apply the matrix to the entire clone at once.
This is a waste of memory, and could be avoided with
BufferGeometry.merge(bufferGeometry, optionalMatrix)
BufferGeometryUtils.mergeBufferGeometries(bufferGeometries, optionalMatrices)
The 2nd option is slightly more awkward but is preferred because BufferGeometryUtils is lossless (doesn’t require manual index argument)
If a matrix is passed in, each vertex being merged in should have it applied.
Note: I know I could get around this by pre-applyMatrix4-ing all my objects’ geometries, but I don’t want to do that…I want them to share a single, applyMatrix4’d buffer geometry instance.
Note 2: For my use case, each child’s BufferGeometry is the same. A solution specific to my case is :
BufferGeometryUtils.stamp(bufferGeometry, matrices)
Which would take a single geometry and stamp it at multiple locations/rotations/scales defined by each matrix.
Three.js version
- Dev
- r114
Issue Analytics
- State:
- Created 4 years ago
- Comments:13 (1 by maintainers)
Top GitHub Comments
@finnbear both your results and your code look reasonable to me.
I expect that a carefully designed function could write arbitrary objects, with arbitrary transforms, into a large geometry buffer efficiently enough to make the 50-100ms latency go away. For an imaginary
BufferGeometryBuilder
example:However, this sort of API seems better as a new thing, rather than a change to
mergeBufferGeometries
.bufferGeometry1.merge(bufferGeometry2)
overwrites data rather than doing a union. This is rarely what users want.I’m not sure how we’d implement it in BufferGeometryUtils any other way, without duplicating a fair bit of code from:
BufferGeometry.prototype.applyMatrix4
BufferAttribute.prototype.applyMatrix4
BufferAttribute.prototype.applyNormalMatrix
BufferAttribute.prototype.transformDirection
I agree with @gkjohnson that InstancedMesh may be a better fit for this use case.