#define PI 3.14159265359 float DegreesToRadians(float degrees) { return degrees * PI / 180.0; } float RadiansToDegrees(float radians) { return radians * (180.0 / PI); } //Convert RGB with sRGB/Rec.709 primaries to CIE XYZ //http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html float3 RGBToXYZ(float3 color) { float3x3 transform = float3x3( 0.4124564, 0.3575761, 0.1804375, 0.2126729, 0.7151522, 0.0721750, 0.0193339, 0.1191920, 0.9503041 ); return mul(transform, color); } //http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_Lab.html float3 XYZToLab(float3 xyz) { float3 D65 = float3(0.9504, 1.0000, 1.0888); xyz /= D65; xyz = xyz > 0.008856 ? pow(abs(xyz), 1.0 / 3.0) : xyz * 7.787 + 16.0 / 116.0; float l = 116.0 * xyz.y - 16.0; float a = 500.0 * (xyz.x - xyz.y); float b = 200.0 * (xyz.y - xyz.z); return float3(l, a, b); } //http://www.brucelindbloom.com/index.html?Eqn_Lab_to_LCH.html float3 LabToLch(float3 lab) { float c = sqrt(lab.y * lab.y + lab.z * lab.z); float h = atan2(lab.z, lab.y); if(h >= 0.0) { h = RadiansToDegrees(h); } else { h = RadiansToDegrees(h) + 360.0; } return float3(lab.x, c, h); } //https://www.academia.edu/13506981/Predicting_the_lightness_of_chromatic_object_colors_using_CIELAB float CalculateFairchildPirrottaLightness(float3 lch) { float f1 = 0.116 * abs(sin(DegreesToRadians((lch.z - 90.0) / 2.0))) + 0.085; //HK magnitude float f2 = max(0, 2.5 - 0.025 * lch.x); //lightness ratio adjustment return lch.x + f2 * f1 * lch.y; } float GetLightness(float3 color) { float3 xyz = RGBToXYZ(color); float3 lab = XYZToLab(xyz); float3 lch = LabToLch(lab); return CalculateFairchildPirrottaLightness(lch) / 100.0; }