Skip to content
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

Adding perlin noise replacement for fastled functions #4594

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

DedeHai
Copy link
Collaborator

@DedeHai DedeHai commented Mar 12, 2025

I created integer-math based perlin noise functions to replace the 8-bit optimized fastled inoise functions.
They execute about twice as fast and use no look-up tables. The functions are slightly different from the originals but I tried to match them as good as possible. Here is a comparison of the outputs:

image

image

saves about 2.7k of flash as a bonus.

These FX use perlin noise, please check if you can spot obvious differences. They are very subtle and I can only spot them in a direct side-by-side comparison.

  • Noisefire
  • Firenoise
  • Midnoise (AR)
  • Waverly (AR)
  • Rotozoom
  • Sunradiation
  • Polarlights
  • Plasmaball
  • Noise2d
  • Metaballs
  • Noise pal
  • Phased noise
  • Fill noise

Summary by CodeRabbit

  • New Features

    • Introduced a new dynamic visual mode ("Perlin Move") for more fluid, organic animations.
  • Refactor

    • Upgraded the noise generation approach across audio reactive and visual effects, enhancing the responsiveness and overall animation quality.
  • Chores

    • Removed redundant debugging output for a cleaner setup process.

Copy link

coderabbitai bot commented Mar 12, 2025

Walkthrough

The changes update the noise generation methods across multiple modules. In the audio reactive component and various LED effect modules, calls to inoise8()/inoise16() have been replaced with perlin8()/perlin16(). Additionally, new fixed-point Perlin noise functions for 1D, 2D, and 3D noise have been implemented with corresponding declarations. A new effect called "Perlin Move" has been introduced, and several WS2812FX modes have been updated. Separately, a debug print statement was removed from the WLED setup.

Changes

Files Change Summary
usermods/.../audio_reactive.cpp, wled00/FX.cpp, wled00/util.cpp, wled00/fcn_declare.h Replaced inoise8()/inoise16() with perlin8()/perlin16() across modules. Added fixed-point Perlin noise implementations (including perlin1D_raw, perlin2D_raw, perlin3D_raw, perlin16, perlin8) and updated effects (e.g., new "Perlin Move").
wled00/wled.cpp Removed a debug print statement ("arduino-esp32 v1.0.x\n") from the setup method within the ESP32 conditional block.

Possibly related PRs

  • Soap FX optimization #4543: The changes in the main PR, which involve replacing inoise8() with perlin8() in the getSample() method of the AudioReactive class, are related to the changes in this PR, where inoise8() is also replaced with perlin8() in various effects within the FX.cpp file.

Tip

⚡🧪 Multi-step agentic review comment chat (experimental)
  • We're introducing multi-step agentic chat in review comments. This experimental feature enhances review discussions with the CodeRabbit agentic chat by enabling advanced interactions, including the ability to create pull requests directly from comments.
    - To enable this feature, set early_access to true under in the settings.
✨ Finishing Touches
  • 📝 Generate Docstrings

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

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

@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: 0

🧹 Nitpick comments (8)
wled00/FX.cpp (2)

6224-6224: Minor suggestion regarding type usage.

Storing sizeof(float) in an unsigned works, but typically size_t is used for sizes. This is non-blocking.


6648-6648: Consider clarifying the expression with parentheses.

strip.now * SEGMENT.speed/64 * SEGLEN/255 can be read in multiple ways due to left-to-right associativity. Adding parentheses would help avoid confusion.

wled00/fcn_declare.h (1)

517-525: Add brief usage notes for new Perlin noise prototypes.
These new function declarations look logically consistent and match the changes elsewhere in the PR.
However, consider documenting the parameter ranges and expected outputs (especially for is16bit in the _raw variations) to help maintain clarity for future developers.

wled00/util.cpp (5)

622-625: Add short overview of newly added Perlin functions.
The comment block reference is good, but consider briefly summarizing the main differences from typical noise functions, including performance rationale and approximate numeric range.


626-626: Prefer a compile-time constant over a macro.
Using constexpr int PERLIN_SHIFT = 1; instead of #define can help with type safety and debugging.

-#define PERLIN_SHIFT 1
+constexpr int PERLIN_SHIFT = 1;

637-645: Validate hashing approach for 1D gradient.
This approach looks correct for single-dimension Perlin. Ensure that the prime multipliers align well with your random/hashing goals, and confirm no collisions degrade the noise distribution.

Would you like a test snippet or additional analysis to confirm uniform distribution?


