Disposing of Textures, Materials, and MultiMaterials not used by any Mesh

Hi there! I’ve been using Babylon.js for a couple weeks now to try to create my first game and have had a lot of fun with it. Thanks for making a great framework and tending to an awesome community!

I have a couple questions regarding the safe disposal of Textures, Materials, and MultiMaterials. It looks like to get rid of these things you call .dispose() on them. I have a case where I may have many Meshes and they could be using any combination of Textures, Materials, and MultiMaterials. So one Texture could be used in more than one Material and one Material could be used in more than one MultiMaterial or Mesh. My use-case is that the user may want to delete a specific Mesh and I want to dispose of its associated resources only if they are not being used by another Mesh.

Is there a way, through the Babylon.js API, to quickly:

  1. Know what Materials are using a Texture?
  2. Know what MultiMaterials are using a Material or Texture?
  3. Know what Meshes are using a Texture, Material, or MultiMaterial?
  4. Dispose of a Texture, Material, or MultiMaterial if, and only if, it’s no longer being used by a MultiMaterial or Mesh? Something like a .dispose() with an option ifUnused or ifNoAssociatedMesh.

I’ve searched around and found another forum post where Material.getBindedMeshes() was added which helps us know a little bit about question 3, but I think it still suffers from the scenario where one may have a material1 that’s in use by both mesh1 and multiMaterial1. multiMaterial1 is used by mesh2. material1.getBindedMeshes() will return [mesh1], but it’s still used in mesh2 through multiMaterial1: Playground with similar scenario and console outs. In looking at the code for this method, this is by design as it’s only looking at what Meshes directly use a given Material, not looking through any MultiMaterials that may use it.

All this being said, I believe that if I want to accomplish the kind of safe disposal that I have in mind, I can either:

  1. Keep a map of Textures -> Materials, Materials -> MultiMaterials & Meshes, MultiMaterials -> Meshes. When the user removes a Mesh, I can remove it from the necessary map and check to see if there are any other Meshes/MultiMaterials using a Material or MultiMaterial and then follow the chain through to Textures to know what I can safely dispose of.
  2. Get all Meshes in the Scene and traverse down in a similar fashion.

Is there an easier way of doing this? Perhaps something like texture|material|multiMaterial.getAssociatedMeshes() that will traverse Materials and MultiMaterials and come up with a Mesh list for me? I looked through the API docs and couldn’t find anything, but maybe you folks know something I’ve missed or of a better solution!

In your case, I would keep the graph on your side so at least you ll be in full control of it and could even pull in some optim tricks if you know things might get reused soon and so on which not be possible by knowing the current links only :slight_smile:

Gotcha. I will keep the map on my side. Thanks sebavan.