Hi folks, first time posting
I’m working with InstancedMesh in the following way: I load a GLTF file which has a bunch of mesh object defined in it. Each mesh will be used many times in the scene. I divide the models into two groups: those that have animations, and those that don’t. For the ones that do not have animations, I used InstancedMesh. Because materials cannot be shared between instanced and non-instanced meshes, I carefully clone any materials that are being referenced by the instanced meshes. However, I do not clone the textures, as (AFAIK) there is no requirement to do so. Instead the same textures are shared by both instanced and non-instanced meshes.
What I am seeing, however, is that the textures on instanced meshes sometimes appear black. This seems to happen randomly - sometimes when I reload the scene everything looks OK, other times it does not. The error seems correlated to the order in which the instances are created, although I am not absolutely certain of this.
In a few cases I will see an object with multiple textures where one of the textures is black and the other appears normal, so this problem seems to affect individual textures and not entire models.
I’ve examined the material object in the debugger and nothing looks incorrect.
Any advice on how I might go about debugging this problem?
Welcome! Everything you’re doing sounds reasonable to me, you shouldn’t need to clone any textures. I’m surprised by the issue here… would you be able to share a demo?
When cloning a material, are you pretty sure that you’re assigning each mesh a material that is a clone of its original? It’s possible two objects might share a material in the glTF file, but THREE.GLTFLoader would split that into two materials if one has vertex colors and the other does not, for instance.
Perhaps try cloning all of the materials (not just the ones attached to instanced meshes) and see if that changes anything.
Hi Don, thanks for answering. The way I am cloning the materials is as follows: I traverse the graph via Object3D.traverse(), and for each material (obj.material) that I find, I call material.clone() on it - however, I also maintain a map of materials I have already cloned, so if I encounter the same material more than once I don’t make two clones. (Basically I generate a unique key for each material based on the name in the GLTF file, and use that as the map key).
I’ll try your suggestion of cloning all the materials. It is interesting that the non-instanced meshes do not appear to be affected by the bug, so that just might work. Probably what I will do is use a different prefix for the map key so that these don’t get mixed together.
In terms of a demo, the problem is that this is part of a giant program, and the problem only started showing up once it reached a certain level of complexity. I don’t know if I could reduce to a simple demo and still have the problem manifest.
Clarifying here, is
material.name the map key? The material name may not be unique, so
material.uuid would be a safer choice.
Ah, I think that may have been it. Thanks!