Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Hue Shift

Name: Anonymous 2019-07-19 9:30

Ok. The HSV formula for transferring RGB triplet into the HSV form is widely published. But I've failed to find any hints to how one arrives at it, so I could try to optimize it for my game's blitter routine. Therefore I tried to infer h,s,v formula myself, using basic vector math.

v = (r+g+b)/3 //value
hs = v-r,v-g,v-b //hue*saturation vector
s = hs.length //saturation
h = angle(hs/s) //hue is the angle of the vector


Guess when one needs to just change the saturation, there is no reason compute the angle or even vector length in full, but the common requirement to change the hue requires nasty computation. Can anyone hint at any efficient way of shifting hue?

Name: Anonymous 2019-08-05 22:44

Instead of introducing the previously devised custom color space, I want to see how fast I can do hue-saturation change in plain RGB. It seems not exactly fast. But would it be fast enough for my game? Here is the saturation multiplier function.
void saturate(int *sr, int *sg, int *sb, int f) {
int r, g, b, l;
r = *sr;
g = *sg;
b = *sb;
r = r*r; g = g*g; b = b*b;
l = LUMA8(r,g,b);
l = l*(256-f);
r = (r*f + l)>>8;
g = (g*f + l)>>8;
b = (b*f + l)>>8;
if (r < 0) r = 0;
if (g < 0) g = 0;
if (b < 0) b = 0;
r = isqrt16(r); g = isqrt16(g); b = isqrt16(b);
*sr = clamp_byte255(r);
*sg = clamp_byte255(g);
*sb = clamp_byte255(b);
}



Yes. You see it right. A mere saturation boost/reduce requires 3 square roots and a lot of other operations. That is for each pixel. Ideally gamma function should be 2.2, but that would be even more expensive, square roots map better to a lookup table and there is that old Quake hack you can use to computer them lightning fast. In addition, gamma=2.2 would require doing r=pow22lut[r], instead of less expensive r*r, but 256 byes LUT isn't that expensive. Disabling gamma correction leads to heavy artifacts, like de-saturated sprite being too dark.

Still in my format changing saturation would be as simple as moving the U,V coords towards the whitepoint:
NV = (V-WV)*Saturation + WV
NU = (U-WU)*Saturation + WU

I.e. far more simpler code. So if one does full scene saturation change, then RGB is not an option. Hue shifting can be solved in part by recoloring, but even recoloring is expensive in general case, because of requiring to compute 256 byte LUT for every shade of recolored color.

Generally one reduces saturation to make special effects more eye popping. I.e. if on a bomb explosion you reduce surroundings saturation, that explosion would look more heavy.

TLDR: gamedev isn't easy.

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List