Palette Blender - AlbertGBarber/PixelSpork GitHub Wiki
See the Documentation Guide for help understanding each page section.
Streamer Effect Using 3 Color Palette Being Blended Through Random Colors
(see here segment layout info) |
A utility that takes a starting and ending palette and produces a palette that is blended over a set time from the start towards the end palette. You also have options for looping the blend so that it repeats and randomizing the palette colors for each loop. This allows you to produce an endless set of blending colors, which you can then plug into effects.
See the Palettes and Util Classes code example for a working usage of the utility.
See Palette Basics for info on palettes. Also see the Palette Cycle utility for blending through a set of palettes.
The utility's blended output palette is stored locally as blendPalette
.
You can use it in your effects like:
//Sets an effect's palette to your palette blender's output palette
//Note that this assumes that the effect's "palette" var is a pointer (true in most effects)
//So we need to pass the palette blender's palette by address (using the "&")
yourEffect.palette = &yourPaletteBlender.blendPalette;
You can also pass yourPaletteBlender.blendPalette
as part of the effect's constructor.
-
Overall, I recommend only blending between palettes of equal lengths. The length of the blended output palette will be the length of the longest input palette. For example, if I blend from a palette of 5 colors into a palette with 3, the output palette will have 5 colors. This makes it easier when looping and helps maintain compatibility with effects. Note however, that this means that sometimes the output palette will have repeats of colors. Consider the previous example, since our output palette will 5 colors, but the ending palette only has 3, two of the end palette colors will be repeated in the output. The repeats will follow the order of the ending palette, so it shouldn't be noticeable with most effects.
-
The blend can be set to loop (using
looped
). When looping, once the blend palette has reached the current ending palette, the utility swaps the starting and ending palette and resets itself, setting itself to blend back to the original starting palette. For example, if I had a two single color palettes of red and blue, when looping, the output palette would blend from red to blue, back to red, then back to blue, etc. -
When looping, the start/end palettes can be set (using
randomize
) to have their colors randomized each cycle. Note that this permanently changes the colors of the input start and end palette, so be sure you aren't using the palettes in other effects. If you do randomize, you may want to callreset()
just before you first update the utility. This will refill the blended output palette's colors, and can help prevent "jumps" where an input palette changes after the utility is setup, but before it starts updating. -
You can have the blend pause either at the beginning or end of the blend, with a configurable pause time,
pauseTime
. This is mainly used when looping. When paused, the palettes will not be blended, giving you time to reflect/absorb the current palette (and effect) colors, before cycling to a new palette.
-
The start and end palettes are not modified by the utility unless
randomize
is active. -
When looping, if you're not starting paused, you can use
step == 0
to track when the blend cycle restarts. If you are starting paused, you can use(step == 0) && !paused && !firstPauseDone
instead. This can be useful if you want to trigger effect changes when once the utility has finished a blend. -
If you have set an external variable pointing to one of the colors in the
blendPalette
(such as a background for an effect) be warned that theblendPalette
is allocated dynamically. If theblendPalette
is ever re-sized and re-allocated, any pointers to the palette will break, and need to be re-bound. However, the palette is only re-allocated if its size needs to change for a new blend (ie new start/end palettes are set that don't have the same max size as the previous pair), which you control. -
The blend palette is allocated dynamically. Be aware of memory fragmentation. See Memory Management for more details.
PaletteBlenderPS PaletteBlender(startPalette, endPalette, false, 50, 100);
/* Blends from the start palette to the end palette once (looping is false),
using 50 steps, with 100ms between each step
Note, you'll have to create your own start and end palettes. */
PaletteBlenderPS PaletteBlender(startPalette, endPalette, true, true, false, 0, 50, 100);
/* Blends from the start palette to the end palette once,
looping and randomizing the palettes with each loop cycle
(looping and randomize are true).
The utility will pause for 0ms after every cycle
(startPaused is false, and pauseTime is 0)
Uses 50 steps, with 100ms between each step.
Will produce a palette of ever-changing colors.
Note, you'll have to create your own start and end palettes. */
//Base constructor
PaletteBlenderPS(palettePS &StartPalette, palettePS &EndPalette, bool Looped, uint8_t TotalSteps, uint16_t Rate);
//Constructor including randomize and pausing options
PaletteBlenderPS(palettePS &StartPalette, palettePS &EndPalette, bool Looped, bool Randomize, bool StartPaused,
uint16_t PauseTime, uint8_t TotalSteps, uint16_t Rate);
-
palettePS* startPalette-- The palette of colors the output blend palette will start as. Can be changed later using a
reset()
function (see Functions below). -
palettePS* endPalette-- The palette of colors the output blend palette will end as. Can be changed later using a
reset()
function (see Functions below). -
bool looped -- If set true, the utility will reset and restart once a blend has ended, switching the start and end palettes (see note on looping in intro).
-
bool randomize (optional, default false) -- If true, will randomize the colors of the end palette. Combine this with looped to produce constantly changing palettes. Note that this will permanently modify the end palette so make sure you aren't using it elsewhere!
-
uint16_t pauseTime (optional, default 0) -- The length of time (ms) the utility will pause for once a palette blend has finished. Only relevant if looping. (See notes in intro).
-
bool startPaused (optional, default false) -- If true, the utility will pause before the blend starts instead of after it is over. Allows you to use the starting palette for a time before it is blended to the final palette. Mainly used when looping. The initial pause will be triggered on the first update().
-
uint8_t totalSteps (max 255) -- The total number of steps taken to blend between the palettes.
-
uint16_t* rate -- Update rate (ms). Is a pointer, allowing you to bind it to an external variable. By default it's bound the effect's local variable,
rateOrig
. See common varsrate
entry for more.
- palettePS blendPalette -- The blended palette created by the utility. See notes in intro on how to use it in effects.
-
bool compliment (default false) -- Only relevant when randomizing. If true, randomized palettes will only generate complimentary colors, which means they will be equally spaced across the hue spectrum (see the HSV color space). This should generate color sets that are different but "look good" together.
-
bool active (default true) -- If false, the utility/effect will be disabled (updates() will be ignored). See common vars
active
entry for more details.
-
void reset();
Restarts the blend (all settings and palettes stay the same).
-
void reset( palettePS &StartPalette, palettePS &EndPalette );
Restarts the blend with a new start/end palette, with the same steps and update rate.
-
void reset( palettePS &StartPalette, palettePS &EndPalette, uint8_t TotalSteps, uint16_t Rate) ;
Restarts the blend with all new settings.
-
void setupBlendPalette( uint8_t blendPaletteLength );
Creates the blend palette. You should not ever need to call this.
-
void update();
Updates the utility.
- uint8_t step -- The current blend step. See "Other Notes" above about using this to track the palette blend.