public static ColorLChuv Lerp(ColorLChuv c0, ColorLChuv c1, float f) { f = Mathf.Clamp01(f); float l, h; float c = -1; // Hue if (!float.IsNaN(c0.H) && !float.IsNaN(c1.H)) { h = Mathf.LerpAngle(c0.H, c1.H, f); h = h < 0 ? (h + 360f) % 360f : h; } else if (!float.IsNaN(c0.H)) { h = c0.H; if (c0.L == 0 || c1.L == 1) { c = c0.C; } } else if (!float.IsNaN(c1.H)) { h = c1.H; if (c0.L == 1 || c1.L == 0) { c = c1.C; } } else { h = float.NaN; } c = c == -1 ? c0.C + f * (c1.C - c0.C) : c; l = c0.L + f * (c1.L - c0.L); return(new ColorLChuv(l, c, h, Mathf.Lerp(c0.A, c1.A, f))); }
/// <summary> /// Generates a texture that encodes the Gradient specified by colors, colorKeyLocations, alpha and alphaKeyLocations. /// The generated texture is textureWidth x 1 pixels in size. /// Supports more than 8 each of Alpha Keys and Color Keys /// </summary> /// <param name="colors"></param> /// <param name="colorKeyLocations"></param> /// <param name="alphas"></param> /// <param name="alphaKeyLocations"></param> /// <param name="textureWidth"></param> /// <returns></returns> public static bool GradientToColors(Color[] colors, float[] colorKeyLocations, float[] alphas, float[] alphaKeyLocations, Color[] gradientColors, GradientMode mode) { Assert.AreEqual(colors.Length, colorKeyLocations.Length); Assert.AreEqual(alphas.Length, alphaKeyLocations.Length); // Invalid array lengths if (colors.Length != colorKeyLocations.Length || alphas.Length != alphaKeyLocations.Length) { return(false); } // Too few keys if (colors.Length < 2 && alphas.Length < 2) { return(false); } float prevColorKey = 0f, nextColorKey = colorKeyLocations[0]; Color prevColor = colors[0], nextColor = colors[0]; float prevAlphaKey = 0f, nextAlphaKey = alphaKeyLocations[0]; float prevAlpha = alphas[0], nextAlpha = alphas[0]; var textureWidth = gradientColors.Length; var invTextureWidth = 1f / (textureWidth - 1); for (int i = 0; i < textureWidth; i++) { float f = i * invTextureWidth; if (f >= nextAlphaKey) { if (nextAlphaKey < 1f) { prevAlphaKey = nextAlphaKey; prevAlpha = nextAlpha; int k = 0; while (k < alphaKeyLocations.Length && f >= alphaKeyLocations[k]) { k++; nextAlphaKey = k < alphaKeyLocations.Length ? alphaKeyLocations[k] : 1f; nextAlpha = alphas[k < alphas.Length ? k : k - 1]; } } } if (f >= nextColorKey) { if (nextColorKey < 1f) { prevColorKey = nextColorKey; prevColor = nextColor; int k = 0; while (k < colorKeyLocations.Length && f >= colorKeyLocations[k]) { k++; nextColorKey = k < colorKeyLocations.Length ? colorKeyLocations[k] : 1f; nextColor = colors[k < colors.Length ? k : k - 1]; } } } var colorFraction = (f - prevColorKey) / (nextColorKey - prevColorKey); var alphaFraction = (f - prevAlphaKey) / (nextAlphaKey - prevAlphaKey); var lerpedAlpha = Mathf.Lerp(prevAlpha, nextAlpha, alphaFraction); Color lerpedColor; switch (mode) { case GradientMode.LChuv: lerpedColor = ColorLChuv.Lerp(prevColor, nextColor, colorFraction); break; default: lerpedColor = Color.Lerp(prevColor, nextColor, colorFraction); break; } gradientColors[i] = new Color(lerpedColor.r, lerpedColor.g, lerpedColor.b, lerpedAlpha); } return(true); }