HSVというのは、いわゆるHSV色空間のことです。
これは、Hue(色相)、Saturation(彩度)、Value(明度)を表しておりましています。
ご存知?の通りRGBの色空間から、HSVの色空間へ変換が可能でして、
これを利用すれば、今のRGBの色から、少し濃い色にしたり、逆に薄い色にしたり、
明るい色にしたり、暗い色にしたり、色相を反転させたり、いろいろできるわけです。
そしてこちらが、関数と逆関数です。スキニツカテイイヨー(あんまりテストしてないので・・・)
float fractF(float x) { if(x >= 0) { return(x - (integer)x); } else { return(1.0 + (x - (integer)x));}}
vector getRgbFromHsv(vector hsv) {
vector rgb = <hsv.z, hsv.z, hsv.z>;
if(hsv.y > 0.0) {
hsv.x *= 6.0;
integer i = (integer)hsv.x;
float f = fractF(hsv.x);
if(i == 0) {
rgb.y *= 1.0 - hsv.y * (1.0 - f);
rgb.z *= 1.0 - hsv.y;
}
else if(i == 1) {
rgb.x *= 1.0 - hsv.y * f;
rgb.z *= 1.0 - hsv.y;
}
else if(i == 2) {
rgb.x *= 1.0 - hsv.y;
rgb.z *= 1.0 - hsv.y * (1.0 - f);
}
else if(i == 3) {
rgb.x *= 1.0 - hsv.y;
rgb.y *= 1.0 - hsv.y * f;
}
else if(i == 4) {
rgb.x *= 1.0 - hsv.y * (1.0 - f);
rgb.y *= 1.0 - hsv.y;
}
else if(i == 5) {
rgb.y *= 1.0 - hsv.y;
rgb.z *= 1.0 - hsv.y * f;
}
}
return(rgb);
}
vector getHsvFromRgb(vector rgb) {
float min = llListStatistics(LIST_STAT_MIN, [rgb.x, rgb.y, rgb.z]);
float max = llListStatistics(LIST_STAT_MAX, [rgb.x, rgb.y, rgb.z]);
vector hsv = <max - min, max - min, max>;
if(hsv.x > 0.0) {
if(max == rgb.x) {
hsv.x = (rgb.y - rgb.z) / hsv.x;
if (hsv.x < 0.0) {
hsv.x += 6.0;
}
}
else if(max == rgb.y) {
hsv.x = 2.0 + (rgb.z - rgb.x) / hsv.x;
}
else {
hsv.x = 4.0 + (rgb.x - rgb.y) / hsv.x;
}
}
hsv.x /= 6.0;
if(max != 0.0) {
hsv.y /= max;
}
return(hsv);
}
default {
state_entry() {
}
touch_start(integer total_number) {
vector color = <0.5, 0.7, 0.2>;
vector hsv = getHsvFromRgb(color);
vector rgb = getRgbFromHsv(hsv);
llOwnerSay((string) hsv);
llOwnerSay((string) rgb);
}
}
色相は0→1が360度に対応していますので、
1を超えたら、また0→1へを繰り返します。
余談ですが、HLS色空間というものもあります。
こちらは少し、また計算式が変わってきています。詳しいことはこちらに。
以上
そしていつものおまけ
GLSL でおなじみの lerp や fract はよく使用するので、準備しておくと便利です。
float fractF(float x) { if(x >= 0) { return(x - (integer)x); } else { return(1.0 + (x - (integer)x));}}
float minF(float x, float xmin) { if(x > xmin) { return xmin; } else {return x;}}
float maxF(float x, float xmax) { if(x < xmax) { return xmax; } else {return x;}}
vector lerpV(vector A, vector B, float r) { return(A * (1.0 - r) + B * r); }
float lerpF(float a, float b, float r) { return(a * (1.0 - r) + b * r); }
integer lerpI(float a, float b, float r) { return((integer)(a * (1.0 - r) + b * r)); }
float limitF(float x, float xmin, float xmax) { if(x > xmax) { return xmax; } else if(x < xmin) { return xmin; } else {return x;}}
integer limitI(float x, float xmin, float xmax) { if(x > xmax) { return (integer)xmax; } else if(x < xmin) { return (integer)xmin; } else {return (integer)x;}}
float normalizeF(float x, float xmin, float xmax) { return (x - xmin) / (xmax - xmin); }



コメント