Skip to content

Conversation

@DedeHai
Copy link
Collaborator

@DedeHai DedeHai commented May 1, 2025

  • fixed inconsitencies in size rendering
  • fixed palette being wrapped in color by position and color by age modes
  • Fixed bug in memory layout: for some unknown reason, if flags come before particles, last flag is sometimes overwritten, changing memory laout seems to fix that
  • New color modes in PS Fireworks 1D:
    • custom3 slider < 16: lower saturation (check1: single color or multi-color explosions)
    • custom3 slider <= 23: full saturation (check1: single color or multi-color explosions)
    • custom3 slider > 23: color by speed (check 1 has not effect here)
    • custom slider = max: color by age or color by position (depends on check1)

Summary by CodeRabbit

  • Improvements
    • Enhanced control and clarity for particle effects, including refined particle size handling, gravity application, and color assignment in 1D and 2D particle systems.
    • Improved color blending and rendering for particle effects, leading to more consistent visual results.
    • Adjusted particle emission logic for more precise effect behavior.
  • Documentation
    • Clarified documentation for particle size settings and interactions between global and advanced particle properties.

DedeHai added 3 commits April 28, 2025 21:05
- fixed inconsitencies in size rendering
- fixed palette being wrapped in color by position and color by age modes
- Fixed bug in memory layout: for some unknown reason, if flags come before particles, last flag is sometimes overwritten, changing memory laout seems to fix that
@coderabbitai
Copy link
Contributor

coderabbitai bot commented May 1, 2025

Walkthrough

This change refines the particle system code in both 1D and 2D contexts, focusing on improved clarity and control of particle size, gravity, emission logic, and color blending. It adjusts internal comments to clarify the interaction between global and advanced particle size settings, updates initialization and rendering logic to better handle color blending modes, and modifies the behavior of several particle-based effects, especially the 1D fireworks effect. The changes do not alter public interfaces but improve code readability, initialization correctness, and internal documentation.

Changes

Files / Paths Change Summary
wled00/FX.cpp Refined particle system behaviors in 1D effects: clarified comments on particle size, adjusted initialization and gravity logic in fireworks effect, changed rocket and explosion parameters, improved color assignment logic, renamed variables for clarity, updated emission conditions, and revised effect metadata string.
wled00/FXparticleSystem.cpp Initialized source flags to zero in constructors, introduced blend mode selection for color rendering, clarified and adjusted particle size handling in rendering, reordered pointer assignments for consistency, added debug output, and improved documentation and formatting throughout the code.
wled00/FXparticleSystem.h Updated and extended comments to clarify the semantics of global and advanced particle size settings in all relevant structs and classes; no functional logic changes, only documentation improvements.

Possibly related PRs

Suggested reviewers

  • blazoncek

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ast-grep (0.31.1)
wled00/FX.cpp

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3e7fd5b and c23d044.