664-669: Confirm numeric stability in smoothstep.
This simplified cubic polynomial is standard, but the bit shifts are quite tight. If you find any banding artifacts, consider minor adjustments or an alternate polynomial.


694-724: perlin2D_raw matches 1D logic well.
Everything appears consistent. Check for any off-by-one or wrap-around issues if using extremely high x, y values.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between a6d9a82 and 494b72c.

📒 Files selected for processing (5)
  • usermods/audioreactive/audio_reactive.cpp (1 hunks)
  • wled00/FX.cpp (30 hunks)
  • wled00/fcn_declare.h (1 hunks)
  • wled00/util.cpp (2 hunks)
  • wled00/wled.cpp (0 hunks)
💤 Files with no reviewable changes (1)
  • wled00/wled.cpp
⏰ Context from checks skipped due to timeout of 90000ms (19)
  • GitHub Check: wled_build / Build Enviornments (usermods)
  • GitHub Check: wled_build / Build Enviornments (esp32s3_4M_qspi)
  • GitHub Check: wled_build / Build Enviornments (esp32s3dev_16MB_opi)
  • GitHub Check: wled_build / Build Enviornments (esp32dev_V4)
  • GitHub Check: wled_build / Build Enviornments (esp32c3dev)
  • GitHub Check: wled_build / Build Enviornments (esp01_1m_full_compat)
  • GitHub Check: wled_build / Build Enviornments (esp32_wrover)
  • GitHub Check: wled_build / Build Enviornments (esp32s3dev_8MB_opi)
  • GitHub Check: wled_build / Build Enviornments (lolin_s2_mini)
  • GitHub Check: wled_build / Build Enviornments (esp01_1m_full_160)
  • GitHub Check: wled_build / Build Enviornments (esp32dev)
  • GitHub Check: wled_build / Build Enviornments (esp32_eth)
  • GitHub Check: wled_build / Build Enviornments (nodemcuv2)
  • GitHub Check: wled_build / Build Enviornments (esp8266_2m)
  • GitHub Check: wled_build / Build Enviornments (esp8266_2m_160)
  • GitHub Check: wled_build / Build Enviornments (esp8266_2m_compat)
  • GitHub Check: wled_build / Build Enviornments (nodemcuv2_compat)
  • GitHub Check: wled_build / Build Enviornments (esp01_1m_full)
  • GitHub Check: wled_build / Build Enviornments (nodemcuv2_160)
🔇 Additional comments (39)
usermods/audioreactive/audio_reactive.cpp (1)

872-872: Improved performance by replacing inoise8 with perlin8 for simulated audio.

This change aligns with the PR's objective of replacing FastLED's inoise functions with faster Perlin noise implementations. For simulated microphone input, using perlin8() should provide better performance while maintaining similar random noise patterns needed for audio simulation.

wled00/FX.cpp (28)

2186-2186: Looks good.

No significant concerns regarding shifting from inoise8 to perlin8.


2206-2206: Double-check potential wrap-around in sin8_t(noise * 3).

When multiplying noise by 3, the value can exceed 255 and wrap around. If wrap-around behavior is intentional, no change is needed. Otherwise, consider clamping or casting to ensure the result stays within the expected range.


2224-2224: Implementation appears consistent.

Replacing inoise16 with perlin16 is straightforward here.


2245-2245: No issues detected.

Transition to perlin16 with a right shift for the final 8-bit value looks appropriate.


2260-2260: Confirm expected range for color palette index.

Unlike other places where perlin16(...) >> 8 is used, this call passes the full 16-bit value into color_from_palette() without shifting. If that’s intentional, please verify that the function uses the entire 16-bit range as intended. Otherwise, consider shifting or casting.


4122-4122: Change is acceptable.

Using perlin8(...)/16 for modVal to randomize the wave is a fine adaptation.


4191-4191: Implementation looks correct.

Noise-based index generation is consistent with the rest of the code.


4802-4802: No concerns here.

perlin16 usage with mapped output aligns with the intended effect logic.


5060-5060: No issues noted.

Simple two-argument perlin8 call looks fine.


5453-5457: Transition to new perlin8() calls is clear.

These random offsets for generating mapped coordinates appear intentional.


5513-5513: Seems straightforward.

perlin8(x * scale, y * scale, strip.now / (16 - SEGMENT.speed/16)) is consistent with other usage patterns.


5535-5538: Change is valid.

Three-argument calls to perlin8 for separate axes are standard here.


5583-5583: Change looks good.

New noise-based palette indexing is consistent with other segments.


5700-5701: Conversion logic is acceptable.

