Skip to content

spots effect accuracy improvements#5341

Open
softhack007 wants to merge 2 commits intomainfrom
spots_improvement
Open

spots effect accuracy improvements#5341
softhack007 wants to merge 2 commits intomainfrom
spots_improvement

Conversation

@softhack007
Copy link
Member

@softhack007 softhack007 commented Feb 2, 2026

A few improvement for the spots effect, especially relevant for longer strips:

  • avoid gaps on left/right side of strip, by using higher accuracy for "zoneLength"
  • prevent overflows
  • ensure that zones calculations are performed in full 32bit
  • fix wrong slider name in "spots fade"

Summary by CodeRabbit

  • Bug Fixes

    • Improved Spots effect rendering math to prevent zero-zone cases and visual gaps by using precise fixed-point calculations and safer indexing.
    • Tightened brightness/alpha computation and masking to prevent overflow and ensure correct color blending.
  • Documentation

    • Renamed Spots Fade parameter label from "Spread" to "Speed" for clearer user control.

* avoid gaps on left/light side of strip, by using higher accuracy zoneLength
* prevent overflows
* ensure that zones calculation are performed in full 32bit
* fix wrong slider name in "spots fade"
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 2, 2026

Walkthrough

Refactors Spots Fade rendering math to use fixed-point/32-bit arithmetic, clamps zone counts, adjusts per-zone position and indexing, tightens brightness masking, and updates the Spots Fade metadata label from "Spread" to "Speed".

Changes

Cohort / File(s) Summary
Spots effect rendering
wled00/FX.cpp
Reworked zone calculation and indexing to use 32-bit/fixed-point arithmetic (clamp maxZones≥1, compute zones with scaled intensity, introduce zoneLen8, compute pos and index with scaled math), tightened brightness/alpha computation (s masked to 8-bit), and changed mode metadata string _data_FX_MODE_SPOTS_FADE parameter label from "Spread" to "Speed".

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • DedeHai
🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'spots effect accuracy improvements' directly and clearly describes the main purpose of the changeset: fixing precision issues in the spots lighting effect.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch spots_improvement

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@softhack007 softhack007 added this to the 16.0.0 beta milestone Feb 2, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@wled00/FX.cpp`:
- Around line 2955-2970: The current computation of zoneLen8 uses zones >> 3
which collapses 9–15 to 1 and can make (zones * zoneLen8) >> 3 exceed SEGLEN
causing offset underflow and huge indices; fix by using a true 1/8 fixed‑point
scale (avoid shifts on zones) — compute zoneLen8 as (SEGLEN * 8) / zones (using
a wider integer type to avoid overflow) and compute offset the same way ((SEGLEN
- ((zones * zoneLen8) >> 3)) >> 1); also replace the magic literal 8 with a
named constant like ZONE_FP_SCALE to clarify intent and prevent future errors
(symbols: zoneLen8, offset, zones, SEGLEN).

* use named constants for fixed point scaling
* remove buggy "SEGLEN / (zones >>3)" shortcut
* remove an unnecessary casts to uint32_t
@softhack007 softhack007 changed the title spots effect improvements spots effect accuracy improvements Feb 2, 2026
@softhack007 softhack007 added effect optimization re-working an existing feature to be faster, or use less memory labels Feb 2, 2026
Copy link
Collaborator

@DedeHai DedeHai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generally an improvement, there are two issues (one introduced, one unsolved):

  • on small segments, the threshold can be too high, turning off all spots. something like this fixes that but may introduce "breaking changes" I did only a brief test:
  uint16_t maxWave = triwave16(((zoneLen - 1) * 0xFFFF) / zoneLen);
  threshold = min(threshold, uint16_t(maxWave - 1)); // guarantee threshold is always reached (prevent "no spots" on short strips)

to check: use a segment with 15 LEDs, turn speed slider down and intensity slider up.

  • the newly introduced issue is a classic integer math rounding problem: while the spots now spread better, they distribute unevenly. I faced the same dilemma in "PS chase" and used more elaborate code to get both a full spread distribution as well as an even spacing.

return spots_base(tr);
}
static const char _data_FX_MODE_SPOTS_FADE[] PROGMEM = "Spots Fade@Spread,Width,,,,,Overlay;!,!;!";
static const char _data_FX_MODE_SPOTS_FADE[] PROGMEM = "Spots Fade@Speed,Width,,,,,Overlay;!,!;!";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

while you are at it: rename "Width" to "Density" for both variants?

@softhack007
Copy link
Member Author

softhack007 commented Feb 4, 2026

the newly introduced issue is a classic integer math rounding problem: while the spots now spread better, they distribute unevenly. I faced the same dilemma in "PS chase" and used more elaborate code to get both a full spread distribution as well as an even spacing.

@DedeHai thanks for your comments 😃 Yes unevenly distributed gaps are a new side-effect. At second look the nested loops with offset re-calcution seem unnecessary, we could also just repeat the tri-wave pattern until the end of strip is reached. Just that the effect might not be centered any more for long "spread" values. I'll think about a better implementation.

Edit: maybe this is better

start with offset = 0.5 * (SEGLEN / pattern_length) // similar to old code, no fixed-point math involved. Could also use float for better accuracy as this is only calculated once per frame
while (SEGLEN - last_position < pattern_length) draw_triwave_pattern

Edit2: 🤔 actually offset calculation is the only "tricky" thing left, because the effect should be centered no matter how long or short the strip really is...

@DedeHai
Copy link
Collaborator

DedeHai commented Feb 4, 2026

I need to check that code but in general for long er strips with 100 LEDs+ you will not notice a 1 pixel offset, unless its coarse and you want it aligned to furniture but I guess that is more of an edge case. What is much more noticeable is an irregular pattern.

Edit: with 24V strips and "zones" now coming up more and more, low LED-count segments are not uncommon (I have 64 on mine)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effect optimization re-working an existing feature to be faster, or use less memory

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants