Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Effect blending styles #3877

Closed
wants to merge 41 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
0c8d9d5
Mode blending styles
blazoncek Apr 3, 2024
f5199d2
Fix compile.
blazoncek Apr 3, 2024
c680527
Merge branch '0_15' into blending-styles
blazoncek Apr 8, 2024
a3a8fa1
Remove conditional fade/blend
blazoncek Apr 8, 2024
b3810a1
Merge branch '0_15' into blending-styles
blazoncek Apr 9, 2024
ef017fd
Revert FX.cpp
blazoncek Apr 14, 2024
9735d1c
Merge branch '0_15' into blending-styles
blazoncek Apr 14, 2024
8e8ffa3
Merge branch '0_15' into blending-styles
blazoncek Apr 26, 2024
f441ce9
Merge branch '0_15' into blending-styles
blazoncek May 12, 2024
ccce0f2
Merge branch '0_15' into blending-styles
blazoncek May 15, 2024
de5632b
Merge branch '0_15' into blending-styles
blazoncek Jun 1, 2024
20c0916
Merge branch '0_15' into blending-styles
blazoncek Jun 2, 2024
da484b0
Use transition style for palette and color change
blazoncek Jun 2, 2024
296df26
Merge branch '0_15' into blending-styles
blazoncek Jun 16, 2024
a4ac444
Merge branch '0_15' into blending-styles
blazoncek Jun 23, 2024
bee75a4
Hide 2D blending styles on non-2D set-up
blazoncek Jun 23, 2024
593970e
Merge branch '0_15' into blending-styles
blazoncek Jun 30, 2024
f3891c3
Merge branch '0_15' into blending-styles
blazoncek Jul 5, 2024
0275bd1
On/Off blending respected
blazoncek Jul 5, 2024
13ed78b
Merge branch '0_15' into blending-styles
blazoncek Jul 11, 2024
d88bb3c
Merge branch '0_15' into blending-styles
blazoncek Jul 18, 2024
1975c9c
Merge branch '0_15' into blending-styles
blazoncek Jul 24, 2024
c03422e
Push variants
blazoncek Jul 30, 2024
365c198
Missing clipping fix
blazoncek Aug 1, 2024
e1598a9
Merge branch '0_15' into blending-styles
blazoncek Aug 5, 2024
77723b6
Fix compiler warning
blazoncek Aug 8, 2024
011afd0
Merge branch '0_15' into blending-styles
blazoncek Aug 17, 2024
0430dc5
Merge branch '0_15' into blending-styles
blazoncek Aug 17, 2024
434ba3f
Added FX to copy a segment in 1D or 2D
DedeHai Aug 28, 2024
ebd8a10
Prevent styles on 1px segments
blazoncek Sep 3, 2024
24df6bf
Added copying source settings
DedeHai Sep 4, 2024
696f74b
Update integrating new ideas as discussed
DedeHai Sep 7, 2024
1e0ceab
Merge remote-tracking branch 'upstream/0_15' into 0_15_copy_segment
DedeHai Sep 7, 2024
8aa82ab
fixes and optimizations
DedeHai Sep 8, 2024
dd8353a
moved getRenderedPixelXY() into SEGMENT class, plus little improvement
DedeHai Sep 9, 2024
1cee1c3
Merge branch '0_15' into blending-styles
blazoncek Sep 11, 2024
ce5ee65
Merge branch '0_15' into blending-styles
blazoncek Sep 15, 2024
bdd8747
Merge remote-tracking branch 'upstream/0_15' into 0_15_copy_segment
DedeHai Sep 22, 2024
df33a36
rgb2hsv now returns the CHSV value instead of using a reference
DedeHai Sep 22, 2024
7db1adc
added forgotten returnvalue
DedeHai Sep 22, 2024
60ea7ce
Merge branch '015_copy_segment_blendingstyles' into blending-styles
DedeHai Sep 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
## WLED changelog

#### Build 2404050
- Blending styles (with help from @tkadauke)

