Hiya!
I need to lerp between two gradients that are used in a visual effect graph, which could have keys set in different places.
Is there a way to do this that can create a new lerped gradient with more than 8 keys?
I’ve found this very helpful script online, but it uses Gradient.SetKey, so only allows 8 keys to be set:
using System.Collections;
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;
}
}
}
I read somewhere else that I could create a Color array of all the points of the gradient and then lerp these, but I’m unsure how I convert this array back to a new gradient?
[GradientUsage(true)]
public Gradient Gradient_Skinned;
[ColorUsage(true, true)]
public Color[] GradientValues_Skinned;
void CalculateGradientValues()
{
GradientValues_Skinned = new Color[256];
for (int i = 0; i < 256; i++)
{
GradientValues_Skinned[i] = Gradient_Skinned.Evaluate((float)i / 255f);
}
}
Am I missing something?
Unsure if I can only work with gradients with 4 keys (or 8 in the exact same position perhaps), or if there’s another solution? Thanks!