Skip to content

Improve visuals in MetaballsMode - #794

Merged
JanPetterMG merged 1 commit into
VIPnytt:mainfrom
Solmath:fix/metaballs-gradient-handling
Aug 30, 2026
Merged

Improve visuals in MetaballsMode#794
JanPetterMG merged 1 commit into
VIPnytt:mainfrom
Solmath:fix/metaballs-gradient-handling

Conversation

@Solmath

@Solmath Solmath commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Creating a separate PR for the refinement of the contribution calculation from #788

Currently the brightness calculation does not use the entire contributions array, due to the hard coded 1<<6:

brightness = static_cast<uint8_t>(
    min<uint16_t>(static_cast<uint16_t>(brightness) +
                        contributions[static_cast<uint8_t>(distanceSq * (0b1U << 6U) / radiusSq)],
                  UINT8_MAX));

This factor should be related to the size of the contributions array.

Also the initialization of the contributions array is not very intuitive, so I tried to make it clearer.

Key changes

  • Use named variables instead of magic numbers in initialization of contributions array
  • Use same factor falloffResolution during init of contributions and in calculation of brightness

Impact

  • Better visuals, avoiding sudden brightness drops at the edges of balls

@Solmath
Solmath requested a review from JanPetterMG as a code owner August 29, 2026 16:51
@github-actions github-actions Bot added bug Something isn't working firmware C++ related labels Aug 29, 2026
@coderabbitai

coderabbitai Bot commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 24a2b339-94f0-46e4-92f3-97a9f529ee47

📥 Commits

Reviewing files that changed from the base of the PR and between e190e49 and 7821144.

📒 Files selected for processing (2)
  • firmware/include/modes/MetaballsMode.h
  • firmware/src/modes/MetaballsMode.cpp

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.

📜 Recent review details
⏰ Context from checks skipped due to timeout. (86)
  • GitHub Check: Default (lolin_d32_pro)
  • GitHub Check: Default (lolin_d32)
  • GitHub Check: Default (lolin_s3_mini)
  • GitHub Check: Default (esp32-s3-devkitc-1)
  • GitHub Check: Default (esp32dev)
  • GitHub Check: Default (adafruit_qtpy_esp32s2)
  • GitHub Check: Minimal (seeed_xiao_esp32s3)
  • GitHub Check: Default (esp32-c6-devkitm-1)
  • GitHub Check: Default (esp32-c5-devkitc-1)
  • GitHub Check: Minimal (lolin_d32)
  • GitHub Check: Default (wemos_d1_mini32)
  • GitHub Check: Default (seeed_xiao_esp32s3)
  • GitHub Check: Default (esp32-c3-devkitm-1)
  • GitHub Check: Minimal (seeed_xiao_esp32c6)
  • GitHub Check: Default (adafruit_qtpy_esp32s3_nopsram)
  • GitHub Check: Minimal (lolin_s3_mini)
  • GitHub Check: Minimal (seeed_xiao_esp32c3)
  • GitHub Check: Default (adafruit_qtpy_esp32s3_n4r2)
  • GitHub Check: Minimal (esp32-s3-devkitc-1)
  • GitHub Check: Default (seeed_xiao_esp32c3)
  • GitHub Check: Minimal (wemos_d1_mini32)
  • GitHub Check: Default (seeed_xiao_esp32c6)
  • GitHub Check: Minimal (esp32-c6-devkitm-1)
  • GitHub Check: Minimal (esp32-c5-devkitc-1)
  • GitHub Check: Minimal (lolin_d32_pro)
  • GitHub Check: Minimal (adafruit_qtpy_esp32s2)
  • GitHub Check: Minimal (esp32-c3-devkitm-1)
  • GitHub Check: Minimal (adafruit_qtpy_esp32s3_nopsram)
  • GitHub Check: Minimal (esp32dev)
  • GitHub Check: Minimal (adafruit_qtpy_esp32s3_n4r2)
  • GitHub Check: Extensive (seeed_xiao_esp32s3)
  • GitHub Check: Typical (seeed_xiao_esp32s3)
  • GitHub Check: Extensive (adafruit_qtpy_esp32s3_nopsram)
  • GitHub Check: Typical (esp32-s3-devkitc-1)
  • GitHub Check: Extensive (esp32-s3-devkitc-1)
  • GitHub Check: Typical (adafruit_qtpy_esp32s3_nopsram)
  • GitHub Check: ESPHome (latest)
  • GitHub Check: ESPHome (2025.7.0)
  • GitHub Check: Tidy (IKEA_FREKVENS, esp32-c5-devkitc-1)
  • GitHub Check: Tidy (IKEA_FREKVENS, esp32-c6-devkitm-1)
  • GitHub Check: Tidy (IKEA_OBEGRANSAD, esp32-s3-devkitc-1)
  • GitHub Check: Tidy (IKEA_OBEGRANSAD, esp32-c3-devkitm-1)
  • GitHub Check: Tidy (IKEA_OBEGRANSAD, esp32dev)
  • GitHub Check: Tidy (IKEA_FREKVENS, esp32dev)
  • GitHub Check: Tidy (IKEA_OBEGRANSAD, esp32-c6-devkitm-1)
  • GitHub Check: Tidy (IKEA_OBEGRANSAD, esp32-c5-devkitc-1)
  • GitHub Check: Tidy (IKEA_FREKVENS, esp32-s3-devkitc-1)
  • GitHub Check: Tidy (IKEA_FREKVENS, esp32-c3-devkitm-1)
  • GitHub Check: Minimal (seeed_xiao_esp32s3)
  • GitHub Check: Minimal (lolin_s3_mini)
  • GitHub Check: Minimal (lolin_d32_pro)
  • GitHub Check: Default (adafruit_qtpy_esp32s2)
  • GitHub Check: Minimal (lolin_d32)
  • GitHub Check: Minimal (wemos_d1_mini32)
  • GitHub Check: Minimal (seeed_xiao_esp32c6)
  • GitHub Check: Minimal (esp32dev)
  • GitHub Check: Minimal (esp32-c5-devkitc-1)
  • GitHub Check: Minimal (seeed_xiao_esp32c3)
  • GitHub Check: Default (lolin_s3_mini)
  • GitHub Check: Minimal (esp32-c3-devkitm-1)
  • GitHub Check: Minimal (esp32-c6-devkitm-1)
  • GitHub Check: Minimal (adafruit_qtpy_esp32s3_nopsram)
  • GitHub Check: Minimal (adafruit_qtpy_esp32s3_n4r2)
  • GitHub Check: Minimal (adafruit_qtpy_esp32s2)
  • GitHub Check: Default (adafruit_qtpy_esp32s3_n4r2)
  • GitHub Check: Default (seeed_xiao_esp32s3)
  • GitHub Check: Default (lolin_d32_pro)
  • GitHub Check: Default (wemos_d1_mini32)
  • GitHub Check: Default (seeed_xiao_esp32c3)
  • GitHub Check: Default (esp32-s3-devkitc-1)
  • GitHub Check: Minimal (esp32-s3-devkitc-1)
  • GitHub Check: Default (esp32-c3-devkitm-1)
  • GitHub Check: Default (adafruit_qtpy_esp32s3_nopsram)
  • GitHub Check: Default (lolin_d32)
  • GitHub Check: Default (seeed_xiao_esp32c6)
  • GitHub Check: Default (esp32-c6-devkitm-1)
  • GitHub Check: Default (esp32dev)
  • GitHub Check: Default (esp32-c5-devkitc-1)
  • GitHub Check: Typical (esp32-s3-devkitc-1)
  • GitHub Check: Typical (adafruit_qtpy_esp32s3_nopsram)
  • GitHub Check: Extensive (adafruit_qtpy_esp32s3_nopsram)
  • GitHub Check: Extensive (esp32-s3-devkitc-1)
  • GitHub Check: Extensive (seeed_xiao_esp32s3)
  • GitHub Check: Typical (seeed_xiao_esp32s3)
  • GitHub Check: DejaVuSans font
  • GitHub Check: Format
