(Question) [Solved] Color interpolation

  • 5 Replies
  • 304 Views

0 Members and 1 Guest are viewing this topic.

Offline galac

  • *
  • Fractal Freshman
  • *
  • Posts: 5
« on: February 27, 2019, 04:23:34 PM »
Hello, I'm trying to do color interpolation (with 16bits colors), but I don't get smooth transitions when I use more than two colors.

Here is the result with two colors (0xFFFF, 0x0000):


And here with five colors (0x4708, 0xC5FA, 0x15D4, 0x0F92, 0x23CD):


(Sorry for the image quality)

The code (RGB565 is just an unsigned short int):
Code: [Select]
#define PALETTE_WIDTH 320
#define PALETTE_SIZE 5

RGB565 colors[PALETTE_SIZE] = { 0x4708, 0xC5FA, 0x15D4, 0x0F92, 0x23CD };

RGB565 Palette(uint16_t num)
{
float p = num / float(PALETTE_WIDTH-1);
num = (int)( (float)num*(PALETTE_SIZE-1)/(float)PALETTE_WIDTH );

byte r, g, b,
     r_t, g_t, b_t;

r = (colors[num].val & 0b1111100000000000) >> 11;
g = (colors[num].val & 0b0000011111100000) >> 5;
b = colors[num].val & 0b0000000000011111;
r_t = (colors[num+1].val & 0b1111100000000000) >> 11;
g_t = (colors[num+1].val & 0b0000011111100000) >> 5;
b_t = colors[num+1].val & 0b0000000000011111;

r = int( (1.0-p)*float(r) + p*float(r_t) );
g = int( (1.0-p)*float(g) + p*float(g_t) );
b = int( (1.0-p)*float(b) + p*float(b_t) );

return RGB565( (u16(r) << 11) + (u16(g) << 5) + u16(b) );
}

Maybe linear interpolation only works with two colors...

Linkback: https://fractalforums.org/programming/11/solved-color-interpolation/2652/
« Last Edit: February 27, 2019, 09:53:14 PM by galac »

Offline hobold

  • *
  • Fractal Friar
  • *
  • Posts: 114
« Reply #1 on: February 27, 2019, 08:42:36 PM »
Almost there. The value of p needs to be relative to each pair of colors in the palette. Maybe something like:

float p = float(num)*float(PALETTE_WIDTH - 1);
p = p - floorf(p);

Then the values of p across all of the palette is a sawtooth curve, rising repeatedly from zero to one between any two palette entries.

(Beware, the above code has just been hacked in as an illustration. It is untested and probably has bugs.)

Offline galac

  • *
  • Fractal Freshman
  • *
  • Posts: 5
« Reply #2 on: February 27, 2019, 09:48:08 PM »
Almost there. The value of p needs to be relative to each pair of colors in the palette. Maybe something like:

float p = float(num)*float(PALETTE_WIDTH - 1);
p = p - floorf(p);

Then the values of p across all of the palette is a sawtooth curve, rising repeatedly from zero to one between any two palette entries.

(Beware, the above code has just been hacked in as an illustration. It is untested and probably has bugs.)

Thank you, I was able to get it to work! I simply had to change a bit the code example you gave me.

Though, I should have noticed the sawtooth graph... I'll plot my value next time!

Here is the modified code if anyone is interested:
Code: [Select]
float p = float(num)/float(PALETTE_WIDTH)*float(PALETTE_SIZE-1);
num = (int)( (float)num*(PALETTE_SIZE-1)/(float)PALETTE_WIDTH );
p = p - num;

Offline mclarekin

  • *
  • Fractal Frankfurter
  • *
  • Posts: 594
« Reply #3 on: February 28, 2019, 07:28:38 AM »
@ hobold.  Thanks, for showing me how floor function is used with a color palette.

@ galac    A while ago i tested different interpolations with a palette - linear, trig, and parabolic (with mix functions to blend) but my implementation was too slow.  I think i will try again  :yes:

Offline Spyke

  • *
  • Strange Attractor
  • ******
  • Posts: 98
    • Spyke Art
« Reply #4 on: March 01, 2019, 11:32:02 PM »
@galac: You probably never considered a negative index into a color palette. But I have found it useful in some situations. Be aware that cast to int is not the same as floor() for negative numbers. This may be too pedantic, but consider changing your (int) to floor() and saving what may be a painful debug if someday you decide to allow negative palette indices.

Earl Hinrichs, offering free opinions on everything.

Offline mclarekin

  • *
  • Fractal Frankfurter
  • *
  • Posts: 594
« Reply #5 on: March 02, 2019, 09:03:11 AM »
Quote
negative index into a color palette
defiantly is useful when you are building up a colorValue using several colorValue components within each iteration, (opposed to a simple single distance based function). It is more intuitive when tweaking, e.g. a mandelbox may have tweakable color components derived from boxFold, sphere fold, varying scale,  etc,   the component parameters can be negative,

Before converting to RGB , offset the palette origin (or use other maths)  such that all points have positive FinalColorValues.


xx
"Time Span"

Started by cricke49 on Fractal Image Gallery

0 Replies
341 Views
Last post August 02, 2018, 07:05:21 AM
by cricke49
xx
MIT color drops.

Started by Caleidoscope on Chemistry

3 Replies
738 Views
Last post March 04, 2019, 08:33:15 AM
by mclarekin
clip
color trial

Started by mclarekin on Color Snippets

46 Replies
2651 Views
Last post February 27, 2018, 02:58:46 AM
by mclarekin
xx
color trial s12.

Started by mclarekin on Fractal Image Gallery

0 Replies
296 Views
Last post October 07, 2017, 01:36:23 AM
by mclarekin
xx
color trial s13

Started by mclarekin on Fractal Image Gallery

0 Replies
244 Views
Last post October 13, 2017, 12:01:14 PM
by mclarekin