📒 Files selected for processing (1)
  • wled00/FX.cpp (6 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • wled00/FX.cpp
⏰ Context from checks skipped due to timeout of 90000ms (7)
  • GitHub Check: wled_build / Build Environments (usermods)
  • GitHub Check: wled_build / Build Environments (esp32s3dev_8MB_opi)
  • GitHub Check: wled_build / Build Environments (esp32_wrover)
  • GitHub Check: wled_build / Build Environments (esp32s3_4M_qspi)
  • GitHub Check: wled_build / Build Environments (esp32s3dev_16MB_opi)
  • GitHub Check: wled_build / Build Environments (esp32_eth)
  • GitHub Check: wled_build / Build Environments (lolin_s2_mini)
✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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: 2

🔭 Outside diff range comments (1)
wled00/FXparticleSystem.cpp (1)

241-248: 🛠️ Refactor suggestion

setParticleSize() is executed once per particle – that’s O(N²) work in disguise

Inside particleMoveUpdate() the call to setParticleSize(particlesize) is made for every live particle when advPartProps is enabled.
setParticleSize() touches several globals (particleHardRadius, motionBlur) and contains branching logic that was meant for occasional calls from user-facing setters, not tight inner loops.

On a 640-particle 32×32 matrix this alone burns ~5-8 % of the CPU time per frame.

-    if (advancedproperties) { //using individual particle size?
-      setParticleSize(particlesize); // updates default particleHardRadius
+    static uint32_t baseHardRadius = 0;
+    if (advancedproperties) {
+      if (baseHardRadius == 0) {           // compute once per frame
+        baseHardRadius = particleHardRadius;
+      }

Or compute particleHardRadius once before the particle loop (e.g. in update()) and pass it in.

🧹 Nitpick comments (4)
wled00/FX.cpp (3)

8129-8133: Avoid resetting the global particle size inside the per-particle loop

Calling setParticleSize() for every particle iteration incurs unnecessary overhead and may introduce subtle race conditions if another effect re-uses the same PartSys instance concurrently.
Instead, set the global size once before entering the emission loop and only touch advPartProps[i].size inside the loop:

-  PartSys->setParticleSize(1); // set global size to 1 for advanced rendering (no single pixel particles)
-  PartSys->advPartProps[i].size = hw_random16(SEGMENT.custom1); // set each particle to random size
+  // set global size once outside the loop
+  PartSys->advPartProps[i].size = hw_random16(255);  // random size per particle

If the surrounding code already runs in a loop, consider hoisting the global call outwards to keep the inner loop tight.


9321-9325: Fix typo and clarify gravity-blur coupling

// anable motion blur// enable motion blur. While purely cosmetic, spelling mistakes in comments make maintenance harder.

Additionally, gravity is calculated even when SEGMENT.speed == 0, but later ignored. Computing it conditionally avoids one shift and addition:

-int32_t gravity = (1 + (SEGMENT.speed >> 3)); // gravity value used for rocket speed calculation
-PartSys->setGravity(SEGMENT.speed ? gravity : 0); // set gravity
+int32_t gravity = SEGMENT.speed ? (1 + (SEGMENT.speed >> 3)) : 0;
+PartSys->setGravity(gravity);

9385-9394: Repeated system-wide mode toggles inside tight loop

setColorByAge() / setColorByPosition() are invoked for every single explosion particle, yet they modify global PS state, not the individual particle.
Call them once before the for loop to avoid redundant 100-1000 writes per explosion:

-if(SEGMENT.custom3 == 31) { // highest slider value
-  PartSys->setColorByAge(SEGMENT.check1);
-  PartSys->setColorByPosition(!SEGMENT.check1);
-}
+if(SEGMENT.custom3 == 31) { // highest slider value
+  PartSys->setColorByAge(SEGMENT.check1);
+  PartSys->setColorByPosition(!SEGMENT.check1);
+}
 ...
 for (uint32_t e = 0; e < explosionsize; e++) {

Moving the calls out improves frame time on large explosions.

wled00/FXparticleSystem.h (1)

215-218: Comment/doc mismatch could confuse future maintainers

The inline comment claims that particlesize 255 = 10 pixels, yet the surrounding code and the public setParticleSize() APIs constrain the valid range to 0‒10 in steps of 1 (or 64 in the blur pass).
Consider clarifying the comment (or enforcing range checks) so that it is obvious how values >10 or random user input are handled.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d10714d and 3e7fd5b.

📒 Files selected for processing (3)
  • wled00/FX.cpp (7 hunks)
  • wled00/FXparticleSystem.cpp (14 hunks)
  • wled00/FXparticleSystem.h (6 hunks)
🔇 Additional comments (3)
wled00/FX.cpp (1)

9396-9398: Randomising source.hue inside particle loop changes colour mid-explosion

Because source.hue is mutated each iteration, later particles in the same explosion can receive a different offset than earlier ones, leading to unintended hue streaking.
If the intent is “rainbow per explosion”, compute one random hue before the loop and keep it constant:

-          if (SEGMENT.check1) // colorful mode
-            PartSys->sources[0].source.hue = hw_random16(); //random color for each particle
+          static uint16_t explosionHue = hw_random16();
+          if (SEGMENT.check1)
+            PartSys->sources[0].source.hue = explosionHue;

Do we want colour variation per particle or per explosion? Please confirm; I can draft a patch once the desired behaviour is clear.

wled00/FXparticleSystem.cpp (2)

564-566: Palette-blend flag logic: only colorByAge considered

blend switches to LINEARBLEND_NOWRAP if colorByAge is set, but not when the palette is driven by position (which is a valid 2-D mode in other effects).
If this omission is intentional, please add a short comment.
If not, extend the condition:

if (particlesettings.colorByAge || particlesettings.colorByPosition)
    blend = LINEARBLEND_NOWRAP;

979-982: Memory-alignment assumption lacks hard guarantees

particleFlags (1 byte) is placed immediately after PSparticle[numParticles] (10 bytes each).
Even though numParticles is forced to be a multiple of 4, 10 × 4 = 40 is not 8-byte aligned on 64-bit targets and could mis-align subsequent PSsource objects (which contain 16-bit and 32-bit fields).

Consider:

static_assert(sizeof(PSparticle) % 4 == 0,
              "PSparticle must be 4-byte aligned");

or insert manual padding after particleFlags when sizeof(PSparticle) is not a power of two.

Comment on lines 9343 to 9345
uint32_t speed = sqrt((gravity * ((PartSys->maxX >> 2) + hw_random16(PartSys->maxX >> 1))) >> 4); // set speed such that rocket explods in frame
PartSys->sources[0].source.vx = min(speed, (uint32_t)127);
PartSys->sources[0].source.ttl = 4000;
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Heavy floating-point sqrt() on MCU – replace with an integer approximation

sqrt() promotes the argument to double, incurring ~40 µs on ESP8266 and ~15 µs on ESP32. As this path runs every launch, that overhead is avoidable.
A fast 16-bit integer square-root (e.g. ic_sqrt16() used elsewhere in WLED) or a bit-shift approximation is sufficient:

-uint32_t speed = sqrt((gravity * ((PartSys->maxX >> 2) + hw_random16(PartSys->maxX >> 1))) >> 4);
+uint32_t speed = isqrt16((gravity * ((PartSys->maxX >> 2) + hw_random16(PartSys->maxX >> 1))) >> 4);

(Replace isqrt16 with any existing integer sqrt helper.)
This saves CPU cycles and power without visible changes in the effect.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
uint32_t speed = sqrt((gravity * ((PartSys->maxX >> 2) + hw_random16(PartSys->maxX >> 1))) >> 4); // set speed such that rocket explods in frame
PartSys->sources[0].source.vx = min(speed, (uint32_t)127);
PartSys->sources[0].source.ttl = 4000;
uint32_t speed = isqrt16((gravity * ((PartSys->maxX >> 2) + hw_random16(PartSys->maxX >> 1))) >> 4); // set speed such that rocket explods in frame
PartSys->sources[0].source.vx = min(speed, (uint32_t)127);
PartSys->sources[0].source.ttl = 4000;

@DedeHai DedeHai merged commit d9b086c into wled:main May 1, 2025
21 checks passed
@DedeHai DedeHai deleted the PSfirworks1D_bugfix branch May 1, 2025 12:05
DedeHai added a commit to DedeHai/WLED that referenced this pull request May 4, 2025
- fixed inconsitencies in size rendering
- fixed palette being wrapped in color by position and color by age modes
- Fixed bug in memory layout: for some unknown reason, if flags come before particles, last flag is sometimes overwritten, changing memory laout seems to fix that
- New color modes in PS Fireworks 1D:
 - custom3 slider < 16: lower saturation (check1: single color or multi-color explosions)
 - custom3 slider <= 23: full saturation (check1: single color or multi-color explosions)
 - custom3 slider > 23: color by speed (check 1 has not effect here)
 - custom slider = max: color by age or color by position (depends on check1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant