-
-
Notifications
You must be signed in to change notification settings - Fork 3.3k
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
added function to generate random palette based on harmonic color theory #3729
added function to generate random palette based on harmonic color theory #3729
Conversation
not sure if adding #include "FastLED.h" fcn_declare.h is the correct way |
Better to place it into "wled.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you very much. Code looks good.
Will test ASAP.
Tested on ESP32 and it performs ok. |
@DedeHai please re-test after my change. |
-fastled flags -gamma correction -pass by reference instead of pointer
895b19b
to
2659055
Compare
Do not force push. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've had a second look after yesterday's testing, which involved monitoring palette transitions for several minutes.
I must say that random palettes didn't look any more pleasing than the old ones. Perhaps the issue lies in randomisation of palette entries but I cannot say as I am no color theory specialist. What I would expect from this PR is to add (apart from greater complexity) a more visually pleasing result (best observed using Palette or Rainbow effects).
There are some other issues addressed separately as in-line comments.
P.S. And please follow the guidelines from Wiki on how to manage PRs. I've made some changes yesterday which were overwritten by force-pushing your updates.
I disagree. I did compare it to the original and it is much better. but that is taste I guess. Not saying it could not be improved more but it is a start. maybe get some other's opinions? |
What about auric color pair palettes, complementary color palettes, tertiary color palettes, etc? Not randomised as seen in this code, but still random as in random base hue. That's what I was thinking of. I would love to see other people feedback as well. We should ask beta testers on Discord for help. |
that IS exactly what it does. I dont get what you mean... |
I do not know what randomness ESP took yesterday, but today palettes look less "jumpy" and more pleasing. |
-added fully random palette function ('the old way', currently just used for initialization) -changed randomness values to make it a little less random -added 10% chance for pastel color palette -now using swap() from std library for shuffeling -changed function name -moved update check from loadPalette() to handleRandomPalette() saving CPU cycles
I found some time yesterday to try out the changes (still without gamma correction => code from Sunday). I think the new random palettes do look nice 👍 just sometimes they seems to be a bit too dark, especially when you run at 50% or less global brightness. Compared to the old random palettes, they are more colourful and fewer pastel colours (pale horses). However for me they also lack any "white". As the results are so different, why not let users decide? It means we could have two random palettes in the list, one "classic" or simple, and the other one "harmonic". What do you think? |
@blazoncek @DedeHai I'm wondering why this PR - which is about adding a new (super 😎 ) way of making random palettes - is also modifying the transitions code? I have to admit that I did not read through your long discussion... just wouldn't it be better to separate the topics, and move changes to transitions into another PR? |
@softhack007 where did you spot that? As far as I can see it only touches random palettes. @DedeHai this now looks much better. 👏 |
wled00/FX_fcn.cpp
Outdated
@@ -466,6 +456,21 @@ CRGBPalette16 IRAM_ATTR &Segment::currentPalette(CRGBPalette16 &targetPalette, u | |||
void Segment::handleRandomPalette() { | |||
// just do a blend; if the palettes are identical it will just compare 48 bytes (same as _randomPalette == _newRandomPalette) | |||
// this will slowly blend _newRandomPalette into _randomPalette every 15ms or 8ms (depending on MIN_SHOW_DELAY) | |||
// if palette transitions is enabled, blend it according to Transition Time (if longer than minimum given by service calls) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@blazoncek I was referring to this part (modifying transitions/blending)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah. This refers to "respect transition time" while blending new random palette into old/displayable random palette.
My (or original) implementation relied on periodic (with constant period) calls to handleRandomPalette()
to do the blend, (due to bug) this happened rather quickly (and not consistent between different ESPs)
The bug has been mitigated and the blend was consistent but still dependent on FPS. This change (although I'm not very fond of it) somehow mitigates that.
Reality is that it would need a separate timer and be independently controllable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for explaining 👍
Indeed transition/blending time should - in best case - not depend on framerates, but use millis() or other timers so it always looks smooth, and same time will be needed no matter how high or low users set their "target fps".
As its "your" code, you're the best person to know if a second PR is needed or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@blazoncek another thought:
We could measure "time elapsed" (in millis) since the last blend step. then calculate how many steps correspond to elapsed time (using 40 FPS as the baseline for changes). Put the blending into a loop. If steps needed > 0, perform several blends at once. OFC the blending code must still run at a high rate so it won't show visual stuttering.
This is similar to how audioreactive mitigates "hickups" in userloop activity, in order to stabilize audio filtering.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@softhack007 I already added in something like that but I think it needs to be polished a little more. It is not a question of coding it but more a question of how it should behave.
My opinion is, that the user should be given the option to set the blend speed, which I added in by tying it to 'Transition Speed' but IMHO this should be a separate value. Next question is then, does this blend speed control random palette only or is it also used for normal palette blending or will that still depend on transition time. Adding too many options is also bad for usability, it should be somehow logical which value controls what. Right now (without my changes but with @blazoncek fix for random blend) the Transition Time (which also controls palette blending) can be set to 5000ms for example, but random palettes will still blend at default speed, which is ~150 frames. To me as a user this is quite inconsistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we are discussing it then let me try to explain "Transition Time" as far as blending palettes go. "Transition Time" is the time taken to switch (smoothly without visible steps) from one palette to the other. Random palette is exactly that - a single randomly generated palette. A single palette which is constantly changing so no transition is triggered when random change happen. If you want to consider this random change to be considered as a trigger for "Transition Time" then the approach taken above works until transition time is shorter than minimum time needed for full blend of two palettes (255 iterations) this is the inconsistency I am not fond of. I am not saying it will not work or that it may impact users much, I just want for things to be logical.
User can specify the amount of time between random changes (between 1s and 65535s), we could reuse that time to determine the time needed to transition from one random palette to the other without introducing yet another parameter or rely on "Transition Time". The connection can be linear, logarithmic or some other non-linear function. I.e. if a user specifies random palette time of 30s then the actual transition could take 1/3rd of time (or 10 seconds). This correlation will ensure no conflicts arise from improper user selection. I am open to suggestions regarding this approach.
In any case I'm ok with proposed solution taking strip.getTransition()
into account.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I completely agree, to me the current solution (without this PR) with frame based random palette blends is inconsistent as well. If I set transitions to a slow 10s then change between palettes I get a smooth transition. If I switch to random palette, suddenly transitions are much faster.
I just try to imagine differen use cases and what a user would expect. In my case, I use it for 2D matrix displays and ambient lighting. For the display case, a frame based 'static' change would be fine. For ambient not so much (as I mentioned before), here I would want slow transitions or at least have some control over it.
Then I see lots of people using it for quite flashy displays, mostly sound reactive stuff. I think here a fast transition would be expected if transition time is set low, even if the random change is set to say 5 minutes, so tying the random transition time to the change interval may be a bad idea. These are the scenarios I was thinking about.
There is no 'one fits all' solution I think without adding another config parameter.
The currently proposed solution in this PR may be the best compromise. Some people may not like it, some may find it much better, most probably don't even care or notice ;)
The most consistent approach would be to adjust the random palette blend so it (approximately) fits the transition time, even if that is set lower than the current frame based transition. I could do that by adjusting the amount of blending done in 'handleRandomPalette' but keep the approach to just call that function once every frame.
I tweaked it already a little, made it a tad brighter and upon request from @blazoncek added a 50% chance of hue shuffeling, giving it a more 'ranbowy' look and added a 10% chance to generate a 'pastel' palette (experimental, not sure if this should be kept). |
added more white, changed function return value of fully random palette function
Comment cleanup
@DedeHai please verify if my latest changes broke anything. If not, I am merging as is. |
thx for the code cleanup. I see no issues, works just like before. |
looks really nice :)