Proportionally mix HSB color values

Hi, I need to gradually mix two HSB values to create a fade, but after doing some code I've found that HSB can't be mixed in the same way that RGB (but I need to keep working on HSB). I think that the parameters that mix well are Brightness and Saturation, but HUE is a mess with my current code.

This is the code:

 if (speed[on] == 1 || speed[on] == -1){
    fadeH[fadeCount] = fadeHref[fadeCount];
    fadeS[fadeCount] = fadeSref[fadeCount];
    fadeB[fadeCount] = fadeBref[fadeCount];
    fadeRef = t;
  } else {
    fadeHref[fadeCount] = h;
    fadeSref[fadeCount] = s;
    fadeBref[fadeCount] = b;
  }
  if (fadeTime[on] > abs(1000 / frameRate)){
    float q = (t - fadeRef) / fadeTime[on];
    h = ((fadeH[fadeCount] * (1-q)) + (h * q));
    s = ((fadeS[fadeCount] * (1-q)) + (s * q));
    b = ((fadeB[fadeCount] * (1-q)) + (b * q));
  }
  fadeCount++;

As you can see I'm just mixing the values proportionally through an established time span. I don't know how I should be mixing HUE.

Tagged:

Answers

  • edited August 2017

    Hue doesnt work the same as RGB because it is cyclical / radial rather than having a min/max. So if you want to blend 350 (red) with 10 (red) the intermediate value should be ((350 + (360+10)/2)%360 = 0 (red) ... NOT (350-10)/2 = 190 (teal).

  • It's a bit confusing to see what you're doing when most things are arrays

    if (speed[on] == 1 || speed[on] == -1)
    if(speed[on] != 0)

    Assuming speed[on] can me -1, 0, 1 this should be the same.
    I might be wrong about this as I only seen portion of your code.

    the abs() probably won't do anything

    h = ((fadeH[fadeCount] * (1-q)) + (h * q));
    is the same as ..
    h =lerp(fadeH[fadeCount],h,q);

    I wrote some example code, using some processing functions, if you're wondering what they do all of them are on the right-hand side on the reference page.

    https://processing.org/reference/

    use HSB colorMode ...

    colorMode(HSB, 360, 100, 100);

    if you just need to mix two colors ...

    color a, b, ab:
    ab = lerpcolor(a, b, float );  
    

    if you need to mix hue, saturation, brightness individially ...

    float HUE = lerp(       hue(a), hue(b), float );
    float SAT = lerp(saturation(a), saturation(b), float );
    float BRI = lerp(brightness(a), brightness(b), float );
    ab = color(HUE, SAT, BRI);  
    

    if you don't wan't to use HSB colorMode ...

    https://docs.oracle.com/javase/7/docs/api/java/awt/Color.html

    import java.awt.Color;
    float hsba[] = Color.RGBtoHSB((int)red(a), (int)green(a), (int)blue(a), null);
    float hsbb[] = Color.RGBtoHSB((int)red(b), (int)green(b), (int)blue(b), null);
    float HUE = lerp(hsba[0], hsbb[0], float);
    float SAT = lerp(hsba[1], hsbb[1], float);
    float BRI = lerp(hsba[2], hsbb[2], float);
    ab = Color.HSBtoRGB(HUE, SAT, BRI);
    
  • edited August 2017

    Hi, thank you very much. Sorry for the arrays, they're very useful for the main objective of the code. Your post led me to learn about lerp, and I found that also there's a function called lerpColor that seems to do exactly what I'm trying with my code. Great!

    I can't try it now, I'll do it tomorrow and report back.

Sign In or Register to comment.