This commit is contained in:
2024-12-16 08:27:20 +03:00
parent dbe7aebd4f
commit 87abfde205
6 changed files with 62 additions and 42 deletions

View File

@@ -37,34 +37,50 @@ const vec3 ConsoleColorVec3[16] = vec3[](
vec3(1.0, 1.0, 1.0) // White
);
// RGB to LAB conversion (simplified approximation)
vec3 rgb2lab(vec3 x) {
const float epsilon = 0.008856;
const float k = 903.3;
vec3 fx;
fx.x = x.x > epsilon ? pow(x.x, 1.0 / 3.0) : (k * x.x + 16.0) / 116.0;
fx.y = x.y > epsilon ? pow(x.y, 1.0 / 3.0) : (k * x.y + 16.0) / 116.0;
fx.z = x.z > epsilon ? pow(x.z, 1.0 / 3.0) : (k * x.z + 16.0) / 116.0;
return fx;
vec3 srgbToLinear(vec3 color) {
return mix(color / 12.92, pow((color + 0.055) / 1.055, vec3(2.4)), step(0.04045, color));
}
vec3 rgbToXyz(vec3 color) {
const mat3 rgbToXyzMatrix = mat3(
0.4124564, 0.3575761, 0.1804375,
0.2126729, 0.7151522, 0.0721750,
0.0193339, 0.1191920, 0.9503041
);
return rgbToXyzMatrix * color;
}
vec3 xyzToLab(vec3 xyz) {
const vec3 whitePoint = vec3(0.95047, 1.0, 1.08883); // D65 white point
xyz = xyz / whitePoint;
vec3 f = mix(pow(xyz, vec3(1.0 / 3.0)), 7.787 * xyz + 16.0 / 116.0, step(0.008856, xyz));
return vec3(
(116.0 * f.y) - 16.0,
500.0 * (f.x - f.y),
200.0 * (f.y - f.z)
);
}
vec3 rgb2hsv(vec3 c)
{
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
float d = q.x - min(q.w, q.y);
float e = 1.0e-10;
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}
// Perceptually weighted color difference (CIEDE2000-inspired)
float perceptualColorDistance(vec3 color1, vec3 color2) {
vec3 lab1 = rgb2lab(color1);
vec3 lab2 = rgb2lab(color2);
vec3 lab1 = xyzToLab(rgbToXyz(srgbToLinear(color1)));
vec3 lab2 = xyzToLab(rgbToXyz(srgbToLinear(color2)));
vec3 delta = lab1 - lab2;
// Compute LAB-like color difference with perceptual weighting
float deltaL = lab1.x - lab2.x;
float deltaA = lab1.y - lab2.y;
float deltaB = lab1.z - lab2.z;
// Perceptual weighting
return deltaL * deltaL * 1.0 + // Lightness difference
deltaA * deltaA * 1.5 + // Green-Red difference
deltaB * deltaB * 1.5; // Blue-Yellow difference
return dot(delta, delta);
}
// Advanced color matching considering multiple color attributes
int findMostPerceptuallyAccurateColor(vec3 color) {
int bestMatchIndex = 0;
float minDistance = perceptualColorDistance(color, ConsoleColorVec3[0]);