Difference between revisions of "HSV color"

m (Color range from 0 - 255 to 0 - 1, minor code style changes)
 
(5 intermediate revisions by 5 users not shown)
Line 7: Line 7:
 
This function converts HSV values to RGB:
 
This function converts HSV values to RGB:
 
<source lang="lua">
 
<source lang="lua">
-- Converts HSV to RGB. (input and output range: 0 - 255)
+
-- Converts HSV to RGB. (input and output range: 0 - 1)
  
 
function HSV(h, s, v)
 
function HSV(h, s, v)
 
     if s <= 0 then return v,v,v end
 
     if s <= 0 then return v,v,v end
     h, s, v = h/256*6, s/255, v/255
+
     h = h*6
 
     local c = v*s
 
     local c = v*s
 
     local x = (1-math.abs((h%2)-1))*c
 
     local x = (1-math.abs((h%2)-1))*c
     local m,r,g,b = (v-c), 0,0,0
+
     local m,r,g,b = (v-c), 0, 0, 0
     if h < 1     then r,g,b = c,x,0
+
     if h < 1 then
     elseif h < 2 then r,g,b = x,c,0
+
        r, g, b = c, x, 0
     elseif h < 3 then r,g,b = 0,c,x
+
     elseif h < 2 then
     elseif h < 4 then r,g,b = 0,x,c
+
        r, g, b = x, c, 0
     elseif h < 5 then r,g,b = x,0,c
+
     elseif h < 3 then
     else             r,g,b = c,0,x
+
        r, g, b = 0, c, x
     end return (r+m)*255,(g+m)*255,(b+m)*255
+
     elseif h < 4 then
 +
        r, g, b = 0, x, c
 +
     elseif h < 5 then
 +
        r, g, b = x, 0, c
 +
     else
 +
        r, g, b = c, 0, x
 +
     end
 +
    return r+m, g+m, b+m
 
end
 
end
 
</source>
 
</source>
Line 30: Line 37:
 
     vec3 HSV(float h, float s, float v)
 
     vec3 HSV(float h, float s, float v)
 
     {
 
     {
     if (s <= 0 ) { return vec3 (0.0); }
+
     if (s <= 0 ) { return vec3 (v); }
 
         h = h * 6;
 
         h = h * 6;
 
     float c = v*s;
 
     float c = v*s;
Line 50: Line 57:
 
</source>
 
</source>
  
 +
Or for those who want to save up on space (and achieve better performance, as branching is quite costly on GPUs), here's one-liner:
 +
 +
<source lang="c">
 +
vec3 hsv(float h,float s,float v) { return mix(vec3(1.),clamp((abs(fract(h+vec3(3.,2.,1.)/3.)*6.-3.)-1.),0.,1.),s)*v; }
 +
</source>
  
 
[[Category:Snippets]]
 
[[Category:Snippets]]
 +
{{#set:LOVE Version=any}}
 +
{{#set:Description=An alternate colorspace, allowing for aesthetically-pleasing color transformations.}}
  
 
== Other Languages ==
 
== Other Languages ==
{{i18n|HSL color}}
+
{{i18n|HSV color}}

Latest revision as of 18:15, 2 March 2022

The HSV color space is based on how humans perceive color, and as such, makes various aesthetically-pleasing color transformations very simple.

  • Hue describes where in the spectrum the color is. As Hue increases, a color will transition in the following order: Red, orange, yellow, green, teal, blue, violet, purple, magenta, red.
  • Saturation denotes how vibrant a color is. Ranges from grey to pure color.
  • Value is how saturated an image is, the amount of each color.

This function converts HSV values to RGB:

-- Converts HSV to RGB. (input and output range: 0 - 1)

function HSV(h, s, v)
    if s <= 0 then return v,v,v end
    h = h*6
    local c = v*s
    local x = (1-math.abs((h%2)-1))*c
    local m,r,g,b = (v-c), 0, 0, 0
    if h < 1 then
        r, g, b = c, x, 0
    elseif h < 2 then
        r, g, b = x, c, 0
    elseif h < 3 then
        r, g, b = 0, c, x
    elseif h < 4 then
        r, g, b = 0, x, c
    elseif h < 5 then
        r, g, b = x, 0, c
    else
        r, g, b = c, 0, x
    end
    return r+m, g+m, b+m
end

and the same function implemented in GLSL, for those that need it:

    vec3 HSV(float h, float s, float v)
    {
    	if (s <= 0 ) { return vec3 (v); }
        h = h * 6;
    	float c = v*s;
    	float x = (1-abs((mod(h,2)-1)))*c;
    	float m = v-c;
    	float r = 0.0;
        float g = 0.0;
        float b = 0.0;

    	if (h < 1) { r = c; g = x;b = 0.0;}
	    else if (h < 2) { r = x; g = c; b = 0.0; }
	    else if (h < 3) { r = 0.0; g = c; b = x; }
	    else if (h < 4) { r = 0.0; g = x; b = c; }
	    else if (h < 5) { r = x; g = 0.0; b = c; }
	    else  { r = c; g = 0.0; b = x; }

    	return vec3(r+m,g+m,b+m);
    }

Or for those who want to save up on space (and achieve better performance, as branching is quite costly on GPUs), here's one-liner:

vec3 hsv(float h,float s,float v) { return mix(vec3(1.),clamp((abs(fract(h+vec3(3.,2.,1.)/3.)*6.-3.)-1.),0.,1.),s)*v; }


Other Languages