From 3260f465434518b515ff771059dce20d39b6281a Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Mon, 18 Sep 2023 14:57:15 +0200 Subject: [PATCH 1/3] bugfix for #3375 * improves robustness of the Matrix effect, by dynamically adjusting the "reference color" used to identify "falling code" head pixels. * a bit faster, as I've removed the need to scan all pixels a second time for "black screen" detection. Its still not perfect, and the main loop could be simplified a lot by leveraging on the fact that all changes actually happen in the top row, and "falling" is actually just moving everything down by one pixel. --- wled00/FX.cpp | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 2a1f9f27b..1abca8855 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -5169,7 +5169,7 @@ static const char _data_FX_MODE_2DLISSAJOUS[] PROGMEM = "Lissajous@X frequency,F /////////////////////// // 2D Matrix // /////////////////////// -uint16_t mode_2Dmatrix(void) { // Matrix2D. By Jeremy Williams. Adapted by Andrew Tuline & improved by merkisoft and ewowi. +uint16_t mode_2Dmatrix(void) { // Matrix2D. By Jeremy Williams. Adapted by Andrew Tuline & improved by merkisoft and ewowi, and softhack007. if (!strip.isMatrix) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); @@ -5177,6 +5177,8 @@ uint16_t mode_2Dmatrix(void) { // Matrix2D. By Jeremy Williams. if (SEGENV.call == 0) { SEGMENT.fill(BLACK); + SEGENV.aux0 = SEGENV.aux1 = UINT16_MAX; + SEGENV.step = 0; } uint8_t fade = map(SEGMENT.custom1, 0, 255, 50, 250); // equals trail size @@ -5194,10 +5196,23 @@ uint16_t mode_2Dmatrix(void) { // Matrix2D. By Jeremy Williams. if (strip.now - SEGENV.step >= speed) { SEGENV.step = strip.now; + // find out what color value is returned by gPC for a "falling code" example pixel + // the color values returned may differ from the previously set values, due to + // - auto brightness limiter (dimming) + // - lossy color buffer (when not using global buffer) + // - color balance correction + // - segment opacity + CRGB oldSpawnColor = spawnColor; + if ((SEGENV.aux0 < cols) && (SEGENV.aux1 < rows)) { // we have a hint from last run + oldSpawnColor = SEGMENT.getPixelColorXY(SEGENV.aux0, SEGENV.aux1); // find color of previous spawns + SEGENV.aux1 ++; // our sample pixel will be one row down the next time + } + + // move pixels one row down. Falling codes keep color and add trail pixels; all others pixels are faded for (int row=rows-1; row>=0; row--) { for (int col=0; col= rows); // empty screen means that the last falling code has moved out of screen area // spawn new falling code - if (random8() < SEGMENT.intensity || emptyScreen) { + if (random8() <= SEGMENT.intensity || emptyScreen) { uint8_t spawnX = random8(cols); SEGMENT.setPixelColorXY(spawnX, 0, spawnColor); + // update hint for next run + SEGENV.aux0 = spawnX; + SEGENV.aux1 = 0; } } // if millis From 555dd2e726f1e392649be6bd000f94e3f78e7e62 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Mon, 18 Sep 2023 15:34:53 +0200 Subject: [PATCH 2/3] matrix: fix for a corner case (e.g. gapmaps) workaround for a corner case; if the reference pixels falls into a "gap" then gPC returns BLACK. Solutions is to reject BLACK. --- wled00/FX.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 1abca8855..f0d84c649 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -5207,6 +5207,7 @@ uint16_t mode_2Dmatrix(void) { // Matrix2D. By Jeremy Williams. oldSpawnColor = SEGMENT.getPixelColorXY(SEGENV.aux0, SEGENV.aux1); // find color of previous spawns SEGENV.aux1 ++; // our sample pixel will be one row down the next time } + if ((oldSpawnColor == CRGB::Black) || (oldSpawnColor == trailColor)) oldSpawnColor = spawnColor; // reject "black", as it would mean that ALL pixels create trails // move pixels one row down. Falling codes keep color and add trail pixels; all others pixels are faded for (int row=rows-1; row>=0; row--) { From 43613e3b100acb8af6cf544efce95b90b8108083 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Mon, 18 Sep 2023 15:56:50 +0200 Subject: [PATCH 3/3] Matrix effect speedup Typically, more than 50% of pixels are black. This optimization avoids to fade and rewrite already black pixels. --- wled00/FX.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index f0d84c649..6e8e5df04 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -5218,7 +5218,7 @@ uint16_t mode_2Dmatrix(void) { // Matrix2D. By Jeremy Williams. if (row < rows-1) SEGMENT.setPixelColorXY(col, row+1, spawnColor); } else { // fade other pixels - SEGMENT.setPixelColorXY(col, row, pix.nscale8(fade)); + if (pix != CRGB::Black) SEGMENT.setPixelColorXY(col, row, pix.nscale8(fade)); // optimization: don't fade black pixels } } }