Repository navigation
Releases: FastLED/FastLED
Release list
FastLED 3.10.6
- MP3 decoder: minimp3 is now the only backend, and it decodes in fixed point
- The RPSL/RCSL-licensed
src/third_party/libhelix_mp3/tree has been removed. FastLED's MP3 support is now entirely CC0 (minimp3), which is what makes the library redistributable without the Helix licence obligations. - The decoder defaults to an integer (Q26 fixed-point) DSP path, so MP3 decoding no longer needs an FPU. Float remains available for reference and comparison via
MINIMP3_FLOAT_POINT. - Integer SIMD kernels (SSE4.1 with runtime dispatch, NEON unconditionally on ARM64) accelerate the polyphase filter and DCT-32, and are gated on producing bit-identical PCM to the scalar path.
Mp3HelixDecoderis gone. It was an internalfl::third_partytype exposed only for backend-parity testing; the publicfl::Mp3Decoder/fl::Mp3API is unchanged. Code that namedMp3HelixDecoderorMP3_HELIX_STREAM_BUFFER_SIZEdirectly should useMp3Minimp3Decoder/MP3_MINIMP3_STREAM_BUFFER_SIZE.- Working RAM for the shipping fixed-point build is 23,308 bytes against Helix's 27,952 (the float reference build measures 23,180), and the budget is enforced in CI by
codec_memory_ledger.md.
- The RPSL/RCSL-licensed
- NEW: TrueType Font Rendering Support: Full TrueType font (.ttf/.ttc) rendering API with embedded default font
- High-quality text rendering: Render scalable TrueType fonts to LED matrices with antialiasing support
- stb_truetype integration: Built on industry-standard stb_truetype library (5108 lines, compact and efficient)
- Embedded default font: Includes Covenant5x5 pixel font (9.9KB) with 5x5 pixel cell size, perfect for LED displays
- Custom font support: Load any TrueType font from memory (
.ttfsingle fonts or.ttcfont collections) - FontRenderer API: Convenient high-level wrapper for rendering at specific pixel heights
fl::Font::loadDefault()- Load embedded Covenant5x5 fontfl::Font::load(fontData)- Load custom TrueType font from memoryfl::FontRenderer(font, pixelHeight)- Create renderer at specified sizerenderer.render('A')- Render character with 2x2 antialiasing (default)renderer.renderNoAA('A')- Render without antialiasing for crisp pixelsrenderer.measureString("Hello")- Calculate string width with kerning
- Advanced features:
- Grayscale antialiasing with configurable oversampling (1x1 to NxN)
- Automatic kerning support for professional text layout
- Font metrics query (ascent, descent, line gap, bounding boxes)
- Glyph metrics (advance width, side bearings, per-character bounds)
- Unicode codepoint support
- Scaled metrics calculation for any pixel height
- GlyphBitmap output: Rendered glyphs as 8-bit grayscale bitmaps (0=transparent, 255=opaque)
- Easy pixel access via
getPixel(x, y)with bounds checking - Proper glyph positioning with xOffset/yOffset for baseline alignment
- Direct mapping to LED coordinates for seamless integration
- Easy pixel access via
- Minimal API: Simple 3-step workflow - load font, create renderer, render glyphs
- Memory efficient: Shared font instances via
fl::shared_ptr, on-demand rendering - Platform agnostic: Works on all FastLED platforms with C++ support
- Example usage:
#include "fl/font/truetype.h" #include "fl/font/truetype.cpp.hpp" // Include ONCE auto font = fl::Font::loadDefault(); // Load embedded font fl::FontRenderer renderer(font, 10.0f); // 10px height fl::GlyphBitmap glyph = renderer.render('A'); // Render with AA // Draw to LED matrix for (int y = 0; y < glyph.height; ++y) { for (int x = 0; x < glyph.width; ++x) { uint8_t alpha = glyph.getPixel(x, y); // 0-255 // Blend alpha onto LED at (x + glyph.xOffset, y + glyph.yOffset) } }
- Unit tested: Comprehensive test suite with 303 lines covering font loading, metrics, glyph queries, bitmap rendering, and kerning
- Files:
- API: src/fl/font/truetype.h (185 lines)
- Implementation: src/fl/font/truetype.cpp.hpp (264 lines)
- Embedded font: src/fl/font/ttf_covenant5x5.cpp.hpp (657 lines, 9.9KB font data)
- stb_truetype: src/third_party/stb/truetype/stb_truetype.h (414 lines header, 5108 lines implementation)
- Tests: tests/fl/font/truetype.cpp
- NEW: WS2812B-V5 and WS2812B-Mini-V3 Chipset Support: Added support for newer WS2812B variants with tighter timing specifications
- WS2812B-V5: Newer variant with 220/580ns timing (T0H: 220-380ns, T1H: 580-1000ns)
- WS2812B-Mini-V3: Compact 3535 package with identical timing to V5
- Both variants use tighter timing tolerances compared to original WS2812B (250/625ns)
- Usage:
FastLED.addLeds<WS2812BV5, DATA_PIN, GRB>(leds, NUM_LEDS);orFastLED.addLeds<WS2812BMiniV3, DATA_PIN, GRB>(leds, NUM_LEDS); - Supported across all platforms with clockless controller support
- See timing comparison table in README.md
- NEW: Native RGBW Support Without Emulation: The following platforms now support true RGBW LED strips (SK6812, etc.) with hardware-native 4-channel output:
- RP2040/RP2350 (Raspberry Pi Pico): Full RGBW support with parallel output driver
- Supports mixed RGB/RGBW strips in same parallel group
- Automatic white channel handling via
setRgbw(RgbwDefault()) - Works with automatic parallel grouping (2/4/8-lane output)
- See commit e2fc7f6 and src/platforms/arm/rp/rpcommon/PARALLEL.md
- STM32: Native RGBW output on STM32 ARM platform
- Hardware-timed 4-channel output for SK6812 and similar RGBW chipsets
- No software emulation overhead
- See commit 2293b52 and src/platforms/arm/stm32/README.md
- Teensy 3.x Series: Native RGBW support added for Teensy 3.0/3.1/3.2/3.5/3.6
- Teensy 3.0/3.1/3.2 (ARM K20): Full 4-channel RGBW output
- Teensy 3.5/3.6 (ARM K66): Full 4-channel RGBW output
- Follows STM32 implementation pattern with unified loop and fixed-size buffer
- Automatic RGBW detection with no performance impact on RGB mode
- Files: src/platforms/arm/teensy/teensy31_32/clockless_arm_k20.h, src/platforms/arm/teensy/teensy36/clockless_arm_k66.h
- nRF52 (Nordic nRF52, Bluefruit boards): Native RGBW support via PWM peripheral
- 4-channel RGBW output using hardware PWM peripheral
- PWM buffer sized for maximum (RGBW), runtime selects RGB or RGBW mode
- Separate code paths for RGB (3 bytes) and RGBW (4 bytes) for optimal performance
- Supports up to 144 LEDs per string in RGBW mode
- File: src/platforms/arm/nrf52/clockless_arm_nrf52.h
- Note: Previous RGBW support via software emulation (ESP32, Teensy ObjectFLED) remains available
- RP2040/RP2350 (Raspberry Pi Pico): Full RGBW support with parallel output driver
- NEW: HD108/NS108 16-bit SPI Chipset Support: High-definition LED chipset with built-in gamma correction
- 16-bit color depth (65,536 levels per channel) vs APA102's 8-bit (256 levels)
- Automatic gamma correction (gamma 2.8) provides smooth perceptual brightness transitions
- Higher PWM frequency (27 kHz) reduces visible flicker compared to APA102's ~20 kHz
- 5-bit brightness control (0-31) per LED for current limiting
- 40 MHz max clock speed (25 MHz default for stable operation on long strips)
- Dual-byte header encoding for brightness/current control
- Manufacturer: Newstar LED (NS108 = HD108, same chip)
- Protocol: APA102-like but extended to 16-bit with 8 bytes per LED
- Start frame: 64 bits (8 bytes)
- LED frame: 2 header bytes + 6 data bytes (16-bit RGB, big-endian)
- End frame: (num_leds / 2) + 4 bytes of 0xFF
- Usage:
FastLED.addLeds<HD108, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); - Implementation: Enhanced showPixels() with brightness caching and optimized gamma correction
- No SD (standard definition) option available - all HD108s use gamma correction
- See detailed protocol documentation in src/chipsets.h:1040-1183
- Unit tests: Comprehensive test suite in tests/chipsets/test_hd108.cpp
- Related: GitHub Issue #1045, Pull Request #2119 (thanks to @arfoll for initial implementation)
- NEW: Vorbis Audio Decoder: Added support for decoding Ogg Vorbis audio files via stb_vorbis integration
- Streaming Decoder:
VorbisDecoderclass provides frame-by-frame audio decoding from ByteStream - Convenience API:
Vorbis::decodeAll()decodes entire files to AudioSample vectors in one call - Metadata Parsing:
Vorbis::parseVorbisInfo()extracts sample rate, channels, and stream info without full decoding - Float PCM Output: Decodes to floating-point audio samples (-1.0 to 1.0 range) compatible with FastLED audio processing
- Low-Level Wrapper:
StbVorbisDecoderprovides direct access to stb_vorbis for advanced use cases - Memory-Based: Requires entire Vorbis file in memory (suitable for embedded audio playback)
- Platform Support: Works on all platforms with sufficient memory for audio buffers
- Third-Party Integration: Uses Sean Barrett's stb_vorbis single-header library
- Usage:
auto decoder = Vorbis::createDecoder(); decoder->begin(byteStream); decoder->decodeNextFrame(&sample); - See API documentation ...
- Streaming Decoder:
FastLED 3.10.4
FastLED 3.10.4
Bumps the bundled zccache floor to >=1.12.7 to pick up zackees/zccache#763, which version-namespaces the cache root and closes the version-shadow chain at zackees/zccache#762.
Practically: side-by-side installs (e.g. PyPI + bundled fbuild copies) no longer trample each other's daemon state, fixing the silent mid-build daemon death reported in zackees/zccache#759 and the 1.12.6 self-hash regression in zackees/zccache#760.
No FastLED source code changes — Arduino API and runtime behaviour are identical to 3.10.3.
FastLED 3.10.3: W2812 timing update - stm32F4 board support
- WS2812B Reset Time Update: Enhanced compatibility with newer WS2812B chipsets
- Updated default reset time from 50μs to 280μs across all platforms
- Fixes intermittent issues where only first LED responds to
fill_solid()and similar operations - Addresses GitHub issue #2067: WS2812B strips showing ~80% failure rate with latest FastLED
- Updated 18 ARM platform clockless controllers (Apollo3, STM32, SAMD, Teensy, etc.)
- ESP8266 clockless controller timing updated for better reliability
- Maintains backward compatibility while supporting newer WS2812B chip revisions
- STM32F4 Support Added: BlackPill STM32F411CE and STM32F4 family support
- Added STM32F4 platform detection using canonical
STM32F4preprocessor define - Full GPIO pin mapping support for WeAct Studio BlackPill V2.0 (STM32F411CE)
- Consolidated STM32F1/STM32F4 pin definitions to reduce code duplication
- Added CI testing with GitHub Actions build badge for continuous validation
- Compatible with PlatformIO
ststm32platform and Arduino framework
- Added STM32F4 platform detection using canonical
- Silicon Labs MGM240 Support Added: Arduino Nano Matter and SparkFun Thing Plus Matter support
- Resolves GitHub issue #1750: Platform support for MGM240 (EFR32MG24) wireless modules
- Added complete platform implementation with ARM Cortex-M33 @ 78MHz support
- Silicon Labs EMLIB integration for optimized GPIO control and clock management
- Clockless LED controller support for WS2812, SK6812, and other standard chipsets
- Board definitions for
mgm240target withsiliconlabsefm32platform - Added CI testing with GitHub Actions build badge for continuous validation
For a compile environment please see https://github.com/fastled/platformio-starter
FastLED 3.10.2
Fastled.3.10.2-1.mp4
FastLED 3.10.2
- CORKSCREW MAPPING!
- Want to create a light saber or festival stick? Before your options were to have vertical strips.
- Now you can use a corkscrew mapping fl/corkscrew.h, see examples/FestivalStick
- You input the number of LEDS + number of turns.
- Corkscrew will provide a surface XY grid that you draw too.
- then call Corkscrew::draw(), and the current surface will be mapped to the corkscrew.
- Rendering is done via 2x2 bilinear sampling. Looks great!
- Animartrix - 30% faster due to forced
-O3andfastmathcompiler settings for this one file. - Ease Functions - lots and lots of ease functions! Great for animations!
- see fl/ease.h and the demo examples/Ease/Ease.ino
- Fast! Everything is done in integer space.
- 3D Perlin noise (
inoise8(x, y, z)) range utilization improved from 72.9% to 88.6%- Significantly better quality for volumetric LED effects (3D fire, clouds, particles)
- Uses industry-standard 12 edge vectors of a cube for optimal gradient coverage
- Adafruit NeoPixel Bridge: Optional Adafruit_NeoPixel clockless controller support
- For some platforms Adafruits NeoPixel just works better.
- Enable with
#define FASTLED_USE_ADAFRUIT_NEOPIXELbefore including FastLED - Now your WS2812 chipset will use the AdafruitNeopixel library (if installed)
- New LED chipset: SM16824E
- 3-Wire
- See also: #1941 (comment)
- apollo3_red (stm variant): beta support.
- HSV16 support
- CRGB -> HSV -> CRGB is highly lossy
- CRGB -> HSV16 -> CRGB is almost perfect.
- Integer based so it's fast.
- ColorBoost
- CRGB::colorBoost()
- Are you doing video on WS2812? Well then you probably are using gamma correction
- Color Boost is an alternative for gamma correction for the WS2812 and other RGB8 chipsets.
- It preserves luminosity but allows you to increase saturation.
- HSV16 is used to preserve color resolution.
- HSV -> CRGB default conversion function can now be overriden.
- Thanks to https://github.com/ssilverman or this full spectrum HSV implementation.
- If you just want to change it for your sketch you can use this:
#define FASTLED_HSV_CONVERSION_RAINBOW(default)#define FASTLED_HSV_CONVERSION_SPECTRUM#define FASTLED_HSV_CONVERSION_FULL_SPECTRUM- To change for the entire engine (recommended) then set these as build flags:
-DFASTLED_HSV_CONVERSION_RAINBOW-DFASTLED_HSV_CONVERSION_SPECTRUM-FASTLED_HSV_CONVERSION_FULL_SPECTRUM
- fl/fetch.h
- A non blocking http fetch library returning an fl/promise.h
- You can then await the promise with
fl::awaitor install a callback to be invoked. The latter is recommended.
- fl/json.h rewrite
- Much more ergonic library. Fast parsing for packed arrays of number
- The underlying ArduinoJson library is only ergonomic if you allow
std:stringandstd::sstream, which is missing on platforms like avr. So we had to write our own api to handle this.
- Platforms
- ESP32-C5 is now supported.
- ESP32 WS2812 SPI driver has a fix for it's async draw routine.
- Blend2d will now replace a subfx XYMap (when necessary) to prevent double mapping. A warning will be issued.
- Seeed XIAO nRF52840 Sense: Fixed incorrect pin mappings that were copied from Adafruit Feather board
- APA102HD Gamma Correction Algorithm: Completely rewritten with closed-form mathematical solution
- Thanks https://github.com/gwgill!
- Graph of the old algorithms quantization issues can be see here:
- STM32F1 pin mapping fixes (blue pill)
- #1973
- Thanks https://github.com/vishwamartur!
- Internal stuff
- FastLED is now way more strict in it's compiler settings. Warnings are treated as errors
- Lots of fixes, some code required amnesty.
- The examples now compile under clang and run for
./test - All examples now compile for ALL platforms.
- this was a major undertaking.
- required a rewrite of the testing infrastructure.
- Teensy41 took ~ 1 hours to compile 40 examples, now it can do 80 examples in ~8 mins
- FastLED is now way more strict in it's compiler settings. Warnings are treated as errors
3.10.1 - Bug Fix for 3.10.0
- Fix for Esp32s3 - Improvement to code caused DMA mode was set to true, breaking RMT5
- Examples fix
- Some problematic headers were pulled in that conflicts with Arduino.h, these have been fixed
- SKETCH_HAS_LOTS_OF_MEMORY was being tested before
#include "FastLED.h"fixed
FastLED 3.10.0 Released - Animartrix, ESP32-P4, ESP32-S3 I2S improvements
fastled_3_10_animartrix_small.mp4
- Animartrix now out of beta.
- examples/Animartrix/Animartrix.ino
- ESP32
- Esp32P4 now officially supported.
- ESP32-S3 I2S driver is improved
- It will now auto error on known bad Esp32-Arduino Core versions.
- Arudino core 3.2.0 is now know to work.
- Documentation has been greatly simplified and unnecessary steps have been removed.
- It will now auto error on known bad Esp32-Arduino Core versions.
Full Changelog: 3.9.20...3.10.0
3.9.20: Misc Fixes
Optional upgrade. Fixes fadeByLight not being in the global namespace. This fixes a regression that happened in 3.9.17.
Full Changelog: 3.9.19...3.9.20
Hot Fix #2 for 3.9.17
For more information see this bug fix thread.
It turns out the older AVR gcc compilers will not eliminate complex static objects that are not referenced. However it seems it will eliminate them if they are in statics inside static functions, like this:
This will unconditionally initialize in avr-gcc at startup, but be removed in more modern toolchains.
typedef fl::hash_map<Key, Value> HashMap;
static HashMap gStatic;
This however, will be removed in avr-gcc and others
static HashMap& get_static() {
static HashMap s_static;
return s_static;
}
Here is a Chat GPT Summary:
🔍 Summary:
-
AVR-GCC does not aggressively eliminate unused static non-POD objects — even if they appear to be unused — because:
- It lacks certain modern optimizations (especially LTO-level optimizations).
- It typically relies on the
.ctorssection to ensure initialization of static objects with constructors. - By default, objects with static storage duration and non-trivial constructors get registered for initialization via
.ctorsand the linker keeps them.
-
Modern Clang and GCC (non-AVR) will remove these if they are not referenced and the constructors are not marked in a way that ensures their side effects are preserved.
🔧 Arduino Build Settings
In the Arduino build system (typically using avr-gcc):
- Link-Time Optimization (LTO) is often disabled by default for compatibility. Without LTO, the compiler doesn't see across translation units and is less aggressive about removing "unused" symbols.
- Static initializers are kept because they're registered in the
.ctorssection which the startup code walks through during initialization. - If you're using Arduino CLI or PlatformIO with LTO enabled (
-flto), you may start seeing more Clang/GCC-like elision behavior if you're not careful.
🔒 Why static constructors aren’t elided (AVR-specific reasons)
- AVR
libc(avr-libc) startup code explicitly calls global/static constructors via__do_global_ctors. - The compiler places constructors into
.ctorssection using.section .ctors+.initNpriorities. - These sections are preserved unless explicitly dropped or optimized out with aggressive LTO.
✅ To Preserve in Modern Toolchains
In more aggressive modern toolchains (Clang/GCC with LTO):
- Use
__attribute__((used))orvolatileglobals if you want to force retention. - Or rely on
__attribute__((constructor))for function-level hooks that are less likely to be optimized out.
👇 Example
struct AutoRun {
AutoRun() { Serial.println("I ran!"); }
};
static AutoRun my_auto_run; // Kept by AVR-GCC, likely dropped by Clang w/LTOTo preserve it in Clang:
__attribute__((used)) static AutoRun my_auto_run;✅ Conclusion
This is an AVR-GCC behavior, not strictly Arduino's doing — but Arduino's default settings do reinforce this behavior by avoiding LTO and preserving .ctors invocations. Modern toolchains need extra care to keep static initializers with side effects.
Bug fix - hot fix!
- Reverted AVR memory blow up
- Fix odd even bug on leds on avr
FastLED 3.9.17 - stdlib compatibility, audio preview, xypath
This release has a few bug fixes in it and some internal refactorings that has been on my to-do list for a while. The next release will have more features and less core changes.
FastLED now has a small subset of std:: data structures. This allows complex code ingest from open source which rely on things like std::vector<>, hashmaps and others. Unlike other micro stdlib attempts, this one actually compiles everywhere thanks to our ~50 testing configurations that we run on each change committed to the repo.
These std data structures were used to create complex rendering functions xypaths that look absolutely jaw dropping.
However in this release my attention got pulled into about four different directions. Audio and xypaths were added to the core, but the examples were prunned for this release, in order to get this release out in a timely manner.
What's all the noise about lines and rasterization in this release?
You ever try to draw a point or a line on a LED matrix? By default it looks awful. As the point particle moves it lights up one led index at a time. It's tricky to make this transition look smooth. Drawing beautiful lines on matrices requires pixel-neighboring calculations in order to correctly blend into a low resolution strip/matrix. And that's what most of the new math you see below is about.. Take a point in float(x,y) and then color a tile of 2x2 pixels, or 2x1 if you are in a strip.
Happy coding!
Change list
- esp
- esp-idf v5.4 fixes to include lcd_50
- #1924
- Thanks! https://github.com/rommo911
- RMT5 will now respect DMA_MODE=DMA_ENABLED
- Default is still off.
- #1927
s.
- datastructures
- FastLED now has it's own subset of std lib. fl::vector<>, fl::hash_map<> etc so you can bring in external code to your sketches easily and have it still be cross platform compatible. Our std lib subset is backed by a fleet of platform testers so it compiles and works everywhere. Will this increase the AVR and other small memory footprints? No, we have strict checks for these platforms and compile size remains the same.
- fl::hash_map
- open addressing but with inlined rehashing when "tombstones" fill up half the slots.
- fl::hash_map_inlined
- fl::hash_set
- fl::vector
- fl::vector_inlined
- fl::function<>
- fl::variant<T,...>
- fl::optional
- esp-idf v5.4 fixes to include lcd_50
- graphics
- CRGB::downscale(...) for downsizing led matrices / strips.
- Essentially pixel averaging.
- Uses a fastpath when downsizeing from M by N to M/2 by N/2.
- Uses fixed-integer fractional downsizing when the destination matrix/strip is any other ratio.
- CRGB::upscale(...) for expanding led matrices / strips, uses bilinear expansion.
- XYPath (Work in progress):
- Create paths that smoothly interpolate in response to animation values => [0, 1.0f]
- Still a work in progress.
- Subpixel calculations.
- Let's face it, low resolution matrices and strips produce bad results with simple pixel rendering in integer space. I've implemented the ability for using floating point x,y coordinates and then splatting that pixel to a 2x2 tile. If a point is dead center on a led then only that led in the tile will light up, but if that point moves then other neighboring leds will start to light up in proportion to the overlap. This gives 256 effective steps in the X and Y directions between neightbors. This greatly improves visual quality without having to super sample.
- Line Simplification
- Take a line with lots of points and selectively remove points that
have the least impact on the line, keeping the overall shape. We use an improved Douglas-Peucker algorithm that is memory efficient. We also have a version that is more cpu intensive which will will hit a target number of vertices.
- Take a line with lots of points and selectively remove points that
- RasterSparse: efficient rendering to an intermediate buffer that only allocates x,y points for values actually written, then flush to LED matrix/strip. See below for more information.
- traverseGridSegment
- Given a line A-B, find all the intersecting cells on a grid.
- Essentially 2D ray tracing.
- Great for optimization of particle trails and rastering an entire XYPath.
- Example:
- Full XYPath (e.g. Heart) renders 200 xy points
- Use line simplification to reduce this to 50 most significant points -> 49 line segments
- For each line segment
- traverseGridSegment computes all the intersecting grid points
- for each grid point find the closest point on the segment, call it closest-pt
- closet-pt generates a tile2x2 of itself plus it's 3 neighbors
- for each tile2x2 it will have a uint8_t value representing it's intensity / closeness to center.
- tile2x2 list/stream -> raster (RasterSparse)
- raster -> composite to LED matrix/strip using a gradient or draw functor.
- closet-pt generates a tile2x2 of itself plus it's 3 neighbors
- for each grid point find the closest point on the segment, call it closest-pt
- traverseGridSegment computes all the intersecting grid points
- Example:
- RasterSparse
- A memory efficient raster that elements like the XYPath can write to as an intermediate step to writing to the display LEDs. This allows layering: very important for creating things like "particle trails" which require multiple writing to similar pixels destructively and then flushed to the LED display. For example if a particle has a long fade trail with say 30 points of history, then this entire path can be destructively drawn to the raster then composited to the led display as an unified layer.
- "Sparse" in "RasterSparse" here means that the x,y values of the pixels being written to are stored in a hash table rather than a spanning grid. This greatly reduces memory usage and improves performance. To prevent excessive computation with hashing, a small 8-unit inlined hash_table with a FastHash function is carefully used to exploit the inherent locality of computing particle and paths.
- Right now, RasterSparse is only implemented for uint8_t values and not an entire CRGB pixel, as CRGB values are typically computed via an algorithm during the compositing process. For example a gradient function can take a rasterized particle trail and apply coloring.
- LineMath
- Take a line A-B and calculate the closest distance from the line to a point P. This is important to optimize rendering if oversampling takes too much CPU.
- CRGB::downscale(...) for downsizing led matrices / strips.