Replacing inoise8_raw with perlin8 and applying an offset/division is a normal approach for adjusting the noise range.


6238-6245: Verify float-to-int conversions in indexing.

abs8(u1 - j * sinus) suggests an implicit float → int cast. Confirm that truncation is intended before taking % cols. If so, explicitly cast to avoid ambiguity.


6394-6398: Implementation looks fine.

Incorporation of perlin8 with audio reactivity handling is done consistently.


6476-6476: No issues identified.

Simultaneous use of multiple Perlin inputs appears deliberate.


6498-6498: All good.

Mirrors the gravity logic from the preceding chunk.


6620-6620: Looks correct.

Noise-based indexing for sound-based expansions is consistent.


6679-6679: No concerns.

Logic is coherent with other perlin8 usage.


7095-7095: Implementation is consistent.

Noise-based location mapping for the new bin approach is fine.


7545-7545: Implementation is sound.

Combining perlin16 >> 8 into 8-bit data is standard.


8050-8050: No concerns with applying wind force.

Shifting the perlin8(...) result by 7 after scaling is consistent with the rest of the code.


8059-8059: Change is appropriate.

perlin8() for turbulence is a standard approach in these effects.


8276-8277: Approved.

Gravity-based randomization using Perlin noise is in line with the rest of this PR.


8348-8352: Potential overflow in int8_t fields.

baseheight and additional perlin8 calls can sum up to 510, exceeding the range of int8_t. If both are up to 255, the result will overflow. Consider clamping or using a larger type, e.g. int16_t.

Apply this diff if you want to cast and clamp:

- int8_t xslope = (baseheight + (int16_t)perlin8(xnoise - 10, ynoise, SEGENV.aux0));
- int8_t yslope = (baseheight + (int16_t)perlin8(xnoise, ynoise - 10, SEGENV.aux0));
+ int16_t xslope = baseheight + perlin8(xnoise - 10, ynoise, SEGENV.aux0);
+ int16_t yslope = baseheight + perlin8(xnoise, ynoise - 10, SEGENV.aux0);
+ if (xslope < -128) xslope = -128;
+ else if (xslope > 127) xslope = 127;
+ if (yslope < -128) yslope = -128;
+ else if (yslope > 127) yslope = 127;

9720-9720: No issues present.

Noise-based xgravity logic is consistent with the rest of the effect design.


10072-10072: Change is acceptable.

Adding a randomized hue offset from Perlin noise is consistent with the approach in other modes.

wled00/util.cpp (10)

509-509: Confirm output range suitability.
Replacing inoise8 with perlin8 can subtly alter the output distribution. Ensure the resulting effect still aligns with the target audio visualization, as Perlin noise might differ slightly at extremes.


514-514: Validate consistency with previous visual/audio effects.
Similar to line 509, confirm that the changes introduced by perlin8 preserve the intended effect behavior under different timing or input parameters.


628-635: Check for boundary cases in hashToGradient.
The function is concise and efficient. Performance seems strong for a small integer-based approach. Just make sure extreme corner cases (e.g. large input hash) don’t cause unexpected intermediate overflows.


647-653: Cross-check potential integer overflow in gradient2D.
The function accounts for two coordinates; it appears you are hashing them together with distinct prime factors. The logic is consistent with the 1D approach. No immediate issues seen.


655-662: Hash combination in gradient3D.
Using multiple prime-based shifts to incorporate x, y, z is a solid strategy. The scale factor in the return statement (line 661) looks correct for typical Perlin usage.


671-674: Check inline usage in lerpPerlin.
The linear interpolation approach is clear. Having it inlined helps performance. No immediate concerns.


676-692: Wrap logic in perlin1D_raw carefully.
The is16bit branching is effective for controlling wrap-around in small coordinate spaces. Be sure all call sites pass the correct boolean and expect the unscaled raw range.


726-770: perlin3D_raw complexity.
The logic is more involved, but it follows the same approach as the 1D and 2D implementations. The large arithmetic is carefully bit-shifted. Keep an eye on performance if used in tight loops, but overall this should be acceptable.


772-783: Ensure scaling constants remain consistent in perlin16.
These scale factors (e.g. 1159, 1537, 1731) appear carefully chosen. If you further tweak the hashing or random steps, re-verify these constants to preserve the approximate output range.


785-795: Double-check final offsets in perlin8.
After scaling down to 8 bits, the offset constants (e.g. + 32769) ensure the range stays within 0–255. Encouraging thorough real-world testing to verify no unexpected boundary saturations occur.

@blazoncek
Copy link
Collaborator

