Skip to content

Perlinscape FX (2D) in the user_fx usermod - #5587

Merged
softhack007 merged 16 commits into
wled:mainfrom
BobLoeffler68:pr-perlinscape-user-fx
Oct 17, 2026
Merged

softhack007 merged 16 commits into
wled:mainfrom
BobLoeffler68:pr-perlinscape-user-fx

Conversation

@BobLoeffler68

@BobLoeffler68 BobLoeffler68 commented May 10, 2026 •

Copy link
Copy Markdown
Contributor

This PR adds the 2D Perlinscape effect into the new user_fx usermod instead of FX.cpp

  • a Perlin noise landscape animation
  • Created by stepko as part of Stepko Land on soulmatelights.com
  • Adapted to WLED by Bob Loeffler with additional features (and help from Claude)
  • First slider is for speed
  • Second slider is for zooming in/out (Perlin scaling)
  • Third slider is the X multiplier
  • Fourth slider is the Y multiplier
  • Fifth slider is the rotation speed (0 = do not rotate)
  • Checkbox will randomize the horizonal and vertical directions

Example videos:

80007897461__00E4D193-7401-4ED9-9F74-DBF3C8C172A7.mov

^-- Default settings and Rotation

IMG_6838.mov

^-- Using the Hult 64 palette

Untitled.1.mp4

^-- Hult 64 palette and mirrored X

Untitled.mp4

^-- Candy palette and Rotation

Summary by CodeRabbit

  • New Features
    • Added the Perlinscape visual effect for 2D matrix displays, rendering animated Perlin-noise patterns.
    • Choose between RGB and palette-based coloring, and adjust the effect’s speed, zoom, and horizontal and vertical scaling.
    • Optional rotation and randomized movement direction provide additional visual variation. On layouts other than 2D matrices, the effect uses a static display.

@softhack007 softhack007 added usermod usermod related AI Partly generated by an AI. Make sure that the contributor fully understands the code! effect labels May 10, 2026
@softhack007

Copy link
Copy Markdown
Member

@BobLoeffler68 I see "0 files changed" - is this expected?

image

@softhack007 softhack007 added the waiting for feedback addition information needed to better understand the issue label May 10, 2026
@BobLoeffler68

Copy link
Copy Markdown
Contributor Author

@BobLoeffler68 I see "0 files changed" - is this expected?

Hmmmmm... I'm not sure what is happening. I can't even compile it anymore as it says platform_wled_default doesn't exist in the [common] section of platformio.ini Something strange is happening.

@coderabbitai

coderabbitai Bot commented May 10, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • No new commits to review - use @coderabbitai full review for a full pass

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository YAML (base), Repository UI (inherited), Organization UI (inherited)
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 0b68bfe6-69ad-46cb-89cb-bb5e994250ec
📥 Commits

Reviewing files that changed from the base of the PR and between dcc1cd2 and 946cd6f.

📒 Files selected for processing: 1
  • usermods/user_fx/user_fx.cpp

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

📜 Recent review details
🧰 Additional context used
📚 Code guidelines: 3
docs/hardening.instructions.md — configured
.github/agent-build.instructions.md — auto-discovered
AGENTS.md — configured
📓 Path-based instructions: 5
For usermods, the untrusted ingress points are: readFromConfig(JsonObject& root) and calls to getJsonValue() readFromJsonState(JsonObject& obj) — JSON is parsed, but values are client-supplied onMqttMessage(char* topic, char* payload) — raw...

⚙️ CodeRabbit configuration file

Files:

  • usermods/user_fx/user_fx.cpp
Follow the C++ coding conventions documented in docs/cpp.instructions.md and the general project guidelines in AGENTS.md and .github/copilot-instructions.md.

⚙️ CodeRabbit configuration file

Files:

  • usermods/user_fx/user_fx.cpp
Usermods are community add-ons.

⚙️ CodeRabbit configuration file

Files:

  • usermods/user_fx/user_fx.cpp
Applicability reference: AGENTS.md: # AGENTS.md — WLED AI Coding Agent & AI Code Review Reference See also: `.github/copilot-instructions.md`, `.github/agent-build.instructions.md`, `docs/cpp.instructions.md`, `docs/web.instructions.md`, `d...

📄 CodeRabbit inference engine (docs/hardening.instructions.md)

Files:

  • usermods/user_fx/user_fx.cpp
Source excerpt: Avoid unexplained "magic numbers".

📄 CodeRabbit inference engine (AGENTS.md)

Files:

  • usermods/user_fx/user_fx.cpp
🧠 Learnings: 3
📚 Learning: 2026-01-03T14:38:09.949Z
Learnt from: DedeHai
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2026-01-03T14:38:09.949Z
Learning: In WLED code reviews, check that FastLED trigonometric function aliases are not used. Replace `sin8()` and `cos8()` with `sin8_t()` and `cos8_t()`. Replace `sin16()` and `cos16()` with `sin16_t()` and `cos16_t()`. For float versions, replace `sinf()` and `cosf()` with `sin_approx()` and `cos_approx()`. See wled_math.cpp for the proper WLED implementations.

Applied to files:

  • usermods/user_fx/user_fx.cpp
