Concept by Stefan Petrick.
Concept by Stefan Petrick. Emitters inject color onto a float-precision 2D grid, then a noise-driven flow field advects (transports) those colors with bilinear interpolation, creating emergent fluid-like patterns.
Original C++ implementation by 4wheeljive (ColorTrails project). Distilled into a self-contained FastLED example.
This sketch is fully compatible with the FastLED web compiler. To use it:
#include <FastLED.h>
#define WIDTH 64
#define HEIGHT 64
#define NUM_LEDS (WIDTH * HEIGHT)
#define DATA_PIN 2
#define BRIGHTNESS 255
#define SERPENTINE true
"Flow field visualization with noise-driven advection, creating fluid-like patterns from color emitters. "
"Concept by Stefan Petrick, Initial C++ implementation by 4wheeljive. FastLED port adaptation + fixed point "
"optmization by Zach Vorhies."
);
}
bool pickX = random8() < 128;
float sign = (random8() < 128) ? 1.0f : -1.0f;
if (pickX) {
float cx = random8(0, fx.getWidth());
float w = fx.getWidth() * 0.4f;
fx.noisePunchX(cx, w, sign);
} else {
float cy = random8(0, fx.getHeight());
float h = fx.getHeight() * 0.4f;
fx.noisePunchY(cy, h, sign);
}
}
}
fl::UIDescription description("Demo of the Animatrix effects. @author of fx is StefanPetrick")
fl::UITitle title("Animartrix")
FL_DISABLE_WARNING_PUSH FL_DISABLE_WARNING_GLOBAL_CONSTRUCTORS CFastLED FastLED
Global LED strip management instance.
fl::UISlider flowSpeedY("Y Speed", 0.10f, -2.0f, 2.0f, 0.01f)
fl::UIGroup appearanceGroup("Appearance", endpointSpeed, colorShift, persistence, flowShift, numDots, emitterMode)
fl::UIGroup flowXGroup("Flow X", flowSpeedX, flowAmpX, flowFreqX)
fl::UICheckbox showFlowVectors("Show Flow Vectors", false)
fl::UISlider flowAmpY("Y Amplitude", 1.0f, 0.0f, 2.0f, 0.01f)
fl::UIGroup debugGroup("Debug", computeMode, showFlowVectors)
fl::UISlider flowFreqX("X Frequency", 0.33f, 0.05f, 4.0f, 0.01f)
fl::UISlider flowAmpX("X Amplitude", 1.0f, 0.0f, 2.0f, 0.01f)
fl::UIButton noisePunch("NoisePunch")
fl::UIDropdown emitterMode("Emitter Mode", {"Lissajous", "Dots", "Both"})
fl::FlowFieldFloat flowFieldFloat(xyMap)
fl::UISlider numDots("Dots", 3, 1, 5, 1)
fl::UISlider flowFreqY("Y Frequency", 0.32f, 0.05f, 4.0f, 0.01f)
fl::UISlider endpointSpeed("Endpoint Speed", 0.80f, 0.05f, 2.0f, 0.01f)
fl::UISlider colorShift("Color Shift", 0.04f, 0.0f, 0.5f, 0.01f)
fl::UISlider flowShift("Pixel Shift", 1.8f, 0.5f, 4.0f, 0.1f)
fl::UIGroup flowYGroup("Flow Y", flowSpeedY, flowAmpY, flowFreqY)
fl::UISlider persistence("Trail Half-Life (s)", 0.86f, 0.05f, 5.0f, 0.01f)
fl::UIDropdown computeMode("Compute Mode", {"Float", "Fixed-Point (Fast)"})
fl::UISlider flowSpeedX("X Speed", 0.10f, -2.0f, 2.0f, 0.01f)
fl::FlowFieldFP flowFieldFP(xyMap)
void setColorShift(float speed)
void setFlowSpeedX(float speed)
void setFlowSpeedY(float speed)
void setNoiseFrequencyX(float freq)
void setEndpointSpeed(float speed)
void setDotCount(int count)
void setPersistence(float halfLife)
void setFlowAmplitudeX(float amp)
void draw(DrawContext context) override
Handles timing, then delegates to drawImpl().
void setFlowShift(float shift)
void setNoiseFrequencyY(float freq)
void setEmitterMode(int mode)
void setShowFlowVectors(bool show)
void setFlowAmplitudeY(float amp)
Pure fixed-point (s16x16) flow field implementation for maximum speed.
Float-precision flow field implementation.
Abstract base class for 2D flow field effects.
::fl::DrawContext DrawContext
2D flow field visualization: emitters paint color, noise advects it
fl::u32 millis()
Universal millisecond timer - returns milliseconds since system startup.
Base definition for an LED controller.
Aggregator header for the fl/ui/ family of per-element UI types.