Search Unity

Object instances sharing materials and shaders

Discussion in 'General Graphics' started by rukqoa, Dec 12, 2018.

  1. rukqoa

    rukqoa

    Joined:
    Apr 6, 2013
    Posts:
    10
    I have an object prefab that is randomly generating its mesh and passing parameters from the mesh into the material, which is using a shader I made that basically colors it differently based on where the point is.

    The problem is now I'm creating multiple instances of the object prefab, but since they share the same shader and material, every time I change the material, it's applying the change to all the object instances. They all have the same coloring. Anyone know how I can make the objects all instantiate a new copy of the material/shader every time I create one or something?
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Why not use vertex colors?
     
    rukqoa likes this.
  3. rukqoa

    rukqoa

    Joined:
    Apr 6, 2013
    Posts:
    10
    That's how I ended up making it work. I just initially thought calculating the color in the shader (just an inverse lerp on a pre-defined gradient) would be faster, but not if I have to create a separate material for each object.
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Since you're already use a unique mesh per object, also having unique material per mesh wouldn't really add a significant extra expense in rendering, and may even be slightly faster than using vertex colors. This is just potentially easier.

    If you want to explore other options:

    If you're instantiating these at runtime, accessing the renderer.material automatically generates a clone of the material that can be uniquely modified. It's just another thing to manage, and manually destroy when removing the gameObject.
    https://docs.unity3d.com/ScriptReference/Renderer-material.html
    If you doing this outside of play mode then unique materials assets would need to be created, which isn't great. Again, fine for performance, just annoying to manage.

    The other good option is to use a material property block to assign the material color per renderer. This has the huge benefit of not creating new materials to be managed so it's much more "fire and forget". However property blocks are not serialized (i.e.: saved) so your script will need to apply the color on awake in both edit and play mode for it to show the change.
     
    BlackHoleTracer likes this.