Hi @1icri_Old_Account - thanks for the thoughtful and detailed start to this discussion!
From the data and code you provided, I think that the built-in HSV-to-RGB in FastLED is functioning correctly as designed. You may want to implement your own conversion, or use a different one, but I think the built-in one is working as intended. A little more info follows below.
There are several different ways to map HSV colors into RGB space, and they all have pros and cons; there is no one universal conversion that gets everything perfect. So when a developer chooses an HSV-to-RGB conversion, they’re making design decisions and trade-offs.
One of the big design decisions that we made with FastLED was this: we wanted all the HSV colors at a given Saturation and Value to produce the same amount of light (and use the same amount of electrical power) regardless of what Hue they were at. And that is designed into the built-in FastLED HSV-to-RGB color conversions, as can be seen on the color charts on this wiki page: https://github.com/FastLED/FastLED/wiki/FastLED-HSV-Colors
Here’s the text from that page on this topic: “The bottom grayscale bar is the Radiance of each color: the total amount of light emitted. The FastLED color maps have extremely uniform radiance across the entire color map, and a correspondingly uniform power consumption across colors. In the Rainbow color map, rendering yellow takes a little bit more power than other colors, but otherwise the power usage and radiance curves are absolutely flat.”
So here’s how this relates to what you noticed: In this conversion model: just because “V” is 255 doesn’t mean that any one RGB channel must be 255.
Look at the R G and B graphs on the wiki page (above) to see what the design is.
So, consider the design of an HSV-to-RGB conversion, with constant-power / constant-brightness being a design goal. We decide that obviously Red is [255,0,0] (total power=255), and that also obviously Blue is [0,0,255] (total power=255). What should Purple be?
The ‘classic’ answer from the world of LCD screens and CRT monitors is [255,0,255]. That’s the answer you may get from screen/monitor -based color pickers and color converters as well. But in our world of individually powered LEDs, that formulation of purple has two problems. First, it draws twice as much power (total=510) as Red or Blue, and second it is not at all the same apparent brightness as Red or Blue.
We chose a different design: we chose constant brightness / constant power across all hues. And that means that Purple has to have the same total power as Red, and that means that Purple has to come out of the HSV-to-RGB conversion as something like [128,0,127] – with a total power of 255 – even though none of the R G or B channels are ‘maxed out’ at 255.
And yes, that Purple does not appear as bright as [255,0,255], but it does appear as bright as Red, or Blue, and we designed for constant brightness. (Well, except for a little bump in the yellows, which are a separate topic.)
And to be clear, there’s nothing stopping you from writing a simple little HSV-to-RGB conversion that would return [255,0,255] for the purple hue, and using that in your code in FastLED. But the built-in HSV-to-RGB conversion is designed for constant power across all hues, not maximum brightness at each hue separately.
You’re totally welcome to make other choices, and to implement other HSV-to-RGB conversions that have other design goals, but I think the built-in one that FastLED gives you ‘for free’ is working as designed here.
Make sense?