Make rainbow effects more colorful (#3681)

* Make color_wheel rotate in HSV sapce instead of linearly interpolating R->G->B
* Remove the rainbow wheel option, as that is the same as the rainbow palette
* Use hsv2rgb for color_wheel

This is the current result of the discussion in https://github.com/wled/WLED/pull/3681
This commit is contained in:
TripleWhy
2025-08-15 20:19:18 +02:00
committed by GitHub
parent c8d8ab020e
commit b8b59b2bb1
6 changed files with 5 additions and 24 deletions

23
wled00/FX_fcn.cpp Executable file → Normal file
View File

@@ -1085,27 +1085,14 @@ void Segment::blur(uint8_t blur_amount, bool smear) const {
/* /*
* Put a value 0 to 255 in to get a color value. * Put a value 0 to 255 in to get a color value.
* The colours are a transition r -> g -> b -> back to r * The colours are a transition r -> g -> b -> back to r
* Inspired by the Adafruit examples. * Rotates the color in HSV space, where pos is H. (0=0deg, 256=360deg)
*/ */
uint32_t Segment::color_wheel(uint8_t pos) const { uint32_t Segment::color_wheel(uint8_t pos) const {
if (palette) return color_from_palette(pos, false, false, 0); // never wrap palette if (palette) return color_from_palette(pos, false, false, 0); // only wrap if "always wrap" is set
uint8_t w = W(getCurrentColor(0)); uint8_t w = W(getCurrentColor(0));
pos = 255 - pos; uint32_t rgb;
if (useRainbowWheel) { hsv2rgb(CHSV32(static_cast<uint16_t>(pos << 8), 255, 255), rgb);
CRGB rgb; return rgb | (w << 24); // add white channel
hsv2rgb_rainbow(CHSV(pos, 255, 255), rgb);
return RGBW32(rgb.r, rgb.g, rgb.b, w);
} else {
if (pos < 85) {
return RGBW32((255 - pos * 3), 0, (pos * 3), w);
} else if (pos < 170) {
pos -= 85;
return RGBW32(0, (pos * 3), (255 - pos * 3), w);
} else {
pos -= 170;
return RGBW32((pos * 3), (255 - pos * 3), 0, w);
}
}
} }
/* /*

View File

@@ -519,7 +519,6 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
CJSON(briMultiplier, light[F("scale-bri")]); CJSON(briMultiplier, light[F("scale-bri")]);
CJSON(paletteBlend, light[F("pal-mode")]); CJSON(paletteBlend, light[F("pal-mode")]);
CJSON(strip.autoSegments, light[F("aseg")]); CJSON(strip.autoSegments, light[F("aseg")]);
CJSON(useRainbowWheel, light[F("rw")]);
CJSON(gammaCorrectVal, light["gc"]["val"]); // default 2.2 CJSON(gammaCorrectVal, light["gc"]["val"]); // default 2.2
float light_gc_bri = light["gc"]["bri"]; float light_gc_bri = light["gc"]["bri"];
@@ -1042,7 +1041,6 @@ void serializeConfig(JsonObject root) {
light[F("scale-bri")] = briMultiplier; light[F("scale-bri")] = briMultiplier;
light[F("pal-mode")] = paletteBlend; light[F("pal-mode")] = paletteBlend;
light[F("aseg")] = strip.autoSegments; light[F("aseg")] = strip.autoSegments;
light[F("rw")] = useRainbowWheel;
JsonObject light_gc = light.createNestedObject("gc"); JsonObject light_gc = light.createNestedObject("gc");
light_gc["bri"] = (gammaCorrectBri) ? gammaCorrectVal : 1.0f; // keep compatibility light_gc["bri"] = (gammaCorrectBri) ? gammaCorrectVal : 1.0f; // keep compatibility

View File

@@ -908,7 +908,6 @@ Swap: <select id="xw${s}" name="XW${s}">
<option value="3">None (not recommended)</option> <option value="3">None (not recommended)</option>
</select><br> </select><br>
Use harmonic <i>Random Cycle</i> palette: <input type="checkbox" name="TH"><br> Use harmonic <i>Random Cycle</i> palette: <input type="checkbox" name="TH"><br>
Use &quot;rainbow&quot; color wheel: <input type="checkbox" name="RW"><br>
Target refresh rate: <input type="number" class="s" min="0" max="250" name="FR" oninput="UI()" required> FPS Target refresh rate: <input type="number" class="s" min="0" max="250" name="FR" oninput="UI()" required> FPS
<div id="fpsNone" class="warn" style="display: none;">&#9888; Unlimited FPS Mode is experimental &#9888;<br></div> <div id="fpsNone" class="warn" style="display: none;">&#9888; Unlimited FPS Mode is experimental &#9888;<br></div>
<div id="fpsHigh" class="warn" style="display: none;">&#9888; High FPS Mode is experimental.<br></div> <div id="fpsHigh" class="warn" style="display: none;">&#9888; High FPS Mode is experimental.<br></div>

View File

@@ -351,7 +351,6 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
t = request->arg(F("TP")).toInt(); t = request->arg(F("TP")).toInt();
randomPaletteChangeTime = MIN(255,MAX(1,t)); randomPaletteChangeTime = MIN(255,MAX(1,t));
useHarmonicRandomPalette = request->hasArg(F("TH")); useHarmonicRandomPalette = request->hasArg(F("TH"));
useRainbowWheel = request->hasArg(F("RW"));
nightlightTargetBri = request->arg(F("TB")).toInt(); nightlightTargetBri = request->arg(F("TB")).toInt();
t = request->arg(F("TL")).toInt(); t = request->arg(F("TL")).toInt();

View File

@@ -625,7 +625,6 @@ WLED_GLOBAL unsigned long transitionStartTime;
WLED_GLOBAL bool jsonTransitionOnce _INIT(false); // flag to override transitionDelay (playlist, JSON API: "live" & "seg":{"i"} & "tt") WLED_GLOBAL bool jsonTransitionOnce _INIT(false); // flag to override transitionDelay (playlist, JSON API: "live" & "seg":{"i"} & "tt")
WLED_GLOBAL uint8_t randomPaletteChangeTime _INIT(5); // amount of time [s] between random palette changes (min: 1s, max: 255s) WLED_GLOBAL uint8_t randomPaletteChangeTime _INIT(5); // amount of time [s] between random palette changes (min: 1s, max: 255s)
WLED_GLOBAL bool useHarmonicRandomPalette _INIT(true); // use *harmonic* random palette generation (nicer looking) or truly random WLED_GLOBAL bool useHarmonicRandomPalette _INIT(true); // use *harmonic* random palette generation (nicer looking) or truly random
WLED_GLOBAL bool useRainbowWheel _INIT(false); // use "rainbow" color wheel instead of "spectrum" color wheel
// nightlight // nightlight
WLED_GLOBAL bool nightlightActive _INIT(false); WLED_GLOBAL bool nightlightActive _INIT(false);

View File

@@ -382,7 +382,6 @@ void getSettingsJS(byte subPage, Print& settingsScript)
printSetFormValue(settingsScript,PSTR("TL"),nightlightDelayMinsDefault); printSetFormValue(settingsScript,PSTR("TL"),nightlightDelayMinsDefault);
printSetFormValue(settingsScript,PSTR("TW"),nightlightMode); printSetFormValue(settingsScript,PSTR("TW"),nightlightMode);
printSetFormIndex(settingsScript,PSTR("PB"),paletteBlend); printSetFormIndex(settingsScript,PSTR("PB"),paletteBlend);
printSetFormCheckbox(settingsScript,PSTR("RW"),useRainbowWheel);
printSetFormValue(settingsScript,PSTR("RL"),rlyPin); printSetFormValue(settingsScript,PSTR("RL"),rlyPin);
printSetFormCheckbox(settingsScript,PSTR("RM"),rlyMde); printSetFormCheckbox(settingsScript,PSTR("RM"),rlyMde);
printSetFormCheckbox(settingsScript,PSTR("RO"),rlyOpenDrain); printSetFormCheckbox(settingsScript,PSTR("RO"),rlyOpenDrain);