(Question) [Solved] Color interpolation

  • 5 Replies
  • 303 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
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
xx
Color Spaces

Started by gurroa on Fractal movie gallery

0 Replies
107 Views
Last post February 27, 2019, 11:43:07 AM
by gurroa
xx
color by depth

Started by mclarekin on Fractal Image Gallery

1 Replies
251 Views
Last post January 29, 2018, 06:35:32 AM
by M Benesi