When I load a GLTF file it creates meshes of type Mesh and InstancedMesh. Problem is that I can not change the color of the InstancedMesh, because I can not assign a new material to it.
Is there a way to load a gltf file that does not create InstancedMesh but only unique Meshes?
Thanks. I will. I kind of though they were two different topics. On is GLTF related and the other is not, but they could both solve a current scenario I have.
What would be really powerful is to be able to plug into the load and decide for my case if the mesh should be instancedmesh or not.
On my scene meshes are responding to a point of the mouse and there are about 500-1000 InstancedMesh(s). When the user points at one I must highlight 18 of them, then when he points at a second I must highlight a group of 743 of them and when he points a third I must highlight about 200 of them.
So it would be useful to be able to āconfigureā which meshes are instanced and which are not. Of course this might prove unneeded If I manage to get the buffers working.
But I would really like to use the HighlightLayer for this and for the HighlightLayer I am not sure what the approach should be.
Are these group of instanced meshes static? It seems like the glTF can be authored such that the instances are created properly if you point each group of nodes to the same mesh and then duplicate the mesh for other groups.
No. They are not static. There are animations attached to them.
I tried duplicating all the InstancedMesh with a clone of the source original Mesh. But when there is an animation using the InstancedMesh, the animation is not animating the new cloned Mesh
Thatās not what I mean by static. My question is whether the grouping of the meshes are static (i.e. the instanced meshes donāt need to change each time you load the glTF).
Assuming the grouping is static, you should be able to change the source glTF file and make the instancing grouped in a way that works.
I donāt decide. The content creator decides and there are many of them.
I just receive a gltf and when the gltf(that could be exported from many different exporters) is displayed on the scene the user should click with the mouse and select the mesh. This selection means - highlight, blink, renderOverlay, renderOutline and many other things that are not supported by InstancedMesh.
So i donāt know which one is instanced and which is not. But we should be able to select a mesh.
Thinking about it today, the content creators might have created instances or might have not. So it will be a good feature when a GLTF is received to be able to decide how to group them to optimize the scene.
We recently had to load a scene with a bunch of bolts. And because of the details of the threads they are taking a lot of meshes. 3 billion triangles. And they come with a gltf that has no instances. About 700MB. Why, I donāt know. But I could optimize them. If one rotation of the bolt is created as a mesh and the others are instancedmesh probably there would be some importance improvements. (Although I am skeptical since I have not found data that compare the performance of mesh to instancedmesh to further understand the scenario)
Are you saying you will optimize the glTF before loading it or optimize it after/during loading? As you pointed out, once you use instances, the highlight layer wonāt work.
I understand you have unknown / possibly non-optimal input sources. How will you decide how to group the instances if the scenario is that users need to select arbitrary meshes? How does doing this on load help you? Iām just trying to understand the scenario.
I decided not to use highlight layer because of the instancedMesh. I am trying to highlight by drawing a new lines mesh around the object and enabling edges rendering.
But for the optimization.
As users are uploading arbitrary gltfs my options are:
0. leave it to the users to optimize them, which they may or may not do.
try to optimize them on the server with some python gltf library,
try to optimize them in browser and then save the optimized copy to be delivered to the next clients.
Ideally I would prefer to have one code base, and since I already have a viewer in the browser, probably I could do the optimization in the browser.
A threaded bolt is a repeating pattern. Each cycle repeats for about 20 times. And each cycle could consists of hundreds of thousands of vertexes. Even millions. Who needs this level of detail - nobody. But content creators often lack the tools to optimize the gltfs or have legacy project which when converted to gltf produce this results. We all agree they should be removed, but they should not be removed by hand, but rather automatically.
Theoretically I could have a few vertexes that describe 1 degree of the cycle and this could be repeated 360 times. Given that there are about 40-50 bolts on the scene if I have 1 mesh for the 1 degree of the cycle of the threaded bolt and InstancedMesh for the other 359 than it is ā20x360x50 times optimizedā
How exactly am I going to find the pattern I still donāt know, but I can handle the math. What I probably need in this case from a GLTF.Loader is to get the opportunity to run a check on a āraw geometry nodeā, before it is created as a mesh and decided if this āraw geometry nodeā should be in one large mesh, or one mesh and a lot of instancedmesh. In this way when there is a 20MB node to be loaded that is a threaded bolt I could load only one degree mesh in the memory and hundreds of thousands of instancedmesh that are offset by position and rotation. This, as far as I understood Babylon InstancedMesh in the last two days should take a lot less memory and should render a lot faster.
I think the onMeshLoaded could do be used for this. Load the whole Mesh and then create many InstancedMeshes and dispose of the unneeded Mesh. Would this work?
The last scene I received contained about 40 bolts and was about 700 MB.
Optimizing your glTF assets should be done before loading the model, on the server or client like you say. The glTF loader in Babylon is intended to load the asset into a renderable state as quickly as possible. It is not intended to do these kinds of optimizations on the fly.
var loader = BABYLON.SceneLoader.Load("./", "duck.gltf", engine, function (scene) {
// do something with the scene
});
// do something with the loader
// loader.<option1> = <...>
// loader.<option2> = <...>
// loader.dispose();
So I am doing:
var loader = BABYLON.SceneLoader.Load("/assets/", "map.gltf", engine, function (scene) {
... do something with the scene
});
loader.createInstances = false;// how is this here passed after the creation?
loader.dispose();