How to specify a color with hue, saturation and brightness in libGDX instead of r,g,b,a values. I noticed that the Color constructor only accepts rgba, at least autocompletion offered only rgba. Is this even possible? I wanted to create a gradient ranging from hue=0 to hue=255.
Asked
Active
Viewed 918 times
2 Answers
6
I don't think this is built into Libgdx, unless it's been added since I last checked. I made a utility method for it. This treats hue, saturation, and value as values from 0 to 1. (so pre-divide by 255 if that's the scale you're using). For hue, it circles round from red to yellow to green to cyan to blue to magenta and back to red. Or maybe in the opposite direction, forgot. I adapted the algorithm from Android's color class.
public static Color setColor (Color target, float hue, float saturation, float value){
saturation = MathUtils.clamp(saturation, 0.0f, 1.0f);
hue %= 1f;
if (hue < 0f) {
hue++;
}
value = MathUtils.clamp(value, 0.0f, 1.0f);
float red = 0.0f;
float green = 0.0f;
float blue = 0.0f;
final float hf = (hue - (int) hue) * 6.0f;
final int ihf = (int) hf;
final float f = hf - ihf;
final float pv = value * (1.0f - saturation);
final float qv = value * (1.0f - saturation * f);
final float tv = value * (1.0f - saturation * (1.0f - f));
switch (ihf) {
case 0: // Red is the dominant color
red = value;
green = tv;
blue = pv;
break;
case 1: // Green is the dominant color
red = qv;
green = value;
blue = pv;
break;
case 2:
red = pv;
green = value;
blue = tv;
break;
case 3: // Blue is the dominant color
red = pv;
green = qv;
blue = value;
break;
case 4:
red = tv;
green = pv;
blue = value;
break;
case 5: // Red is the dominant color
red = value;
green = pv;
blue = qv;
break;
}
return target.set(red, green, blue, target.a);
}

Tenfour04
- 83,111
- 11
- 94
- 154
-
@Quadslab, I revised your edit because it had incorrect output for negative values. – Tenfour04 Jun 04 '21 at 18:07
0
This is the version I have been using. All values are based on a 0...1 range, so you need to divide the hue by 255f. It is a port of this vec3 hsv2rgb(vec3 c) method by sam hocevar for glsl.
public static Color fromHSV(final float hue, final float saturation, final float value) {
//vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
final float
Kx=1f,
Ky=2f/3f,
Kz=1f/3f,
Kw=3f;
//vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
final float
px=Math.abs(fract(hue+Kx)*6f-Kw),
py=Math.abs(fract(hue+Ky)*6f-Kw),
pz=Math.abs(fract(hue+Kz)*6f-Kw);
//return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
return new Color(
value*mix(Kx,clamp(px-Kx,0f,1f),saturation),
value*mix(Kx,clamp(py-Kx,0f,1f),saturation),
value*mix(Kx,clamp(pz-Kz,0f,1f),saturation),
1f
);
}
public static float fract(final float x) {
return x-(int)x;
}
public static float mix(final float x, final float y, final float a) {
return x*(1f-a)+y*a;
}
public static float clamp(final float x, final float minVal, final float maxVal) {
return Math.min(Math.max(x,minVal),maxVal);
}
You can also reuse the Color
using Color.set(float r, float g, float b, float a)
.
public static Color fromHSV(final Color target, final float hue, final float saturation, final float value) {
//vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
final float
Kx=1f,
Ky=2f/3f,
Kz=1f/3f,
Kw=3f;
//vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
final float
px=Math.abs(fract(hue+Kx)*6f-Kw),
py=Math.abs(fract(hue+Ky)*6f-Kw),
pz=Math.abs(fract(hue+Kz)*6f-Kw);
//return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
return target.set(
value*mix(Kx,clamp(px-Kx,0f,1f),saturation),
value*mix(Kx,clamp(py-Kx,0f,1f),saturation),
value*mix(Kx,clamp(pz-Kz,0f,1f),saturation),
target.a
);
}
public static float fract(final float x) {
return x-(int)x;
}
public static float mix(final float x, final float y, final float a) {
return x*(1f-a)+y*a;
}
public static float clamp(final float x, final float minVal, final float maxVal) {
return Math.min(Math.max(x,minVal),maxVal);
}

Quadslab
- 294
- 3
- 9