#### Build 2403280
- Individual color channel control for JSON API (fixes #3860)
- "col":[int|string|object|array, int|string|object|array, int|string|object|array]
Expand Down
2 changes: 1 addition & 1 deletion usermods/stairway_wipe_basic/stairway-wipe-usermod-v2.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ void setup() {
jsonTransitionOnce = true;
strip.setTransition(0); //no transition
effectCurrent = FX_MODE_COLOR_WIPE;
resetTimebase(); //make sure wipe starts from beginning
strip.resetTimebase(); //make sure wipe starts from beginning

//set wipe direction
Segment& seg = strip.getSegment(0);
Expand Down
111 changes: 0 additions & 111 deletions usermods/stairway_wipe_basic/wled06_usermod.ino

This file was deleted.

61 changes: 31 additions & 30 deletions wled00/FX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1211,28 +1211,29 @@ static const char _data_FX_MODE_COMET[] PROGMEM = "Lighthouse@!,Fade rate;!,!;!"
*/
uint16_t mode_fireworks() {
if (SEGLEN == 1) return mode_static();
const uint16_t width = SEGMENT.is2D() ? SEGMENT.virtualWidth() : SEGMENT.virtualLength();
const uint16_t height = SEGMENT.virtualHeight();
const unsigned width = SEGMENT.is2D() ? SEGMENT.virtualWidth() : SEGMENT.virtualLength();
const unsigned height = SEGMENT.virtualHeight();
const unsigned dimension = width * height;

if (SEGENV.call == 0) {
SEGENV.aux0 = UINT16_MAX;
SEGENV.aux1 = UINT16_MAX;
}
SEGMENT.fade_out(128);

bool valid1 = (SEGENV.aux0 < width*height);
bool valid2 = (SEGENV.aux1 < width*height);
uint8_t x = SEGENV.aux0%width, y = SEGENV.aux0/width; // 2D coordinates stored in upper and lower byte
bool valid1 = (SEGENV.aux0 < dimension);
bool valid2 = (SEGENV.aux1 < dimension);
unsigned x = SEGENV.aux0%width, y = SEGENV.aux0/width; // 2D coordinates stored in upper and lower byte
uint32_t sv1 = 0, sv2 = 0;
if (valid1) sv1 = SEGMENT.is2D() ? SEGMENT.getPixelColorXY(x, y) : SEGMENT.getPixelColor(SEGENV.aux0); // get spark color
if (valid2) sv2 = SEGMENT.is2D() ? SEGMENT.getPixelColorXY(x, y) : SEGMENT.getPixelColor(SEGENV.aux1);
if (!SEGENV.step) SEGMENT.blur(16);
if (!SEGENV.step) SEGMENT.blur(dimension > 100 ? 16 : 8);
if (valid1) { if (SEGMENT.is2D()) SEGMENT.setPixelColorXY(x, y, sv1); else SEGMENT.setPixelColor(SEGENV.aux0, sv1); } // restore spark color after blur
if (valid2) { if (SEGMENT.is2D()) SEGMENT.setPixelColorXY(x, y, sv2); else SEGMENT.setPixelColor(SEGENV.aux1, sv2); } // restore old spark color after blur

for (int i=0; i<max(1, width/20); i++) {
for (unsigned i=0; i<max(1U, width/20); i++) {
if (random8(129 - (SEGMENT.intensity >> 1)) == 0) {
uint16_t index = random16(width*height);
unsigned index = random16(dimension);
x = index % width;
y = index / width;
uint32_t col = SEGMENT.color_from_palette(random8(), false, false, 0);
Expand Down Expand Up @@ -2066,41 +2067,41 @@ uint16_t mode_fire_2012() {
struct virtualStrip {
static void runStrip(uint16_t stripNr, byte* heat, uint32_t it) {

const uint8_t ignition = max(3,SEGLEN/10); // ignition area: 10% of segment length or minimum 3 pixels
const unsigned ignition = max(3,SEGLEN/10); // ignition area: 10% of segment length or minimum 3 pixels

// Step 1. Cool down every cell a little
for (int i = 0; i < SEGLEN; i++) {
uint8_t cool = (it != SEGENV.step) ? random8((((20 + SEGMENT.speed/3) * 16) / SEGLEN)+2) : random8(4);
uint8_t minTemp = (i<ignition) ? (ignition-i)/4 + 16 : 0; // should not become black in ignition area
uint8_t temp = qsub8(heat[i], cool);
for (unsigned i = 0; i < SEGLEN; i++) {
unsigned cool = (it != SEGENV.step) ? random8((((20 + SEGMENT.speed/3) * 16) / SEGLEN)+2) : random8(4);
unsigned minTemp = (i<ignition) ? (ignition-i)/4 + 16 : 0; // should not become black in ignition area
unsigned temp = qsub8(heat[i], cool);
heat[i] = temp<minTemp ? minTemp : temp;
}

if (it != SEGENV.step) {
// Step 2. Heat from each cell drifts 'up' and diffuses a little
for (int k = SEGLEN -1; k > 1; k--) {
for (unsigned k = SEGLEN -1; k > 1; k--) {
heat[k] = (heat[k - 1] + (heat[k - 2]<<1) ) / 3; // heat[k-2] multiplied by 2
}

// Step 3. Randomly ignite new 'sparks' of heat near the bottom
if (random8() <= SEGMENT.intensity) {
uint8_t y = random8(ignition);
uint8_t boost = (17+SEGMENT.custom3) * (ignition - y/2) / ignition; // integer math!
unsigned y = random8(ignition);
unsigned boost = (17+SEGMENT.custom3) * (ignition - y/2) / ignition; // integer math!
heat[y] = qadd8(heat[y], random8(96+2*boost,207+boost));
}
}

// Step 4. Map from heat cells to LED colors
for (int j = 0; j < SEGLEN; j++) {
SEGMENT.setPixelColor(indexToVStrip(j, stripNr), ColorFromPalette(SEGPALETTE, MIN(heat[j],240), 255, NOBLEND));
SEGMENT.setPixelColor(indexToVStrip(j, stripNr), ColorFromPalette(SEGPALETTE, MIN(heat[j],240), 255, LINEARBLEND_NOWRAP));
}
}
};

for (int stripNr=0; stripNr<strips; stripNr++)
for (unsigned stripNr=0; stripNr<strips; stripNr++)
virtualStrip::runStrip(stripNr, &heat[stripNr * SEGLEN], it);

if (SEGMENT.is2D()) SEGMENT.blur(32);
if (SEGMENT.is2D()) SEGMENT.blur((SEGMENT.virtualWidth()*SEGMENT.virtualHeight()) > 100 ? 32 : 0);

if (it != SEGENV.step)
SEGENV.step = it;
Expand Down Expand Up @@ -4856,9 +4857,9 @@ static const char _data_FX_MODE_FLOWSTRIPE[] PROGMEM = "Flow Stripe@Hue speed,Ef
uint16_t mode_2DBlackHole(void) { // By: Stepko https://editor.soulmatelights.com/gallery/1012 , Modified by: Andrew Tuline
if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up

const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t rows = SEGMENT.virtualHeight();
uint16_t x, y;
const unsigned cols = SEGMENT.virtualWidth();
const unsigned rows = SEGMENT.virtualHeight();
unsigned x, y;

SEGMENT.fadeToBlackBy(16 + (SEGMENT.speed>>3)); // create fading trails
unsigned long t = strip.now/128; // timebase
Expand All @@ -4877,7 +4878,7 @@ uint16_t mode_2DBlackHole(void) { // By: Stepko https://editor.soulma
// central white dot
SEGMENT.setPixelColorXY(cols/2, rows/2, WHITE);
// blur everything a bit
SEGMENT.blur(16);
SEGMENT.blur(sqrt16(cols*rows) > 100 ? 16 : 0);

return FRAMETIME;
} // mode_2DBlackHole()
Expand Down Expand Up @@ -6436,8 +6437,8 @@ static const char _data_FX_MODE_2DSWIRL[] PROGMEM = "Swirl@!,Sensitivity,Blur;,B
uint16_t mode_2DWaverly(void) {
if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up

const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t rows = SEGMENT.virtualHeight();
const unsigned cols = SEGMENT.virtualWidth();
const unsigned rows = SEGMENT.virtualHeight();

um_data_t *um_data;
if (!usermods.getUMData(&um_data, USERMOD_ID_AUDIOREACTIVE)) {
Expand All @@ -6449,21 +6450,21 @@ uint16_t mode_2DWaverly(void) {
SEGMENT.fadeToBlackBy(SEGMENT.speed);

long t = strip.now / 2;
for (int i = 0; i < cols; i++) {
uint16_t thisVal = (1 + SEGMENT.intensity/64) * inoise8(i * 45 , t , t)/2;
for (unsigned i = 0; i < cols; i++) {
unsigned thisVal = (1 + SEGMENT.intensity/64) * inoise8(i * 45 , t , t)/2;
// use audio if available
if (um_data) {
thisVal /= 32; // reduce intensity of inoise8()
thisVal *= volumeSmth;
}
uint16_t thisMax = map(thisVal, 0, 512, 0, rows);
unsigned thisMax = map(thisVal, 0, 512, 0, rows);

for (int j = 0; j < thisMax; j++) {
for (unsigned j = 0; j < thisMax; j++) {
SEGMENT.addPixelColorXY(i, j, ColorFromPalette(SEGPALETTE, map(j, 0, thisMax, 250, 0), 255, LINEARBLEND));
SEGMENT.addPixelColorXY((cols - 1) - i, (rows - 1) - j, ColorFromPalette(SEGPALETTE, map(j, 0, thisMax, 250, 0), 255, LINEARBLEND));
}
}
SEGMENT.blur(16);
SEGMENT.blur(sqrt16(cols*rows) > 100 ? 16 : 0);

return FRAMETIME;
} // mode_2DWaverly()
Expand Down
7 changes: 2 additions & 5 deletions wled00/FX.h
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,7 @@ typedef struct Segment {
inline void setPixelColor(float i, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0, bool aa = true) { setPixelColor(i, RGBW32(r,g,b,w), aa); }
inline void setPixelColor(float i, CRGB c, bool aa = true) { setPixelColor(i, RGBW32(c.r,c.g,c.b,0), aa); }
#ifndef WLED_DISABLE_MODE_BLEND
inline void setClippingRect(int startX, int stopX, int startY = 0, int stopY = 1) { _clipStart = startX; _clipStop = stopX; _clipStartY = startY; _clipStopY = stopY; };
static inline void setClippingRect(int startX, int stopX, int startY = 0, int stopY = 1) { _clipStart = startX; _clipStop = stopX; _clipStartY = startY; _clipStopY = stopY; };
#endif
bool isPixelClipped(int i);
uint32_t getPixelColor(int i);
Expand Down Expand Up @@ -708,9 +708,7 @@ class WS2812FX { // 96 bytes
public:

WS2812FX() :
paletteFade(0),
paletteBlend(0),
cctBlending(0),
now(millis()),
timebase(0),
isMatrix(false),
Expand Down Expand Up @@ -792,6 +790,7 @@ class WS2812FX { // 96 bytes
addEffect(uint8_t id, mode_ptr mode_fn, const char *mode_name), // add effect to the list; defined in FX.cpp
setupEffectData(void); // add default effects to the list; defined in FX.cpp

inline void resetTimebase() { timebase = 0U - millis(); }
inline void restartRuntime() { for (Segment &seg : _segments) seg.markForReset(); }
inline void setTransitionMode(bool t) { for (Segment &seg : _segments) seg.startTransition(t ? _transitionDur : 0); }
inline void setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0) { setColor(slot, RGBW32(r,g,b,w)); }
Expand All @@ -806,7 +805,6 @@ class WS2812FX { // 96 bytes
inline void resume(void) { _suspend = false; } // will resume strip.service() execution

bool
paletteFade,
checkSegmentAlignment(void),
hasRGBWBus(void),
hasCCTBus(void),
Expand All @@ -822,7 +820,6 @@ class WS2812FX { // 96 bytes

uint8_t
paletteBlend,
cctBlending,
getActiveSegmentsNum(void),
getFirstSelectedSegId(void),
getLastActiveSegmentId(void),
Expand Down
10 changes: 5 additions & 5 deletions wled00/FX_2Dfcn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,10 +176,10 @@ bool IRAM_ATTR Segment::isPixelXYClipped(int x, int y) {
if (_clipStart != _clipStop && blendingStyle > BLEND_STYLE_FADE) {
const bool invertX = _clipStart > _clipStop;
const bool invertY = _clipStartY > _clipStopY;
const unsigned startX = invertX ? _clipStop : _clipStart;
const unsigned stopX = invertX ? _clipStart : _clipStop;
const unsigned startY = invertY ? _clipStopY : _clipStartY;
const unsigned stopY = invertY ? _clipStartY : _clipStopY;
const int startX = invertX ? _clipStop : _clipStart;
const int stopX = invertX ? _clipStart : _clipStop;
const int startY = invertY ? _clipStopY : _clipStartY;
const int stopY = invertY ? _clipStartY : _clipStopY;
if (blendingStyle == BLEND_STYLE_FAIRY_DUST) {
const unsigned width = stopX - startX; // assumes full segment width (faster than virtualWidth())
const unsigned len = width * (stopY - startY); // assumes full segment height (faster than virtualHeight())
Expand Down Expand Up @@ -295,7 +295,7 @@ void Segment::setPixelColorXY(float x, float y, uint32_t col, bool aa)
// returns RGBW values of pixel
uint32_t IRAM_ATTR Segment::getPixelColorXY(uint16_t x, uint16_t y) {
if (!isActive()) return 0; // not active
if (x >= virtualWidth() || y >= virtualHeight() || x<0 || y<0) return 0; // if pixel would fall out of virtual segment just exit
if (x >= virtualWidth() || y >= virtualHeight() || x<0 || y<0 || isPixelXYClipped(x,y)) return 0; // if pixel would fall out of virtual segment just exit
if (reverse ) x = virtualWidth() - x - 1;
if (reverse_y) y = virtualHeight() - y - 1;
if (transpose) { uint16_t t = x; x = y; y = t; } // swap X & Y if segment transposed
Expand Down
Loading