Search Unity

  1. We are migrating the Unity Forums to Unity Discussions. On July 12, the Unity Forums will become read-only.

    Please, do not make any changes to your username or email addresses at id.unity.com during this transition time.

    It's still possible to reply to existing private message conversations during the migration, but any new replies you post will be missing after the main migration is complete. We'll do our best to migrate these messages in a follow-up step.

    On July 15, Unity Discussions will become read-only until July 18, when the new design and the migrated forum contents will go live.


    Read our full announcement for more information and let us know if you have any questions.

Question Shared Material performance

Discussion in 'General Graphics' started by theCodeHermit, Aug 15, 2023.

  1. theCodeHermit

    theCodeHermit

    Joined:
    Sep 20, 2018
    Posts:
    39
    I have created a custom shader in shadergraph. It has many different values which can be changed.

    I want to use the shader to have different values on different static gameobjects (Walls, floors etc).
    For example one wall will be red and another blue. I see two ways to do that:

    1: Make two different materials. Assign the same shader on both. Then change the shader settings in each material.

    OR

    2: Create a single material. Asign the shader to it. Assign the same material to both walls. Then use the following editor code:

    Code (CSharp):
    1. Renderer renderer = Selection.activeGameObject.GetComponent<MeshRenderer>();
    2.  
    3. Material mat = renderer.sharedMaterial;
    4. renderer.sharedMaterial = new Material(mat);
    I want to know which way will be better for performance.

    Method 1 has different materials so I wont be able to use any performance optimization techniques (Like draw call batching or GPU instancing) But perhaps I can use the SRP batching for this ?

    Method 2 uses the same material everywhere so I guess it would be possible to use Draw call batching or GPU instancing. I am unsure what exactly am I doing with shared materials... Am I creating a shader or material instance ? If it is Shader instance then perhaps I can use SRP Batching ?

    I would really appreciate your help wit this.
     
  2. theCodeHermit

    theCodeHermit

    Joined:
    Sep 20, 2018
    Posts:
    39
    Ok I think I figured out what to do...
    Will go with 1. Aka: Use multiple materials with the same shader. As far as I understand the SRP Batcher is going to handle that. After some testing I saw it does improve performance in this case.
    Please correct me if I am missing something though.
     
  3. Sluggy

    Sluggy

    Joined:
    Nov 27, 2012
    Posts:
    1,042
    As you've probably found by now, yes the SRP batcher is very good at optimizing this kind of situation because it batches by shader. Unity's recommended approach is to use 'uber shaders' that provide many options and then create as many different materials as needed using as few of these uber shaders as possible. The different values will be uploaded to the GPU in buffers that are accessed by index as needed fore each material. Just keep in mind that in this case using multi compile shader variants is actually less useful because it creates a different shader for each variant, effectively losing the benefit of the SRP batcher.

    As far as your examples in the first post goes - there is no difference between them. You end up with two different materials in the end. The only difference is one is created at edit time in the editor and the other is created as runtime. So the only effect this will have is workflow related.