update to distortionwave FX (#4693)

- fixed "jumpyness" by improving offset calculation resolution
- added palette support
- added two rendering modes for use with palette: one uses hue-mapping, one uses brightness mapping
- added alternate animation mode (from initial source)
- extended scaling: zoom checkmark (depends on matrix size)
This commit is contained in:
Damian Schneider 2025-06-06 17:05:16 +02:00 committed by GitHub
parent 23a51e0982
commit a87b562bc2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -7407,7 +7407,7 @@ static const char _data_FX_MODE_2DAKEMI[] PROGMEM = "Akemi@Color speed,Dance;Hea
// Distortion waves - ldirko // Distortion waves - ldirko
// https://editor.soulmatelights.com/gallery/1089-distorsion-waves // https://editor.soulmatelights.com/gallery/1089-distorsion-waves
// adapted for WLED by @blazoncek // adapted for WLED by @blazoncek, improvements by @dedehai
uint16_t mode_2Ddistortionwaves() { uint16_t mode_2Ddistortionwaves() {
if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up
@ -7416,20 +7416,23 @@ uint16_t mode_2Ddistortionwaves() {
uint8_t speed = SEGMENT.speed/32; uint8_t speed = SEGMENT.speed/32;
uint8_t scale = SEGMENT.intensity/32; uint8_t scale = SEGMENT.intensity/32;
if(SEGMENT.check2) scale += 192 / (cols+rows); // zoom out some more. note: not changing scale slider for backwards compatibility
uint8_t w = 2;
unsigned a = strip.now/32; unsigned a = strip.now/32;
unsigned a2 = a/2; unsigned a2 = a/2;
unsigned a3 = a/3; unsigned a3 = a/3;
unsigned colsScaled = cols * scale;
unsigned rowsScaled = rows * scale;
unsigned cx = beatsin16_t(10-speed,0,colsScaled);
unsigned cy = beatsin16_t(12-speed,0,rowsScaled);
unsigned cx1 = beatsin16_t(13-speed,0,colsScaled);
unsigned cy1 = beatsin16_t(15-speed,0,rowsScaled);
unsigned cx2 = beatsin16_t(17-speed,0,colsScaled);
unsigned cy2 = beatsin16_t(14-speed,0,rowsScaled);
byte rdistort, gdistort, bdistort;
unsigned cx = beatsin8_t(10-speed,0,cols-1)*scale;
unsigned cy = beatsin8_t(12-speed,0,rows-1)*scale;
unsigned cx1 = beatsin8_t(13-speed,0,cols-1)*scale;
unsigned cy1 = beatsin8_t(15-speed,0,rows-1)*scale;
unsigned cx2 = beatsin8_t(17-speed,0,cols-1)*scale;
unsigned cy2 = beatsin8_t(14-speed,0,rows-1)*scale;
unsigned xoffs = 0; unsigned xoffs = 0;
for (int x = 0; x < cols; x++) { for (int x = 0; x < cols; x++) {
xoffs += scale; xoffs += scale;
@ -7438,25 +7441,49 @@ uint16_t mode_2Ddistortionwaves() {
for (int y = 0; y < rows; y++) { for (int y = 0; y < rows; y++) {
yoffs += scale; yoffs += scale;
byte rdistort = cos8_t((cos8_t(((x<<3)+a )&255)+cos8_t(((y<<3)-a2)&255)+a3 )&255)>>1; if(SEGMENT.check3) {
byte gdistort = cos8_t((cos8_t(((x<<3)-a2)&255)+cos8_t(((y<<3)+a3)&255)+a+32 )&255)>>1; // alternate mode from original code
byte bdistort = cos8_t((cos8_t(((x<<3)+a3)&255)+cos8_t(((y<<3)-a) &255)+a2+64)&255)>>1; rdistort = cos8_t (((x+y)*8+a2)&255)>>1;
gdistort = cos8_t (((x+y)*8+a3+32)&255)>>1;
bdistort = cos8_t (((x+y)*8+a+64)&255)>>1;
} else {
rdistort = cos8_t((cos8_t(((x<<3)+a )&255)+cos8_t(((y<<3)-a2)&255)+a3 )&255)>>1;
gdistort = cos8_t((cos8_t(((x<<3)-a2)&255)+cos8_t(((y<<3)+a3)&255)+a+32 )&255)>>1;
bdistort = cos8_t((cos8_t(((x<<3)+a3)&255)+cos8_t(((y<<3)-a) &255)+a2+64)&255)>>1;
}
byte valueR = rdistort+ w* (a- ( ((xoffs - cx) * (xoffs - cx) + (yoffs - cy) * (yoffs - cy))>>7 )); byte valueR = rdistort + ((a- ( ((xoffs - cx) * (xoffs - cx) + (yoffs - cy) * (yoffs - cy))>>7 ))<<1);
byte valueG = gdistort+ w* (a2-( ((xoffs - cx1) * (xoffs - cx1) + (yoffs - cy1) * (yoffs - cy1))>>7 )); byte valueG = gdistort + ((a2-( ((xoffs - cx1) * (xoffs - cx1) + (yoffs - cy1) * (yoffs - cy1))>>7 ))<<1);
byte valueB = bdistort+ w* (a3-( ((xoffs - cx2) * (xoffs - cx2) + (yoffs - cy2) * (yoffs - cy2))>>7 )); byte valueB = bdistort + ((a3-( ((xoffs - cx2) * (xoffs - cx2) + (yoffs - cy2) * (yoffs - cy2))>>7 ))<<1);
valueR = gamma8(cos8_t(valueR)); valueR = gamma8(cos8_t(valueR));
valueG = gamma8(cos8_t(valueG)); valueG = gamma8(cos8_t(valueG));
valueB = gamma8(cos8_t(valueB)); valueB = gamma8(cos8_t(valueB));
SEGMENT.setPixelColorXY(x, y, RGBW32(valueR, valueG, valueB, 0)); if(SEGMENT.palette == 0) {
// use RGB values (original color mode)
SEGMENT.setPixelColorXY(x, y, RGBW32(valueR, valueG, valueB, 0));
} else {
// use palette
uint8_t brightness = (valueR + valueG + valueB) / 3;
if(SEGMENT.check1) { // map brightness to palette index
SEGMENT.setPixelColorXY(x, y, ColorFromPalette(SEGPALETTE, brightness, 255, LINEARBLEND_NOWRAP));
} else {
// color mapping: calculate hue from pixel color, map it to palette index
CHSV hsvclr = rgb2hsv_approximate(CRGB(valueR>>2, valueG>>2, valueB>>2)); // scale colors down to not saturate for better hue extraction
SEGMENT.setPixelColorXY(x, y, ColorFromPalette(SEGPALETTE, hsvclr.h, brightness));
}
}
} }
} }
// palette mode and not filling: smear-blur to cover up palette wrapping artefacts
if(!SEGMENT.check1 && SEGMENT.palette)
SEGMENT.blur(200, true);
return FRAMETIME; return FRAMETIME;
} }
static const char _data_FX_MODE_2DDISTORTIONWAVES[] PROGMEM = "Distortion Waves@!,Scale;;;2"; static const char _data_FX_MODE_2DDISTORTIONWAVES[] PROGMEM = "Distortion Waves@!,Scale,,,,Fill,Zoom,Alt;;!;2;pal=0";
//Soap //Soap