Jump to content

Guide: Correct RGB to HSL conversion with gamma correction


Recommended Posts

Hey:Laie_58:

I'm partially creating this topic because I want to share my formulae, partially to save them somewhere for later so I don't have to redo it.

Forget those formulae from wikipedia's HSL/HSV page, they're not correct and fail especially hard when applying gamma correction.

Standard model formulae:

Spoiler
float4 color = float3(red, green, blue, alpha);
float lightness = (color.x + color.y + color.z) / 3.0f;
float saturation = sqrt(dot(color.xyz, color.xyz) - dot(color.xyz, color.yzx));

 

Gamma Correction formulae:

Spoiler
float4 color = float3(red, green, blue, alpha);

//make sure that a+b+c=1 and 0<a,b,c<1
float a = [whatever you like];
float b = [whatever you like];
float c = [whatever you like];

float lightness = dot(float3(a, b, c), color.xyz);

float3 s_vector = color.xyz - float3(lightness, lightness, lightness);
float n_a = 3.0f * a * a - 2.0f * a + 1.0f;
float n_b = 3.0f * b * b - 2.0f * b + 1.0f;
float n_c = 3.0f * c * c - 2.0f * c + 1.0f;
float normalizer = max(n_a, max(n_b, n_c));

float saturation = sqrt(dot(s_vector.xyz, s_vector.xyz) / normalizer);

float3 normal = float3(a, b, c);
normal /= sqrt(dot(normal, normal));
float3 s_a = float(1.0f - a, 0.0f - a, 0.0f - a);
float cos_phi = dot(s_vector, s_vector);
float sin_phi = dot(normal, cross(s_a, s_vector));

float Hue = Mathf.Atan2(sin_phi, cos_phi) / (2.0f * 3.14159265f);

 

Plug in 1/3 for a, b and c and you get the standard model formulae from above. Good values for a, b and c are a=0.2126, b=0.7152, c=0.0722.

Tip: If you calculate the normalizer value manually after you chose your a, b and c instead of letting the computer do it, you're saving a lot of computational cost.

In case there are any questions:

Spoiler

Color:

RGBa stands for red, green, blue, alpha.
Alpha means transparency and is not important for this calculation.

HSL/HSV means Hue, Saturation, Lightness / Hue, Stauration, Value. Difference is that Value only goes from black to fully colorized while Lightness goes from Black to White. This calculation concentrates on HSL.
Saturation means "greyness" of a color without taking the lightness into account; Black and white both have the same Saturation of 0. In the standard model, fully red, green and blue all have Saturation of 1 while with gamma correction, only the color to which you assign the biggest multiplier and its complementary color can reach a Saturation of 1.

All values are between 0 and 1, so e.g. lightness of 1 always means that the color is pure white. Or (1.0, 0.0, 0.0) is pure red. And saturation=0 always means that r=g=b for both standard model and whatever gamma correction you want to apply.

The complementary color of a fully saturated color is very easily calculated by swapping the 1's and the 0's, e.g. red=(1, 0, 0) has the complementary color cyan=(0, 1, 1).
For not fully saturated colors you'll have to subtract each component from 1, so e.g. (0.7, 0.3, 0.4) has the complementary color (0.3, 0.7, 0.6).

Yes, images and shaders with gamma correction look waaay better imho.

 

Coding language:

Formulae are written in C language, but should be easy to understand. With dot() is the dot product between two vectors meant, with max() the maximum of two floats and with sqrt() the square root. Floats are floating point numbers. floatn() is a n-dimensional vector with floating point numbers as components.

Everything in a line behind two slashes is commentary. Example:

This is code;
//This is commentary
This is code; //This is commentary
/*
This is commentary
This is still commentary
*/
This is code;

 

Mathematics:

Remember multiplication / division before addition / subtraction.
 

 

Edited by Lindor
Reason: figured out Hue formula
  • Like! 1
Link to comment
  • The title was changed to Guide: Correct RGB to HSL conversion with gamma correction

Figured out Formula for Hue calculation; it's basically the angle between the s_vector of the color and the s_vector of (1, 0, 0) a.k.a red. Original post has been updated.

  • Thanks! 1
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...
Please Sign In or Sign Up