Home Unity

unity shader Q, flashing one object?

mod
Offline / Send Message
rooster mod
Hi, this is something I'm trying to get my head around.. in Quest in addition to shaders it has a built in material system and using that this is easy, but in Unity I'm not so sure.

So, lets say I have 10 objects, all with the same shader. I want to make it so when I click on one, it flashes and slowly fades (lets say, using emissive colour). In addition, I want to be able to click rapidly on different ones and all have their flash effect to occur separately based on when they were clicked

the problem, or I guess what I think might be a problem, is when I change the material emissive colour, won't all objects with that shader flash? at least, if I change emissive in the inspector that's what happens. Do I need to make the shader a prefab or something so that all objects have their own instance of the shader?

thanks!

Replies

  • r_fletch_r
    Options
    Offline / Send Message
    r_fletch_r polycounter lvl 9
    are you using renderer.material? that works on a per object basis. I'm doing something similar but with the diffuse channel and it works fine.
  • equil
    Options
    Offline / Send Message
    yep, as long as you're modifying the material through script it should work the way you'd like it to.
  • rooster
    Options
    Offline / Send Message
    rooster mod
    ah, awesome thanks guys. I was just manually trying out what I'd make the script do, and didn't realise that script control would automatically affect instances only.

    That does raise one other question though- what happens if I *do* want all materials changed? Do I just iterate all the objects and do it one by one? or is there a global 'change all' method

    thanks :)
  • commander_keen
    Options
    Offline / Send Message
    commander_keen polycounter lvl 18
    When renderer.material is accessed it will automatically create a unique instance of the material for that renderer if its not already unique. If you dont want to have a unique material created you would use renderer.sharedMaterial. So if you want to change a material used by many objects you use that instead.
  • rooster
    Options
    Offline / Send Message
    rooster mod
    Hi, I have one more thought on this- lets say I'm creating some magic pillars, and I want to tint each one individually while placing them in the level, but they use the same material. Is there a way to do that manually instead of through script? would I need to include the material in the prefab for that to work?

    edit:
    another followup Q :)

    if I set a unique material property in a script (eg, with the flashing example), and it auto-creates an instance of the material, am I in doing so increasing the draw-calls?
  • LoTekK
    Options
    Offline / Send Message
    LoTekK polycounter lvl 17
    As far as I know, you can't edit instances through the inspector. You'd need to create dupes of the material (using the same shader), and edit those individually. Of course, that's probably not exactly ideal, so your best bet would be to do it in script.

    And yup, a new material instance would mean an additional draw call.
  • rooster
    Options
    Offline / Send Message
    rooster mod
    what would be the practical downside to duplicating the material? I'm guessing that to Unity it doesn't make any difference, it's an extra material one way or another- do you just mean from a work perspective it'd be annoying to have the dupes in the hierarchy?

    the thing with doing it in script, won't I have to deal with un-coloured items in the editor and not see the colours until runtime?
  • LoTekK
    Options
    Offline / Send Message
    LoTekK polycounter lvl 17
    Yeah, the downside would be more of a potential workflow and organisational thing. The more individual stuff you have, the harder it gets to start updating things. If you're happy enough with that (ie, if there are only going to be a handful of different material derivatives), then yeah, just duplicating the material in the hierarchy would probably work fine.

    If you want to see the material instances in editor mode, you could also try using ExecuteInEditMode in the script that does the tinting. You'll get error messages about leaks, however (which can more or less be ignored in this case).
  • commander_keen
    Options
    Offline / Send Message
    commander_keen polycounter lvl 18
    When you edit a material on an object and its linked to a Asset file it will change the asset file and have an effect on every other object using that material. If you want to create a unique instance in edit mode you can just copy the material asset and assign it to the renderer, or you can create an editor script that will create an instance of the material like this:
    //Dont try to access renderer.material in edit mode. It will cause errors.
    renderer.sharedMaterial = (Material)Instantiate(renderer.sharedMaterial);
    

    I think in 3.5 they added per renderer overrides for SetTexture, SetFloat, etc.. functions which will work on a per renderer basis instead of material. that way you can keep the reference to the material instance while specifying a single parameter override for the renderer.
    http://unity3d.com/support/documentation/ScriptReference/Renderer.SetPropertyBlock.html?from=MeshRenderer
    It not documented but I assume it allows you to assign MaterialPropertyBlock object to a renderer and it will use that when rendering the mesh like how it shows on the MaterialPropertyBlock page.
Sign In or Register to comment.