📚 Learning: 2026-05-16T08:21:02.410Z
Learnt from: softhack007
Repo: wled/WLED PR: 5587
File: usermods/user_fx/user_fx.cpp:1295-1296
Timestamp: 2026-05-16T08:21:02.410Z
Learning: In WLED effect implementations (e.g., files/functions ending up in `*fx*.cpp` that compute per-frame time deltas), do not store a timestamp/counter (such as `t = strip.now / speedDiv`, or any millisecond-based counter) as `float` solely to represent the “previous time” for delta calculations. IEEE-754 float32 cannot preserve sub-second precision for large values and becomes inaccurate near `uint32_t` rollover (can skew deltas by ~1–2s). Store the previous timestamp as `uint32_t` and compute the frame delta using the rollover-safe integer subtraction before converting to float, e.g. `uint32_t newT = strip.now / speedDiv; float dt = float(int32_t(newT - prevT)); prevT = newT;`. Apply this consistently across WLED effect files that derive per-frame deltas from time counters.

Applied to files:

  • usermods/user_fx/user_fx.cpp
📚 Learning: 2026-05-06T22:10:27.517Z
Learnt from: softhack007
Repo: wled/WLED PR: 4843
File: usermods/elastic_collisions/Elastic_Collisions.cpp:1-1
Timestamp: 2026-05-06T22:10:27.517Z
Learning: In C/C++, do not flag precedence issues for expressions that mix additive operators (`+`, `-`) with shift operators (`<<`, `>>`) based on the assumption that shifts bind tighter. Per C/C++ operator precedence, `+`/`-` have higher precedence than `<<`/`>>` (e.g., `x - edge0 << 8` parses as `(x - edge0) << 8`). When reviewing WLED (and other) fixed-point/bit-manipulation code, confirm the intended parse using cppreference before reporting a precedence bug for mixed `-`/`+` and `<<`/`>>` expressions.

Applied to files:

  • usermods/user_fx/user_fx.cpp
🔇 Additional comments: 2
usermods/user_fx/user_fx.cpp: 2

1261-1395: LGTM!

1617-1617: LGTM!

Walkthrough

The user FX system adds and registers a 2D Perlin-noise effect. It uses palette or RGB output, with optional rotation and timed random direction changes. Unsupported layouts and allocation failures use the static fallback.

Changes

2D Perlinscape Effect

Layer / File(s) Summary
Implement and register Perlinscape
usermods/user_fx/user_fx.cpp
mode_2D_perlinscape initializes animation state, updates movement and optional rotation, and uses Perlin samples to render palette or RGB output. Unsupported layouts and allocation failures use the static fallback. UserFxUsermod::setup registers the effect.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Feature

Suggested reviewers: softhack007

Merge Risk: ⚪ Minimal · up to 946cd

The reviewed effect has no established merge-blocking issue; it is ready for normal build and hardware checks.

Pre-merge checks: Passed 4 · Failed 1

Failed 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%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 1 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly identifies the main change: adding the Perlinscape 2D effect to the user_fx usermod.

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.

coderabbitai[bot]

This comment was marked as resolved.

…- use cos_approx() and sin_approx() instead of cosf and sinf
coderabbitai[bot]

This comment was marked as resolved.

@blazoncek

Copy link
Copy Markdown
Contributor

This is a nice and very useful effect and I would recommend it for inclusion into core effects.

My recommendations for improvement (from Discord):

  • use Perlin color if "Default" palette is used but otherwise use selected palette (i.e. if (SEGMENT.palette == 0) ... and remove Palettes option
  • expand speed range especially towards slower side
  • reduce float use (float is painfully slow on ESP8266; i.e. don't use float for prevT, etc)

And BTW, to avoid pointer use (for a cleaner look) use references instead. I.e.

uint32_t prevT = reinterpret_cast<uint32_t&>(*SEGENV.data);
float offX  = reinterpret_cast<float&>(*(SEGENV.data + sizeof(uint32_t)));
...

Perhaps @coderabbitai can help with replacing floating point math with integer math to improve speed. Or use Claude.

@coderabbitai

This comment was marked as low quality.

… otherwise use selected palette. Also, I expanded the speed range towards the slower side. Both requested by blazoncek.
coderabbitai[bot]

This comment was marked as resolved.

* Switched from using pointers to using references.
* Added a slider for the rotation speed (0 = no rotation), so I removed the rotation checkbox.
* Fixed a bug during rotation where the animation would "jump" because it would overflow
* Changed byte to uint16_t in for loops.
coderabbitai[bot]

This comment was marked as resolved.

* Fixed the speed slider and rotation slider because their middle values were pretty much the same as their lower values.
Comment thread usermods/user_fx/user_fx.cpp Outdated
@softhack007

This comment was marked as outdated.

@coderabbitai

This comment was marked as outdated.

coderabbitai[bot]

This comment was marked as resolved.

@softhack007

Copy link
Copy Markdown
Member

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@softhack007 softhack007 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks good to me, thanks 👍

@softhack007
softhack007 merged commit 4a4e93d into wled:main Oct 17, 2026
37 checks passed
softhack007 pushed a commit that referenced this pull request Oct 17, 2026
a Perlin noise landscape animation

First slider is for speed
Second slider is for zooming in/out (Perlin scaling)
Third slider is the X multiplier
Fourth slider is the Y multiplier
Fifth slider is the rotation speed (0 = do not rotate)
Checkbox will randomize the horizonal and vertical directions
@BobLoeffler68
BobLoeffler68 deleted the pr-perlinscape-user-fx branch October 17, 2026 19:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI Partly generated by an AI. Make sure that the contributor fully understands the code! effect enhancement usermod usermod related waiting for feedback addition information needed to better understand the issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants