How To Restart Shader Time Nodes

I’m sure there’s better terminology for the problem I’m having, but using 2019’s Shader Graph, I’m trying to use a dissolve shader that when an object is clicked, it dissolves completely before being destroyed.

When the material of the clicked object is switched to the dissolve shader material, the dissolving doesn’t start from the beginning of the dissolve. It instead is constantly internally lerping between its dissolved and undissolved state. Whenever I click on this object, the object simply takes the internal timescale of the dissolve. Rather than dissolving, it may be already mostly dissolved, undissolving, or completely dissolved. I’m trying to find a way to only make it begin dissolving as soon as the material is changed over. Attached is my shader graph, many thanks to anyone who can assist.

Hey @Feldethain instead of driving the shader using the built in shader Time node, you will want to instead add another shader property which you drive from your application (i.e. from a C# script).


Delete the Time node that feeds into your Remap node. Now add a Vector1 property and call it “Phase” and change the reference name to “_Phase”. May as well leave that property exposed since this will allow you to test how this Phase property effects the shader from the editor.


Save the shader asset and switch to your scene view. Now, depending on the speed and steps of noise being applied, if you set the Phase to 0, from the editor dragging that value up should dissolve the material in a linear fashion. Try dragging it down to (to see the material resolve, i.e. dissolve in reverse).


Now it’s a simple matter of updating the phase value from a script in, I am guessing, a linear fashion? Lerp is your friend in this case. Here is the code I’m using for a shock wave effect which I have connected to a menu click:

    // ensures shockwave plays once and does a full wave over duration
    IEnumerator PlayShockwave(float duration, Renderer shockwave)
    {
        float timeElapsed = 0f;
        float speed = Mathf.Abs(shockwave.material.GetFloat("_Speed"));
        float phase = shockwave.material.GetFloat("_Phase");
        float targetPhase = 1 / speed;

        while (timeElapsed <= duration)
        {
            timeElapsed += Time.deltaTime;
            shockwave.material.SetFloat("_Phase", Mathf.Lerp(phase, targetPhase, timeElapsed / duration));
            yield return new WaitForEndOfFrame();
        }
    }

Which is called like so: StartCoroutine(PlayShockwave(2.75f, ShockwaveRenderer));


If you don’t have a Speed input for your dissolve shader play around with the Phase float in the editor view and figure out what value it needs to be at to have the material “fully” dissolved. That’s your targetPhase, so just lerp from 0 to that target based on timeElapsed / duration (that gives you more control over how fast or slow the dissolve should happen).

Good luck!