Seems to work, and it will only get easier with array initializers on the way…
// Define palette.
var paramA = array(3); var paramB = array(3); var paramC = array(3); var paramD = array(3);
// rainbow1: [[0.500 0.500 0.500] [0.500 0.500 0.500] [1.000 1.000 1.000] [0.000 0.333 0.667]]
paramA[0] = 0.500; paramA[1] = 0.500; paramA[2] = 0.500;
paramB[0] = 0.500; paramB[1] = 0.500; paramB[2] = 0.500;
paramC[0] = 1.000; paramC[1] = 1.000; paramC[2] = 1.000;
paramD[0] = 0.000; paramD[1] = 0.333; paramD[2] = 0.667;
// Calculate the palette color at a particular point and return its RGB components.
function paletteColorAt(t, coeffA, coeffB, coeffC, coeffD, retVal) {
for (i=0;i<retVal.length;i++) retVal[i] = coeffA[i] + coeffB[i] * cos(PI2 * (coeffC[i] * t + coeffD[i]));
}
var paletteRGB = array(3);
export function render(index) {
paletteColorAt(index/pixelCount, paramA, paramB, paramC, paramD, paletteRGB);
rgb(paletteRGB[0], paletteRGB[1], paletteRGB[2]);
}
The cpt library is another good source of palettes; you can use PaletteKnife for FastLED to extract the coefficients and then render them like so:
// Define palette as a variable number of bands, each containing a startIndex, R, G, and B component.
function newPaletteRGB(numBands) { ary = array(numBands); ary.mutate((v) => array(4)); return ary; }
function setPaletteBandRGB(ary, index, offset, R, G, B) { ary[index][0] = offset; ary[index][1] = R >> 8; ary[index][2] = G >> 8; ary[index][3] = B >> 8; }
function LERP(percent, low, high) { return low + percent * (high - low); }
export var saveV;
function rgbFromFastLedPalette(v, palette, retVal) {
v = clamp(v << 8, 0, 255);
for (idx=0;idx<palette.length;idx++) {
if (v <= palette[idx][0]) {
// We're in this band, so LERP to find the appropriate shade.
if (v == 0) { retVal[0] = palette[idx][1]; retVal[1] = palette[idx][2]; retVal[2] = palette[idx][3]; }
else {
scale = (v - palette[idx-1][0]) / (palette[idx][0] - palette[idx-1][0]);
retVal[0] = LERP(scale, palette[idx-1][1], palette[idx][1]); retVal[1] = LERP(scale, palette[idx-1][2], palette[idx][2]); retVal[2] = LERP(scale, palette[idx-1][3], palette[idx][3]);
}
break;
}
}
}
// Gradient palette "quagga_gp" originally from http://soliton.vm.bytemark.co.uk/pub/cpt-city/rc/tn/quagga.png.index.html; converted for FastLED with gammas (2.6, 2.2, 2.5)
var paletteQuagga = newPaletteRGB(6);
setPaletteBandRGB(paletteQuagga, 0, 0, 1, 9, 84);
setPaletteBandRGB(paletteQuagga, 1, 40, 42, 24, 72);
setPaletteBandRGB(paletteQuagga, 2, 84, 6, 58, 2);
setPaletteBandRGB(paletteQuagga, 3, 168, 88, 169, 24);
setPaletteBandRGB(paletteQuagga, 4, 211, 42, 24, 72);
setPaletteBandRGB(paletteQuagga, 5, 255, 1, 9, 84);
// Pattern
var pixelRGB = array(3);
export function render(index) {
rgbFromFastLedPalette(index/pixelCount, paletteQuagga, pixelRGB);
rgb(pixelRGB[0], pixelRGB[1], pixelRGB[2]);
}
This too will become simpler with v3.19+…happy days!