├── .media
├── oklab.png
├── srlab2.png
├── contextmenu.gif
└── originalGradient.png
├── LICENSE.meta
├── README.md.meta
├── package.json.meta
├── Editor.meta
├── Runtime.meta
├── Editor
├── Editor.asmdef.meta
├── GradientColorSpaceContextMenu.cs.meta
├── Editor.asmdef
└── GradientColorSpaceContextMenu.cs
├── Runtime
├── Runtime.asmdef.meta
├── Lab.cs.meta
├── Oklab.cs.meta
├── SRLAB2.cs.meta
├── GradientColorSpace.cs.meta
├── Runtime.asmdef
├── Lab.cs
├── Oklab.cs
├── SRLAB2.cs
└── GradientColorSpace.cs
├── package.json
├── LICENSE
└── README.md
/.media/oklab.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/markeahogan/GradientColorSpace/HEAD/.media/oklab.png
--------------------------------------------------------------------------------
/.media/srlab2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/markeahogan/GradientColorSpace/HEAD/.media/srlab2.png
--------------------------------------------------------------------------------
/.media/contextmenu.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/markeahogan/GradientColorSpace/HEAD/.media/contextmenu.gif
--------------------------------------------------------------------------------
/.media/originalGradient.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/markeahogan/GradientColorSpace/HEAD/.media/originalGradient.png
--------------------------------------------------------------------------------
/LICENSE.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 4351d83aba58126499f6a7ab61d5700b
3 | DefaultImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/README.md.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 2e25d52953cf8754793c59da5e842041
3 | TextScriptImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/package.json.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: d5c3f9a73283e614681cd625e0856ad0
3 | PackageManifestImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/Editor.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 80e4cc25e4f0bcf49959cff67740abf7
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Runtime.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 67d65d159a38ea24ca65e1ff98790193
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Editor/Editor.asmdef.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 0b84d8bfbc7248348950e582e00150f0
3 | AssemblyDefinitionImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/Runtime/Runtime.asmdef.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 7167cb9366116574a933d185d6da0899
3 | AssemblyDefinitionImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/Runtime/Lab.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 14fcf875eb4c1eb44ad92c5974f66dc2
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Oklab.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: d06bed11f943a0b499c94dc0704c5a56
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/SRLAB2.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: e3af8ae0f1d0e0f47af7d5bc89ffabd8
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/GradientColorSpace.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: cfa3f5d7ee863b04baf15cdf14883e66
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Editor/GradientColorSpaceContextMenu.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 9603155b404a1e5499c0e3ef2c17031a
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Runtime/Runtime.asmdef:
--------------------------------------------------------------------------------
1 | {
2 | "name": "PopupAsylum.GradientColorSpace",
3 | "rootNamespace": "",
4 | "references": [],
5 | "includePlatforms": [],
6 | "excludePlatforms": [],
7 | "allowUnsafeCode": false,
8 | "overrideReferences": false,
9 | "precompiledReferences": [],
10 | "autoReferenced": true,
11 | "defineConstraints": [],
12 | "versionDefines": [],
13 | "noEngineReferences": false
14 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "com.popupasylum.gradientcolorspace",
3 | "displayName": "Gradient Color Space",
4 | "version": "1.0.2",
5 | "unity": "2019.3",
6 | "description": "Provides functionality to break a simple UnityEngine.Gradient into a piecewise curve in other color spaces.",
7 | "keywords": [
8 | "gradient",
9 | "color",
10 | "space",
11 | "colorspace",
12 | "oklab",
13 | "srlab2"
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/Editor/Editor.asmdef:
--------------------------------------------------------------------------------
1 | {
2 | "name": "PopupAsylum.GradientColorSpace.Editor",
3 | "rootNamespace": "",
4 | "references": [
5 | "GUID:7167cb9366116574a933d185d6da0899"
6 | ],
7 | "includePlatforms": [
8 | "Editor"
9 | ],
10 | "excludePlatforms": [],
11 | "allowUnsafeCode": false,
12 | "overrideReferences": false,
13 | "precompiledReferences": [],
14 | "autoReferenced": true,
15 | "defineConstraints": [],
16 | "versionDefines": [],
17 | "noEngineReferences": false
18 | }
--------------------------------------------------------------------------------
/Runtime/Lab.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace PopupAsylum.GradientColorSpace
4 | {
5 | public struct Lab
6 | {
7 | public float L;
8 | public float a;
9 | public float b;
10 | public float alpha;
11 |
12 | public Lab(float l, float a, float b, float alpha = 1)
13 | {
14 | L = l;
15 | this.a = a;
16 | this.b = b;
17 | this.alpha = alpha;
18 | }
19 |
20 | public static Lab Lerp(Lab a, Lab b, float t)
21 | {
22 | return new Lab()
23 | {
24 | L = Mathf.Lerp(a.L, b.L, t),
25 | a = Mathf.Lerp(a.a, b.a, t),
26 | b = Mathf.Lerp(a.b, b.b, t),
27 | alpha = Mathf.Lerp(a.alpha, b.alpha, t)
28 | };
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 markeahogan
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Gradient Color Space
2 |
3 | A tool to convert a simple Unity.Gradient into a peicewise gradient interpolated in another color space.
4 | Useful to create nice looking gradients and avoid 'muddy' or perceptionally incorrect interpolated colors.
5 |
6 | ## Installation
7 |
8 | Installation via the Unity Package Manager.
9 |
10 | ### OpenUPM
11 |
12 | 1. In Unity on the top toolbar, go to `Edit > Project Settings > Package Manager`.
13 | 2. Add a new Scoped Registry (or edit the existing OpenUPM entry)
14 | ```txt
15 | Name package.openupm.com
16 | URL https://package.openupm.com
17 | Scope(s) com.popupasylum.gradientcolorspace
18 | ```
19 | 3. Click Save (or Apply)
20 | 4. Open `Window > Package Manager`
21 | 5. Next to the `+` icon, select `My Registries`
22 | 6. Select `Gradient Color Space` and click install on the bottom right.
23 |
24 | ### Git
25 |
26 | 1. In Unity on the top toolbar, go to `Window > Package Manager`.
27 | 2. Click the `+` icon and select `Add package from Git URL`.
28 | 3. Enter the Git URL of this repository `https://github.com/markeahogan/GradientColorSpace.git`.
29 |
30 | ## Gradient Conversion
31 |
32 | A Gradient with 2 keys can be converted into a piecewise gradient with the appearance of another color space using the `GradientColorSpace.ConvertGradient` method. It creates 6 keys between the first and last keys that are interpolated from the first to last color using the chosen color space.
33 |
34 | ##### Original Gradient
35 | 
36 | ##### Oklab Conversion
37 | 
38 | ##### SRLAB2 Conversion
39 | 
40 |
41 | ## Context Menu
42 |
43 | Right-clicking a gradient property's label will show a 'Color Space' context menu, allowing quick conversion.
44 |
45 | 
46 |
--------------------------------------------------------------------------------
/Runtime/Oklab.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace PopupAsylum.GradientColorSpace
4 | {
5 | static class Oklab
6 | {
7 | public static Lab FromColor(Color color)
8 | {
9 | return FromLinearColor(color.linear);
10 | }
11 |
12 | public static Lab FromLinearColor(Color linearColor)
13 | {
14 | float l = 0.4122214708f * linearColor.r + 0.5363325363f * linearColor.g + 0.0514459929f * linearColor.b;
15 | float m = 0.2119034982f * linearColor.r + 0.6806995451f * linearColor.g + 0.1073969566f * linearColor.b;
16 | float s = 0.0883024619f * linearColor.r + 0.2817188376f * linearColor.g + 0.6299787005f * linearColor.b;
17 |
18 | float l_ = cbrtf(l);
19 | float m_ = cbrtf(m);
20 | float s_ = cbrtf(s);
21 |
22 | return new Lab(
23 | 0.2104542553f * l_ + 0.7936177850f * m_ - 0.0040720468f * s_,
24 | 1.9779984951f * l_ - 2.4285922050f * m_ + 0.4505937099f * s_,
25 | 0.0259040371f * l_ + 0.7827717662f * m_ - 0.8086757660f * s_,
26 | linearColor.a);
27 | }
28 |
29 | public static Color ToColor(Lab lab)
30 | {
31 | return ToLinearColor(lab).gamma;
32 | }
33 |
34 | public static Color ToLinearColor(Lab lab)
35 | {
36 | float l_ = lab.L + 0.3963377774f * lab.a + 0.2158037573f * lab.b;
37 | float m_ = lab.L - 0.1055613458f * lab.a - 0.0638541728f * lab.b;
38 | float s_ = lab.L - 0.0894841775f * lab.a - 1.2914855480f * lab.b;
39 |
40 | float l = l_ * l_ * l_;
41 | float m = m_ * m_ * m_;
42 | float s = s_ * s_ * s_;
43 |
44 | return new Color(
45 | +4.0767416621f * l - 3.3077115913f * m + 0.2309699292f * s,
46 | -1.2684380046f * l + 2.6097574011f * m - 0.3413193965f * s,
47 | -0.0041960863f * l - 0.7034186147f * m + 1.7076147010f * s,
48 | lab.alpha);
49 | }
50 |
51 | private static float cbrtf(float l) => Mathf.Pow(l, 1f / 3f);
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/Editor/GradientColorSpaceContextMenu.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using UnityEditor;
3 | using UnityEngine;
4 |
5 | namespace PopupAsylum.GradientColorSpace.Editor
6 | {
7 | ///
8 | /// Adds a 'Color Space' context menu to Gradient properties that will create a piecewise gradient in a different color space
9 | ///
10 | [InitializeOnLoad]
11 | public class GradientColorSpaceContextMenu
12 | {
13 | static GradientColorSpaceContextMenu()
14 | {
15 | EditorApplication.contextualPropertyMenu += OnPropertyContextMenu;
16 | }
17 |
18 | private static void OnPropertyContextMenu(GenericMenu menu, SerializedProperty property)
19 | {
20 | if (property.propertyType != SerializedPropertyType.Gradient)
21 | return;
22 |
23 | var propertyCopy = property.Copy();
24 | menu.AddItem(new GUIContent("Color Space/sRGB"), false, () =>
25 | {
26 | UpdateGradient(propertyCopy, ColorSpace.sRGB);
27 | });
28 | menu.AddItem(new GUIContent("Color Space/Oklab"), false, () =>
29 | {
30 | UpdateGradient(propertyCopy, ColorSpace.Oklab);
31 | });
32 | menu.AddItem(new GUIContent("Color Space/SRLAB2"), false, () =>
33 | {
34 | UpdateGradient(propertyCopy, ColorSpace.SRLAB2);
35 | });
36 | }
37 |
38 | private static void UpdateGradient(SerializedProperty property, ColorSpace colorSpace)
39 | {
40 | Gradient g = GetGradient(property);
41 |
42 | if (!GradientColorSpace.IsSafeToConvert(g) &&
43 | !EditorUtility.DisplayDialog("Gradient Color Space",
44 | "Gradient Color Space interpolates between the first and last keys, inbetween keys will be lost",
45 | "OK", "Cancel"))
46 | {
47 | return;
48 | }
49 |
50 | GradientColorSpace.ConvertGradient(g, colorSpace);
51 | SetGradient(property, g);
52 | property.serializedObject.ApplyModifiedProperties();
53 | }
54 |
55 | static Gradient GetGradient(SerializedProperty property)
56 | {
57 | PropertyInfo propertyInfo = typeof(SerializedProperty).GetProperty("gradientValue", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
58 | return propertyInfo.GetValue(property, null) as Gradient;
59 | }
60 |
61 | static void SetGradient(SerializedProperty property, Gradient gradient)
62 | {
63 | PropertyInfo propertyInfo = typeof(SerializedProperty).GetProperty("gradientValue", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
64 | propertyInfo.SetValue(property, gradient);
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/Runtime/SRLAB2.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace PopupAsylum.GradientColorSpace
4 | {
5 | ///
6 | /// https://www.magnetkern.de/srlab2.html
7 | ///
8 | public static class SRLAB2
9 | {
10 | public static Lab FromColor(Color color)
11 | {
12 | float red = color.r;
13 | float green = color.g;
14 | float blue = color.b;
15 | float x, y, z;
16 | if (red <= 0.03928) red /= 12.92f;
17 | else red = pow((red + 0.055f) / 1.055f, 2.4f);
18 | if (green <= 0.03928) green /= 12.92f;
19 | else green = pow((green + 0.055f) / 1.055f, 2.4f);
20 | if (blue <= 0.03928) blue /= 12.92f;
21 | else blue = pow((blue + 0.055f) / 1.055f, 2.4f);
22 | x = 0.320530f * red + 0.636920f * green + 0.042560f * blue;
23 | y = 0.161987f * red + 0.756636f * green + 0.081376f * blue;
24 | z = 0.017228f * red + 0.108660f * green + 0.874112f * blue;
25 | if (x <= 216.0 / 24389.0) x *= 24389.0f / 2700.0f;
26 | else x = 1.16f * pow(x, 1.0f / 3.0f) - 0.16f;
27 | if (y <= 216.0 / 24389.0) y *= 24389.0f / 2700.0f;
28 | else y = 1.16f * pow(y, 1.0f / 3.0f) - 0.16f;
29 | if (z <= 216.0 / 24389.0) z *= 24389.0f / 2700.0f;
30 | else z = 1.16f * pow(z, 1.0f / 3.0f) - 0.16f;
31 |
32 | return new Lab(37.0950f * x + 62.9054f * y - 0.0008f * z,
33 | 663.4684f * x - 750.5078f * y + 87.0328f * z,
34 | 63.9569f * x + 108.4576f * y - 172.4152f * z,
35 | color.a);
36 | }
37 |
38 | public static Color ToColor(Lab lab)
39 | {
40 | float lightness = lab.L;
41 | float a = lab.a;
42 | float b = lab.b;
43 | float red, green, blue;
44 | float x, y, z, rd, gn, bl;
45 | x = 0.01f * lightness + 0.000904127f * a + 0.000456344f * b;
46 | y = 0.01f * lightness - 0.000533159f * a - 0.000269178f * b;
47 | z = 0.01f * lightness - 0.005800000f * b;
48 | if (x <= 0.08f) x *= 2700.0f / 24389.0f;
49 | else x = pow((x + 0.16f) / 1.16f, 3.0f);
50 | if (y <= 0.08f) y *= 2700.0f / 24389.0f;
51 | else y = pow((y + 0.16f) / 1.16f, 3.0f);
52 | if (z <= 0.08f) z *= 2700.0f / 24389.0f;
53 | else z = pow((z + 0.16f) / 1.16f, 3.0f);
54 | rd = 5.435679f * x - 4.599131f * y + 0.163593f * z;
55 | gn = -1.168090f * x + 2.327977f * y - 0.159798f * z;
56 | bl = 0.037840f * x - 0.198564f * y + 1.160644f * z;
57 | if (rd <= 0.00304f) red = rd * 12.92f;
58 | else red = 1.055f * pow(rd, 1.0f / 2.4f) - 0.055f;
59 | if (gn <= 0.00304f) green = gn * 12.92f;
60 | else green = 1.055f * pow(gn, 1.0f / 2.4f) - 0.055f;
61 | if (bl <= 0.00304f) blue = bl * 12.92f;
62 | else blue = 1.055f * pow(bl, 1.0f / 2.4f) - 0.055f;
63 |
64 | return new Color(red, green, blue, lab.alpha);
65 | }
66 |
67 | private static float pow(float x, float y) => Mathf.Pow(x, y);
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/Runtime/GradientColorSpace.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using UnityEngine;
3 |
4 | namespace PopupAsylum.GradientColorSpace
5 | {
6 | ///
7 | /// Provides methods for converting a Gradient into a piecewise gradient interpolated in a different color space
8 | ///
9 | public static class GradientColorSpace
10 | {
11 | private const int MAX_KEYS_MINUS_ONE = 7;
12 |
13 | ///
14 | /// Determines if data/keys would be lost by converting the gradient
15 | ///
16 | /// The gradient to be converted
17 | /// Returns false if converting would cause data/keys to be lost
18 | public static bool IsSafeToConvert(Gradient gradient)
19 | {
20 | var keys = gradient.colorKeys;
21 |
22 | if (keys.Length == 2) { return true; }
23 | if (keys.Length != 8) { return false; }
24 |
25 | float expectedSpacing = (keys[7].time - keys[0].time)/7;
26 | for (int i = 1; i < 8; i++)
27 | {
28 | float diff = Mathf.Abs((keys[i].time - keys[i - 1].time) - expectedSpacing);
29 | if (diff > 0.001f) { return false; }
30 | }
31 |
32 | return true;
33 | }
34 |
35 | ///
36 | /// Converts a simple gradient into a piecewise gradient interpolated in a different color space
37 | ///
38 | /// Gradient to be converted, must have at least 2 keys, keys between the first and last will be discarded
39 | /// The color space to convert to
40 | public static void ConvertGradient(Gradient gradient, ColorSpace space)
41 | {
42 | var originalKeys = gradient.colorKeys;
43 |
44 | if (originalKeys.Length < 2)
45 | {
46 | throw new ArgumentException($"Gradient must have at least 2 color keys, found {originalKeys.Length}");
47 | }
48 |
49 | var startKey = originalKeys[0];
50 | var endKey = originalKeys[originalKeys.Length - 1];
51 | if (space == ColorSpace.sRGB)
52 | {
53 | gradient.colorKeys = new GradientColorKey[] { startKey, endKey };
54 | return;
55 | }
56 |
57 | var keys = originalKeys.Length == 8 ? originalKeys : new GradientColorKey[8];
58 | keys[0] = startKey;
59 | keys[MAX_KEYS_MINUS_ONE] = endKey;
60 |
61 | switch (space)
62 | {
63 | case ColorSpace.Oklab:
64 | OklabGradient(startKey, endKey, keys);
65 | break;
66 | case ColorSpace.SRLAB2:
67 | SRLAB2Gradient(startKey, endKey, keys);
68 | break;
69 | default:
70 | throw new Exception($"Can't handle {space}");
71 | }
72 |
73 | gradient.colorKeys = keys;
74 | }
75 |
76 | private static void OklabGradient(GradientColorKey startKey, GradientColorKey endKey, GradientColorKey[] keys)
77 | {
78 | Lab start = Oklab.FromColor(startKey.color);
79 | Lab end = Oklab.FromColor(endKey.color);
80 |
81 | for (int i = 1; i < MAX_KEYS_MINUS_ONE; i++)
82 | {
83 | float t = i / (float)MAX_KEYS_MINUS_ONE;
84 | var time = Mathf.Lerp(startKey.time, endKey.time, t);
85 | var col = Oklab.ToColor(Lab.Lerp(start, end, t));
86 | keys[i] = new GradientColorKey(col, time);
87 | }
88 | }
89 |
90 | private static void SRLAB2Gradient(GradientColorKey startKey, GradientColorKey endKey, GradientColorKey[] keys)
91 | {
92 | Lab start = SRLAB2.FromColor(startKey.color);
93 | Lab end = SRLAB2.FromColor(endKey.color);
94 |
95 | for (int i = 1; i < MAX_KEYS_MINUS_ONE; i++)
96 | {
97 | float t = i / (float)MAX_KEYS_MINUS_ONE;
98 | var time = Mathf.Lerp(startKey.time, endKey.time, t);
99 | var col = SRLAB2.ToColor(Lab.Lerp(start, end, t));
100 | keys[i] = new GradientColorKey(col, time);
101 | }
102 | }
103 | }
104 |
105 | public enum ColorSpace
106 | {
107 | sRGB,
108 | Oklab,
109 | SRLAB2
110 | }
111 | }
112 |
--------------------------------------------------------------------------------