WLED
WLED copied to clipboard
Make rainbow effects more colorful
I was playing around with some rainbow effects and was wondering why there was no real yellow color. Cyan and magenta are also mysteriously underrepresented. I think rainbow effects should use the full rainbow spectrum.
If you agree, that is what this PR does.
Here are two images displaying the Rainbow effect on 256 LEDs, captured using the web UI:
Top: 0_15 (874b24fb320c6dc16e509514b70965bb4ca7964b)
Bottom: mine (760a1d45124903070a62944faf6f0f3e95e9bbaf)
This works by replacing the linear transitions R -> G -> B in color_wheel by the HSV transition 0° -> 360°.
Bravo! That boggled me as well. Approved.
One more thing: As to avoid angering certain users please make the new color wheel calculation optional.
Make an entry in LED settings (something like "Use HSV transition for color wheel") and a global selector (WLED_GLOBAL bool hsvColorWheel _INIT(false); ).
Update: Please check colors.cpp and function colorHStoRGB(). You could optimize the code to reuse that function (which itself could be optimised to not use float).
Tested this today but have to say that I fail to see any real difference on my LEDs.
Hm. You are right. There is a difference for me, but I can't really say that one better than the other. My version certainly is a bit brighter (obviously, now that I think about it). I have the cheapest LEDs I could find though.
Possibly there might be a greater difference with higher quality or future LEDs or setups. I mean there clearly is a difference on an LCD screen.
Update: Please check
colors.cppand functioncolorHStoRGB(). You could optimize the code to reuse that function (which itself could be optimised to not usefloat).
I did actually look at that when I worked on color_wheel and decided against it:
- As you said,
colorHStoRGBis far from optimal. colorHStoRGBdoesn't preserve the W value... I think?- The computations I used are highly optimized to work with the given assumptions. The computations are reduced so far they are not the direct result of math transformations anymore, they are new formulas that happen to produce the correct result for every possible input. These assumptions that can't be made when
colorHStoRGBis used, even if I managed to optimizecolorHStoRGBa bit.
If you wish, (and if you want to keep my version in the first place,) I can have a look at what's possible, but it won't be as optimal. It might result in an ever so slightly smaller binary though.
But for that size goal I'd first decide on one version and only keep one.
I've already updated code to utilize both as an option. Please review and comment.
I saw that. Some more explicit feedback:
- I think I wouldn't keep both versions at the same time.
- Configuration option: I have no idea how this works in WLED, so I can't really comment on that.
- The setting itself is pretty non-descriptive, so I'd want some more information as a user.
colorHStoRGB(): Looks good. Probably doesn't change much though ^^
Another option would be to keep the original function for ESP8266, and use the hsv function for ESP32.
I made some comparisons between the color computation of these functions:
D1 Mini
| original | hsv | delta | % | |
|---|---|---|---|---|
| exec/ns | 429.43 | 546.26 | 116.83 | 127.21 % |
| flash/bytes | 874987 | 875035 | 48 | 100.01 % |
WT32-ETH01
| original | hsv | delta | % | |
|---|---|---|---|---|
| exec/ns | 159.56 | 170.03 | 10.47 | 106.56 % |
| flash/bytes | 1290933 | 1290957 | 24 | 100.00 % |
I made some comparisons between the color computation of these functions
Are you talking about color_wheel() and colorHStoRGB() or about old vs. new color_wheel()?
color_wheel original vs. mine. The versions of the function I benchmarked didn't contain the first two lines that read palette and currentColor, that's why I said this is about the color computation only.
Perhaps change % 256 into & 0xFF and test again. It should provide same result.
According to godbolt's compiler explorer, that produces the same binary
According to godbolt's compiler explorer, that produces the same binary
Nice to learn something new. Quite a different ASM to Z80. ;)
So simpler C code produces 27% overhead. Who would've thought.