Cloning mesh user for instancing

If I have a mesh S that I want to use with instances using two different material I seem to need do do the following:

let a = S.clone()
let b = S.clone()
a.material = material1
b.material = material2

And then do createInstance on a and b. Once I create instances from S or add instance buffers I can no longer clone it properly (instances are cloned, instance buffers are messed up etc).

I think that this means that I am paying three times the GPU-memory for the vertex/index-data (due to makeGeometryUnique). Would it be possible to create a .makeGeometrySomewhatUnique? I get that it is hard to make a clone function that works for everything but a targetted makeGeometryUnique would help a lot.

I think there are memory/resource ownership reasons why things are as they are, but before we do makeGeometryUnique some data is shared so it doesn’t seem impossible.

Any thoughts?

A use-case would be to render many instances of a heavy model with two different materials (or some other setting that need to go on the source mesh).

Hey, if they differ by they material, you cannot do anything else than what you are doing because different shaders and the need for instances.

If the materials are only different by a few things like vertex color then we can rely on instanced buffers

Thanks! We are using instance buffers too so this is for larger changes…!

I think what I am after is a special makeGeometryUnique that keeps pos/normal etc and just does new vertex array object. And let them have different instance buffers… there is nothing preventing this on webgl level afaik!

This is very specific though so but I will be happy to review a PR about it if you want to give it a try

I will try!

Ok I made a first sketch just to see if it was at all possible.

It runs and using spector.js I can see that it now uses the same buffers on the GPU. Memory on the CPU-side should also be shared. I tried implementing a cascading-thing in Geometry first where Geometries had an inner-geometry that they went to unless the outer Geometry specified that kind. It became very messy so settled on this simpler design.

I did some comments

Thanks! Did some updates based on feedback.
Still trying to assess if you hate it or not!

I like the clone a lot :wink:

A fun side thought: I tried my test without the cloneGeometry just to see it crash. But it didn’t!

I think this is because you have added a makeGeometryUnique in mesh.createInstance for 4.2 which is very good! But maybe it should be the new cloneGeometry instead that is called. Then you can have instance buffers for the world-matrix and also any instance buffers you like, but no copy of the mesh data at all. At least the heavy buffers are not duplicated… Given than I fix all the issues that is :wink:

Will try to make it more robust tomorrow, almost night time over here!

1 Like

My biggest concern now is that while the clone is cool and often what people want, it will mess up the dynamic nature of the geometry. If some other user of the vertex buffers changes them it will not propagate properly to the other users (since it will not be in the meshes-array of the geometry the vertex buffer is changed on). Perhaps we should only clone vertex buffers that aren’t updateable and copy the rest…

well I’m less concerned as calling clone is intentional and we can clearly document that side effect,