I would have preferred if you'd use #define inoise8 perlin8 instead of replacing every inoise8 function call.

@DedeHai
Copy link
Collaborator Author

DedeHai commented Mar 13, 2025

the final goal is to replace fastled, then it does not make sense to me to keep the legacy function names.
but actually adding that for compatibility is a good idea.
I also realized I commited changes to rotozoomer that I need to revert...

Copy link

@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: 0

🧹 Nitpick comments (5)
wled00/FX.cpp (5)

2206-2206: Confirm shift-by-8 logic aligns with desired color range.
This usage discards the lower 8 bits from the 16-bit Perlin output. Ensure this is producing the intended intensity curve.


2224-2224: Avoid using magic number 4223 for Z-coordinate.
Consider extracting 4223 into a named constant for clarity.

-    unsigned noise = perlin16(real_x, 0, 4223) >> 8;
+    static const uint16_t PERLIN_Z_BASE = 4223;
+    unsigned noise = perlin16(real_x, 0, PERLIN_Z_BASE) >> 8;

4122-4122: Replace repeated expression (i*10 + i*10) with i*20.
For clarity, consider simplifying the multiplication.

-    if (moder == 1) modVal = (perlin8(i*10 + i*10) /16);
+    if (moder == 1) modVal = (perlin8(i*20) /16);

6399-6402: Add parentheses to clarify operator precedence.
Using parentheses can help ensure the correct order of multiplication and division, especially with (1 + SEGMENT.intensity/64)* perlin8(...) / 2.

-    unsigned thisVal = (1 + SEGMENT.intensity/64) * perlin8(i * 45 , t , t)/2;
+    unsigned thisVal = ((1 + (SEGMENT.intensity/64)) * perlin8(i * 45, t, t)) / 2;

6653-6653: Check arithmetic order when multiplying by SEGLEN/255.
Potential goals might be better served by careful ordering or casting.

-    unsigned index = perlin8(i*SEGMENT.speed/64, strip.now*SEGMENT.speed/64*SEGLEN/255);
+    unsigned index = perlin8((i*SEGMENT.speed)/64, (strip.now*SEGMENT.speed/64)*(SEGLEN/255));
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 494b72c and d2b7e47.

