Skip to content

Update to distortionwave FX #4693

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
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
63 changes: 45 additions & 18 deletions wled00/FX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7412,7 +7412,7 @@ static const char _data_FX_MODE_2DAKEMI[] PROGMEM = "Akemi@Color speed,Dance;Hea

// Distortion waves - ldirko
// 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() {
if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up

Expand All @@ -7421,20 +7421,23 @@ uint16_t mode_2Ddistortionwaves() {

uint8_t speed = SEGMENT.speed/32;
uint8_t scale = SEGMENT.intensity/32;

uint8_t w = 2;
if(SEGMENT.check2) scale += 192 / (cols+rows); // zoom out some more. note: not changing scale slider for backwards compatibility

unsigned a = strip.now/32;
unsigned a2 = a/2;
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;
for (int x = 0; x < cols; x++) {
xoffs += scale;
Expand All @@ -7443,25 +7446,49 @@ uint16_t mode_2Ddistortionwaves() {
for (int y = 0; y < rows; y++) {
yoffs += scale;

byte rdistort = cos8_t((cos8_t(((x<<3)+a )&255)+cos8_t(((y<<3)-a2)&255)+a3 )&255)>>1;
byte gdistort = cos8_t((cos8_t(((x<<3)-a2)&255)+cos8_t(((y<<3)+a3)&255)+a+32 )&255)>>1;
byte bdistort = cos8_t((cos8_t(((x<<3)+a3)&255)+cos8_t(((y<<3)-a) &255)+a2+64)&255)>>1;
if(SEGMENT.check3) {
// alternate mode from original code
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 valueG = gdistort+ w* (a2-( ((xoffs - cx1) * (xoffs - cx1) + (yoffs - cy1) * (yoffs - cy1))>>7 ));
byte valueB = bdistort+ w* (a3-( ((xoffs - cx2) * (xoffs - cx2) + (yoffs - cy2) * (yoffs - cy2))>>7 ));
byte valueR = rdistort + ((a- ( ((xoffs - cx) * (xoffs - cx) + (yoffs - cy) * (yoffs - cy))>>7 ))<<1);
byte valueG = gdistort + ((a2-( ((xoffs - cx1) * (xoffs - cx1) + (yoffs - cy1) * (yoffs - cy1))>>7 ))<<1);
byte valueB = bdistort + ((a3-( ((xoffs - cx2) * (xoffs - cx2) + (yoffs - cy2) * (yoffs - cy2))>>7 ))<<1);

valueR = gamma8(cos8_t(valueR));
valueG = gamma8(cos8_t(valueG));
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;
}
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
Expand Down