Lerp from one Gradient to another

Hey guys,

I have 2 gradients defined and I would like interpolate between those two by time. When working with Colors I usually do that by using Color.Lerp, but it doesn’t seem to exists such a method for Gradients.

Any idea how I could do that?

If the two gradients have the same amount of color keys in the same exact places, then you can create a new gradient with the same keys in the same places and assign the color at each using Color.Lerp. If the gradients have differing color keys, you’d probably need to create a new gradient with all the keys from both, and assign each one a Color.Lerp between the key and its matching interpolated color at the given position on the other gradient.

1 Like

Necro’ing because this is still the top search on google for gradient lerping. Needed to do this today, here’s the helper script I made:

using System.Collections.Generic;
using UnityEngine;

namespace Util {
    public static class Gradient {
        public static UnityEngine.Gradient Lerp(UnityEngine.Gradient a, UnityEngine.Gradient b, float t) {
            return Lerp(a, b, t, false, false);
        }

        public static UnityEngine.Gradient LerpNoAlpha(UnityEngine.Gradient a, UnityEngine.Gradient b, float t) {
            return Lerp(a, b, t, true, false);
        }

        public static UnityEngine.Gradient LerpNoColor(UnityEngine.Gradient a, UnityEngine.Gradient b, float t) {
            return Lerp(a, b, t, false, true);
        }

        static UnityEngine.Gradient Lerp(UnityEngine.Gradient a, UnityEngine.Gradient b, float t, bool noAlpha, bool noColor) {
            //list of all the unique key times
            var keysTimes = new List<float>();

            if (!noColor) {
                for (int i = 0; i < a.colorKeys.Length; i++) {
                    float k = a.colorKeys[i].time;
                    if (!keysTimes.Contains(k))
                        keysTimes.Add(k);
                }

                for (int i = 0; i < b.colorKeys.Length; i++) {
                    float k = b.colorKeys[i].time;
                    if (!keysTimes.Contains(k))
                        keysTimes.Add(k);
                }
            }

            if (!noAlpha) {
                for (int i = 0; i < a.alphaKeys.Length; i++) {
                    float k = a.alphaKeys[i].time;
                    if (!keysTimes.Contains(k))
                        keysTimes.Add(k);
                }

                for (int i = 0; i < b.alphaKeys.Length; i++) {
                    float k = b.alphaKeys[i].time;
                    if (!keysTimes.Contains(k))
                        keysTimes.Add(k);
                }
            }

            GradientColorKey[] clrs = new GradientColorKey[keysTimes.Count];
            GradientAlphaKey[] alphas = new GradientAlphaKey[keysTimes.Count];

            //Pick colors of both gradients at key times and lerp them
            for (int i = 0; i < keysTimes.Count; i++) {
                float key = keysTimes[i];
                var clr = Color.Lerp(a.Evaluate(key), b.Evaluate(key), t);
                clrs[i] = new GradientColorKey(clr, key);
                alphas[i] = new GradientAlphaKey(clr.a, key);
            }

            var g = new UnityEngine.Gradient();
            g.SetKeys(clrs, alphas);

            return g;
        }
    }
}
13 Likes

Very useful :smile:. Thanks a lot

Wow! This really works!!

Be careful, you add up the key times from both gradients. In Unity you can only have 8 keys in total, so your method will not work if you have e.g. one gradient with 5 keys and another one with e.g. 4 keys, where all 9 keys are set at different key times!!