📒 Files selected for processing (2)
  • wled00/FX.cpp (28 hunks)
  • wled00/fcn_declare.h (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (18)
  • GitHub Check: wled_build / Build Enviornments (lolin_s2_mini)
  • GitHub Check: wled_build / Build Enviornments (usermods)
  • GitHub Check: wled_build / Build Enviornments (esp32s3_4M_qspi)
  • GitHub Check: wled_build / Build Enviornments (esp32s3dev_8MB_opi)
  • GitHub Check: wled_build / Build Enviornments (esp32c3dev)
  • GitHub Check: wled_build / Build Enviornments (esp32s3dev_16MB_opi)
  • GitHub Check: wled_build / Build Enviornments (esp8266_2m_160)
  • GitHub Check: wled_build / Build Enviornments (esp8266_2m_compat)
  • GitHub Check: wled_build / Build Enviornments (esp32dev)
  • GitHub Check: wled_build / Build Enviornments (esp32_wrover)
  • GitHub Check: wled_build / Build Enviornments (esp01_1m_full_compat)
  • GitHub Check: wled_build / Build Enviornments (esp32_eth)
  • GitHub Check: wled_build / Build Enviornments (esp01_1m_full_160)
  • GitHub Check: wled_build / Build Enviornments (nodemcuv2_compat)
  • GitHub Check: wled_build / Build Enviornments (esp01_1m_full)
  • GitHub Check: wled_build / Build Enviornments (nodemcuv2_160)
  • GitHub Check: wled_build / Build Enviornments (esp8266_2m)
  • GitHub Check: wled_build / Build Enviornments (nodemcuv2)
🔇 Additional comments (27)
wled00/FX.cpp (23)

2186-2186: Check for potential overflow with large SEGLEN.
If SEGLEN is large, then i * SEGLEN might overflow the parameter's expected range. Verify if wrap-around is the intended effect.


2245-2245: Looks consistent with the other Perlin calls.
The shift-by-8 follows the established pattern of reducing 16-bit noise to 8-bit.


2260-2260: Check consistency with other >> 8 cases.
Other code samples shift the 16-bit result down. Verify if retaining the full 16-bit range is intentional here.


4191-4191: Replacement of inoise8 with perlin8 is straightforward.
Everything looks good here; logic and parameters remain consistent.


4802-4802: Ensure SEGMENT.speed never reaches 260 or higher.
Because (260 - SEGMENT.speed) is used in division, verify that it doesn’t become zero in corner cases.


5060-5060: No immediate issues with this change.
The switch from inoise8 to perlin8 appears consistent, and the indexing logic remains intact.


5453-5457: Double-check float vs integer usage in perlin8 calls.
strip.now * speed is a float expression, but perlin8 typically expects integer parameters. Confirm that the cast or truncation is acceptable.


5513-5513: Check integer division by (16 - SEGMENT.speed/16).
Ensure that (16 - SEGMENT.speed/16) never goes to zero and is used as intended when speed is high.


5535-5538: Potential risk for small denominators.
(256 - SEGMENT.speed) and similar expressions can become small. Confirm that it never becomes zero or negative.


5583-5583: Check _speed for zero-safety.
(SEGENV.step / _speed) could divide by zero if _speed is 0. Verify _speed is guaranteed nonzero.


5700-5701: Verify the new scaling logic.
Previously, noise was halved. Now you subtract 127 and scale by /3. Ensure these changes still produce the intended “bump” effect.


6481-6481: Change from inoise8 to perlin8 is correctly implemented.
No issues spotted with parameter usage.


6503-6503: Change from inoise8 to perlin8 is correctly implemented.
No issues spotted with parameter usage.


6625-6625: Straightforward substitution to perlin8.
Calculation for volumeSmth + offsets remains consistent.


6684-6684: All good here.
Noise usage and palette application remain functionally consistent.


7100-7100: Looks fine for mapping.
Just ensure the mapped range [7500..58000] is correct for large SEGLEN.


7550-7550: Use of >> 8 is consistent with the other 16-bit noise calls.
No issues spotted in scaling or palette usage.


8055-8055: Centering noise around zero.
Casting to int16_t and subtracting 127 is a valid approach to get signed wind speed from noise.


8064-8064: Same pattern of re-centering noise.
Implementation looks consistent with the standard approach.


8281-8282: Gravity anchored by Perlin noise.
Logic is consistent; no issues spotted.


8353-8357: Particle forces from Perlin noise.
The usage of additional Perlin calls for slopes is stable.


9725-9725: Simple shift from inoise8 to perlin8.
No concerns with subtracting 128 to anchor xgravity.


10077-10077: Beware of large mids values.
When multiplied and then shifted by 9, the final hue increment could overflow if mids or perlin8 output is high. Verify that’s acceptable.

wled00/fcn_declare.h (4)

489-490: Good addition of FastLED compatibility aliases.

The inclusion of these legacy aliases (inoise8 -> perlin8 and inoise16 -> perlin16) provides backward compatibility with existing code that uses FastLED's noise functions, making the transition smoother.


519-521: Well-structured raw Perlin noise function declarations.

The raw Perlin noise function declarations provide a good foundation for the noise generation system. The is16bit parameter allows for flexibility in output precision, and the 32-bit input parameters provide sufficient precision for complex noise patterns.


522-524: Good 16-bit Perlin noise API with multiple dimensionality options.

The 16-bit Perlin noise functions provide higher precision output and support for 1D, 2D, and 3D noise generation, which offers flexibility for various visual effects.


525-527: Appropriate 8-bit Perlin noise functions with performance considerations.

The 8-bit functions use 16-bit input parameters (as opposed to 32-bit in the 16-bit variants), which is a good balance between precision and performance for 8-bit output scenarios.

@DedeHai
Copy link
Collaborator Author

DedeHai commented Mar 22, 2025

did anyone have a chance to test this?
I have the rest of fastled replaced with local functions, some optimizations but this needs to be merged before I can move ahead with that. Once fastled is fully replaced, the next step is to try and optimize for speed by replacing CRGB and CHSV instances wherever possible (and useful) to reduce 24bit <-> 32bit color conversions.

@netmindz
Copy link
Member

If you are wanting others to test, I think it would be helpful if you could add some notes as what/how to test

Otherwise let's merge in and see if anyone complains 😜

@DedeHai
Copy link
Collaborator Author

DedeHai commented Mar 22, 2025

that is what I was trying with the

These FX use perlin noise, please check if you can spot obvious differences.

part in the commit comment :)

I mostly tested on 2D FX and those look fine to me. I was hoping someone could run it on a different setup with a different perspective as I may be biased from all the earlier tests.

@netmindz
Copy link
Member

I would say the graphs are more accurate way to compare than looking at the effects and they look close enough to my eyes

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.

3 participants