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. Dismiss Notice

Question Animating a shader's range from 0 to 1 over time

Discussion in 'Shaders' started by stefanplc, Sep 1, 2020.

  1. stefanplc

    stefanplc

    Joined:
    Feb 21, 2015
    Posts:
    82
    Hello,

    I'm pretty bad at coding shaders however with some online searches I managed to build myself a dissolve shader that looks nice. One of the properties of this shader is the dissolve amount and it is a range that goes from 0 to 1. At 0 nothing is dissolved and at 1 the object is completely dissolved. At the moment I'm using an Animator component to animate the slider from 0 to 1 over the course of a couple of seconds.

    Would it be possible to create this animation inside the shader and would this be better in terms of optimization? If I had 100 objects that were to dissolve at the same time, I imagine that not having 100 Animator components and running the animation in the shader would probably run better right?

    If the above is correct, how could I code this animation in the shader so that it happens the moment the dissolve material is applied? Currently in my game objects that require this have a "regular" material applied by default and when the dissolve is needed the "regular" material gets removed and the "dissolve" material gets applied instead.

    Thank you!
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,238
    The way you'd do this is by setting a start or end time and/or duration property. You'd do this with a material property block (which is what the animators do internally to set material values). This means there's some scripting involved, and you'd still have to set values on all 100 objects, but it only has to happen "once" rather than updating every frame.

    Code (csharp):
    1. // c#
    2. rend.GetPropertyBlock(matBlock);
    3. matBlock.SetFloat("_DissolveStartTime", Time.timeSinceLevelLoad);
    4. rend.SetPropertyBlock(matBlock);
    5.  
    6. // shader properties
    7. [HideInInspector] _DissolveStartTime ("", Float) = 0.0
    8. _DissolveDuration ("Dissolve Duration", Float) = 1.0
    9.  
    10. // in shader function
    11. // goes from 0.0 to 1.0 over _DissolveDuration
    12. float dissolve = _DissolveStartTime > 0.0 ? saturate((_Time.y - _DissolveStartTime) / _DissolveDuration) : 0.0;
     
    hopeful and stefanplc like this.
  3. stefanplc

    stefanplc

    Joined:
    Feb 21, 2015
    Posts:
    82
    I'll give this a try, thank you!

    [ update ] - worked great, thanks!
     
    Last edited: Sep 2, 2020