Skip to content

Instantly share code, notes, and snippets.

@totallyRonja
Created March 24, 2021 13:47
Show Gist options
  • Save totallyRonja/8b9d571225f31c7a0d14872cf1478c85 to your computer and use it in GitHub Desktop.
Save totallyRonja/8b9d571225f31c7a0d14872cf1478c85 to your computer and use it in GitHub Desktop.
OkLab color conversion functions for hlsl
static const float3x3 lrgb2cone = {
0.412165612, 0.211859107, 0.0883097947,
0.536275208, 0.6807189584, 0.2818474174,
0.0514575653, 0.107406579, 0.6302613616,
};
static const float3x3 cone2lab = {
+0.2104542553, +1.9779984951, +0.0259040371,
+0.7936177850, -2.4285922050, +0.7827717662,
+0.0040720468, +0.4505937099, -0.8086757660,
};
static const float3x3 lab2cone = {
+4.0767416621, -1.2684380046, -0.0041960863,
-3.3077115913, +2.6097574011, -0.7034186147,
+0.2309699292, -0.3413193965, +1.7076147010,
};
static const float3x3 cone2lrgb = {
1, 1, 1,
+0.3963377774f, -0.1055613458f, -0.0894841775f,
+0.2158037573f, -0.0638541728f, -1.2914855480f,
};
//conversion from linear srgb to oklab colorspace
float3 lrgb2oklab(float3 col) {
col = mul(col, lrgb2cone);
col = pow(col, 1.0 / 3.0);
col = mul(col, cone2lab);
return col;
}
//with alpha copy
float4 lrgb2oklab(float4 col) {
return float4(lrgb2oklab(col.rgb), col.a);
}
//conversion from oklab to linear srgb
float3 oklab2lrgb(float3 col) {
col = mul(col, cone2lrgb);
col = col * col * col;
col = mul(col, lab2cone);
return col;
}
//with alpha copy
float4 oklab2lrgb(float4 col) {
return float4(oklab2lrgb(col.rgb), col.a);
}
//conversion from Oklab colorspace to polar LCh colorspace
float3 toOklabPolar(float3 oklab) {
float3 polar = 0;
polar.x = oklab.x;
polar.y = sqrt(oklab.y * oklab.y + oklab.z * oklab.z);
polar.z = atan2(oklab.z, oklab.y);
return polar;
}
//with alpha copy
float4 toOklabPolar(float4 oklab) {
return float4(toOklabPolar(oklab.rgb), oklab.a);
}
//conversion from Oklab colorspace to polar LCh colorspace
float3 fromOklabPolar(float3 polar) {
float3 oklab = 0;
oklab.x = polar.x;
oklab.y = polar.y * cos(polar.z);
oklab.z = polar.y * sin(polar.z);
return oklab;
}
//with alpha copy
float4 fromOklabPolar(float4 oklab) {
return float4(fromOklabPolar(oklab.rgb), oklab.a);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment