Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Question Material instancing with procedural assemblies of prefabs

Discussion in 'General Graphics' started by ATMLVE, Aug 10, 2023.

  1. ATMLVE

    ATMLVE

    Joined:
    Jun 11, 2023
    Posts:
    59
    I'm creating a spaceship generator, creating little ships you can walk around inside of. I have a 'base material', and at runtime I create a new instance of that material, change that instance's color, and then apply that new material to all the exterior faces of the spaceship.

    The trouble here from what I've read is you generally don't want to do this since material instances, even identical ones, are considered unique by unity and have subsequent performance impacts. My larger issue is in order to have collision geometry, these ships contains lots of instances of this material instance. The other issue is memory leaks.


    I have a few questions:

    If I create that one instance of my base material and then apply only that to multiple game objects, does unity consider all those to still be using the same material, thus mostly negating the batching issue? I feel like it intuitively wouldn't be the case, but some things I've read suggest it is. I plan on there being quite a few modified materials at runtime.

    What's the best way to clean up old material instances when all game objects using it have been unloaded? I read about Resources.UnloadUnusedAssets(), is it that simple?

    Is there a better way to do what I'm doing?
     
  2. Sluggy

    Sluggy

    Joined:
    Nov 27, 2012
    Posts:
    853
    Resources. UnloadUnusedAssets is how you would release things like meshes and materials that are no longer referenced by anything.

    As for the batching issues, that is simply the nature of the beast. You'll notice many games dont allow users to select arbitrary colors and that is partly due to the fact that they want to limit the total number of potential materials. You have a few options: 1) Use a pallet texture and allow users to select only colors from that texture. Essentially all objects referencing this texture now can be batched. 2) Have a fixed number of materials. 3) Dynamically create new materials but keep them in a lookup table so that repeats can be shared. 4) Use one of the new render pipelines with SRP batching enabled where this sort of thing doesn't really matter anymore.
     
  3. ATMLVE

    ATMLVE

    Joined:
    Jun 11, 2023
    Posts:
    59
    Woah could you elaborate on #4? I'm using URP.
     
  4. Sluggy

    Sluggy

    Joined:
    Nov 27, 2012
    Posts:
    853
    The new pipelines support what is called SRP batching. Essentially the different values of each material using the same shader are uploaded to the GPU in arrays and indexed within the shader. This means that batching is done by shader rather than material. It requires that you have SRP batching enabled in your pipeline settings ( which it is by default) as well as the use of SRP-compatible shaders. You can use the inspector to see if a shader is SRP compatible or use the frame debugger to see where SRP batches are breaking.

    Take note that Draw Calls will appear to be quite high but they are not a particularly important metric since they are relatively cheap these days. Set pass calls are what you can use to roughly gauge things and again, you can use the frame debugger for more detail frame-by-frame analysis
     
  5. ATMLVE

    ATMLVE

    Joined:
    Jun 11, 2023
    Posts:
    59
    That's awesome to hear, mitigates a lot of my concerns, thanks for your help!