yum/HLSL_OKLAB
HLSL conversion functions between LRGB and OKLAB/OKLCH, a perceptually uniform color space.
git clone https://git.yummers.dev/yum/HLSL_OKLAB
81ac81b
main
An HLSL implementation of OKLAB
OKLAB is a perceptually uniform color space. That means that blending between colors in OKLAB space produces more perceptually uniform gradients, without weird transitional colors or changes in perceptual brightness or saturation.
Top: HSV gradient varying only hue; Bottom: OKLCH gradient varying only hue.
The original OKLAB blog post explains its merits very well.
OKLAB should be supported in Unity 2022, but for us stuck on older versions, a library like this is necessary.
This code is not optimized. If using in a performance critical setting, you should premultiply all matrices in your desired transformation.
APIs provided:
float3 LRGBtoXYZ(float3 c); float3 XYZtoLRGB(float3 c); float3 XYZtoOKLAB(float3 c); float3 OKLABtoXYZ(float3 c); // Note: OKLCH hue is on the range [0, 2*PI], not [0, 1]. float3 OKLABtoOKLCH(float3 c); float3 OKLCHtoOKLAB(float3 c); // Everything below this line is unoptimized syntactic sugar. float3 LRGBtoOKLAB(float3 c); float3 OKLABtoLRGB(float3 c); float3 LRGBtoOKLCH(float3 c); float3 OKLCHtoLRGB(float3 c);
The gradient above was generated with this fragment shader:
fixed4 frag(v2f i) : SV_Target
{
float4 albedo = 1;
if (i.uv.y > 0.5) {
// HSV gradient
albedo.xyz = HSVtoRGB(float3(i.uv.x, 1.0, 1.0));
} else {
// OKLAB gradient
float3 c0 = LRGBtoOKLCH(float3(1, 0, 0));
c0.z += i.uv.x * 2 * 3.14159265;
albedo.xyz = OKLCHtoLRGB(c0);
}
return albedo;
}
This content is released under the MIT license.
1## An HLSL implementation of OKLAB 2 3OKLAB is a perceptually uniform color space. That means that blending 4between colors in OKLAB space produces more perceptually uniform gradients, 5without weird transitional colors or changes in perceptual brightness or 6saturation. 7 8 9*Top: HSV gradient varying only hue; Bottom: OKLCH gradient varying only hue.* 10 11The [original OKLAB blog post](https://bottosson.github.io/posts/oklab/) 12explains its merits very well. 13 14OKLAB [should be supported in Unity 152022](https://twitter.com/bjornornorn/status/1512428218892095496?lang=en), but 16for us stuck on older versions, a library like this is necessary. 17 18This code is *not* optimized. If using in a performance 19critical setting, you should premultiply all matrices in your desired 20transformation. 21 22APIs provided: 23``` 24float3 LRGBtoXYZ(float3 c); 25float3 XYZtoLRGB(float3 c); 26 27float3 XYZtoOKLAB(float3 c); 28float3 OKLABtoXYZ(float3 c); 29 30// Note: OKLCH hue is on the range [0, 2*PI], not [0, 1]. 31float3 OKLABtoOKLCH(float3 c); 32float3 OKLCHtoOKLAB(float3 c); 33 34// Everything below this line is unoptimized syntactic sugar. 35float3 LRGBtoOKLAB(float3 c); 36float3 OKLABtoLRGB(float3 c); 37 38float3 LRGBtoOKLCH(float3 c); 39float3 OKLCHtoLRGB(float3 c); 40``` 41 42The gradient above was generated with this fragment shader: 43``` 44fixed4 frag(v2f i) : SV_Target 45{ 46float4 albedo = 1; 47 48if (i.uv.y > 0.5) { 49// HSV gradient 50albedo.xyz = HSVtoRGB(float3(i.uv.x, 1.0, 1.0)); 51} else { 52// OKLAB gradient 53float3 c0 = LRGBtoOKLCH(float3(1, 0, 0)); 54c0.z += i.uv.x * 2 * 3.14159265; 55albedo.xyz = OKLCHtoLRGB(c0); 56} 57 58return albedo; 59} 60``` 61 62This content is released under the MIT license.