LODs in GLTF parser makes a bunch of Extra Textures and Materials?

So I have a gltf that has LODs being parsed. (Its a Unity Toolkit Export)

I have been working on optimizing a bunch of assets for a scene and making some custom materials for them when I noticed that a single LOD mesh chain will make duplicates of identical textures and materials. The underlying internal texture for a bunch of them are the same and they have no changes to any of their properties. I thought initially this was because of the lightmap differences, but this persisted even after disabling lightmaps.

I talked to @MackeyK24 directly about it thinking that this was an artifact of the Toolkit. He then explained to me that this section of the parse code was not from the toolkit but was rather behavior of the BJS GTLF parser. There may be some reasons for this but it seems to be excessive when the materials and the textures are identical (I cant see how its not a waste of memory).

These is the textures loaded after the glb parses. It is a single mesh with 4 levels of LOD. It seems it made duplicate references for all steps for every channel and duplicate subMaterials and MultiMaterials.

I am able to at runtime scrape the content and dispose all the duplicates and then rebind, but it seems like this should not even really be needed to be done.

Is there anyways we can have the parser look at the MultiMaterial bound to a mesh and then at a cache of already parsed materials to see if it is duplicate in all its props but id and name for itself and all subMaterials then if so have it bind to that cached material?

On a real big scene with 1000+ nodes all with LODs this creates a cluster effword for lack of a better term and with them being duplicate instances I don’t see the benefit of having so many initializations of the same buffers.

@bghgary I believe this is in your wheelhouse, could I get some input from you as to why it makes so many duplicates of the same buffer and if there is maybe some parser property that I am not taking advantage of? I know its not like its having to reserve a ton of extra things on small scenes but on larger more enterprise style projects this seems to be a significant memory expenditure.

Andy… Lets hook up tomorrow… It looks like the _L0 and _L1 and _L2 are not LOD levels but rather lightmap indexes … Maybe in Unity each LOD is represented on a different lightmap (0 , 1 and 2)… and the materials are already made… I will double check with you tomorrow…

That is why i said to UNCHECK the simple material names so we can see what is going on… I think LOD1 and LOD2 are creating the separate material instances… we can work on it though

we are really exporting all three LOD meshes as seperate meshes… then at runtime i am assigning the LOD distances… problem is they came accross as seperate material… maybe i can check if it is a LOD still use material from _L0

Yep… each one is actually in a different spot in the Unity Lightmaps (designated by the lightmap index for the mesh)…

So in short… you need the three separate material instances because the lightmapTexture atlas will be different for each LOD mesh

That’s fine, still don’t need to duplicate the textures for each material.

We should also look at moving the lightmap uv stuff to a 3 stride buffer of [uv2.x, uv2.y, lightmapIndex]. If we do 3 we then we can use a single material that can pull up the appropriate lightmap per model.

I only made this post because you said it was not the toolkit responsible for all the duplicate texture instances.

Also keep in mind this happened even when Lightmaps where completely disabled.

Can you send me the glTF?

I believe so, let me ask for permission.

Ill also need to do a Raw export of it for you that does not require the CVTOOLS_babylon_mesh extension so it will open in the sandbox.

(I should also check if the problem persists when that is done to be honest)

Ok it for sure still does it even with no Toolkit stuff included.

Ill send you the files now. Really odd, the gltf + bin is 2.3mbs but the glb is 81 mbs… thats really odd, I guess its the duplicate texture buffers?

I got the file from you in a PM. There are no duplicate materials as far as I can tell. There are multiple textures that have the same properties since that’s how the glTF is structured. The way the mapping goes:

glTF material → Babylon material
glTF textureInfo → Babylon texture
glTF image → Babylon internalTexture

There is no way easy way to know in advance that the glTF textureInfo is going to be same between different parts of the glTF so the code just creates a new Babylon texture for each. It is theoretically possible to use the same ones, but it will require processing and the loader tries to avoid processing as much as possible. Unless you have a large number of materials, it shouldn’t really be an issue for memory or fps.

Also, not exactly related, the images are TGA, which are not supported by the glTF specification. It might work in Babylon.js, but they are not going to be portable.

1 Like