🔇 Additional comments (3)
firmware/include/modes/MetaballsMode.h (1)

21-25: LGTM!

firmware/src/modes/MetaballsMode.cpp (2)

13-22: LGTM!


75-79: LGTM!


Summary by CodeRabbit

  • Bug Fixes
    • Improved metaballs brightness falloff for smoother, more consistent visual effects.
    • Prevented brightness lookup values from exceeding their valid range.
    • Preserved peak brightness while providing a more predictable fade to zero.

Walkthrough

Changes

Metaballs falloff calculation

Layer / File(s) Summary
Define fixed falloff storage
firmware/include/modes/MetaballsMode.h
The mode adds falloffResolution and resizes contributions for quantized distances from the ball center to its edge.
Build and consume falloff table
firmware/src/modes/MetaballsMode.cpp
begin() builds a quadratic brightness table with a peak brightness of 64.0. handle() computes and clamps indices to the table bounds.

Merge Risk: ⚪ Minimal · up to 78211

The change refines MetaballsMode brightness calculations to use the full contributions range and removes initialization magic numbers, improving edge brightness behavior. No actionable merge-blocking risk remains after normal checks and review.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: improving MetaballsMode visuals through refined brightness calculations.
Description check ✅ Passed The description explains the problem, lists the key calculation changes, and describes the visual impact. It matches the required template sections.
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.
  • Fix all pre-merge checks with AI
✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code

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.

@JanPetterMG JanPetterMG left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Looks good to me. I've reviewed the code and tested it on the actual hardware, and everything looks good. Approved!

@JanPetterMG JanPetterMG added this to the v2.5.2 milestone Aug 30, 2026
@JanPetterMG
JanPetterMG added this pull request to the merge queue Aug 30, 2026
Merged via the queue into VIPnytt:main with commit e57f259 Aug 30, 2026
111 checks passed
@github-project-automation github-project-automation Bot moved this from Backlog to Done in Frekvens roadmap Aug 30, 2026
@JanPetterMG

Copy link
Copy Markdown
Collaborator

Thanks for the contribution @Solmath! I really appreciate you taking the time to improve this. It's now included in the upcoming v2.5.2 release.

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

Labels

bug Something isn't working firmware C++ related

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants