Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BatchedMesh: Provide approach for sharing geometry and transforms between BatchedMesh #27203

Open
gkjohnson opened this issue Nov 17, 2023 · 3 comments
Milestone

Comments

@gkjohnson
Copy link
Collaborator

Description

Right now you can render a number of geometries with a single material using a BatchedMesh but you may want to swap materials of an individual mesh for things like selection, highlighting, etc. Right now that means creating and maintaining a completely different BatchedMesh which is slower and takes more memory. Instead it would be best if two BatchedMeshes could share geometry and potentially transform data so they can both specify different materials and visibility arrays.

Solution

I'm not exactly sure of some of the options here - but one solution is to add a "BatchedBufferGeometry" object that BatchedMesh references and stores all the geometry, draw ranges, etc. The BatchedMesh would still bookkeep the multidraw buffers, etc:

const mesh1 = new BatchedMesh( maxGeometryCount, maxVertexCount, maxIndexCount, material1 );
const index = mesh1.geometry.addGeometry( ... );
mesh1.setMatrixAt( ... );

const mesh2 = new BatchedMesh( mesh1.geometry, material2 );

mesh1.setVisibilityAt( 0, false );
mesh1.setVisibilityAt( 1, true );
scene.add( mesh1, mesh2 );

Alternatives

Instead the end user could just use something like a proxy or wrapper class that forwards all common information between the BatchedMeshes while reimplementing all needed:

const mesh1 = new BatchedMesh( ... );
const mesh2 = new BatchedMeshWrapper( mesh1 );

Or - possibly the better approach - BatchedMesh could support different and arbitrary material properties and textures but this can get complicated. It's possible this would be best done with node materials in the future.

Additional context

User mentioned this need in three-mesh-bvh: gkjohnson/three-mesh-bvh#513

@gkjohnson
Copy link
Collaborator Author

gkjohnson commented Nov 23, 2023

The demo referenced in #27170 (comment) is relevant to this discussion as it affords different materials across different objects in a single BatchedMesh. It shows highlighting objects with mouseover, as well. It won't fully help with transparent materials, though.

@mrdoob mrdoob added this to the r??? milestone Nov 28, 2023
@donmccurdy
Copy link
Collaborator

Hm, that is hard. I am hoping we could do this without a new subclass of BufferGeometry... I suppose the hard part is that the book-keeping of the two BatchedMesh classes needs to be shared?

Could we keep plain BufferGeometry objects underneath BatchedMesh, but allow syncing their full state with batchMesh1.copy(batchMesh2)?

@gkjohnson
Copy link
Collaborator Author

In the long term I think a solution that enables multiple different material properties in a single draw call like what I've shown in #27170 (comment) is most viable option. That won't work if someone want's to render hover or highlight state with completely different shaders - though thats likely much more of a corner case.

Could we keep plain BufferGeometry objects underneath BatchedMesh, but allow syncing their full state with batchMesh1.copy(batchMesh2)?

This an option - it just feels messy and maybe error prone. The geometry, draw ranges, reserved ranges, bounds, active state, etc would have to be synced between the meshes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants