Color spaces understanding (RGB / RGBW / RGBx)


Please, help to understand is it possible to make my own color scheme?

For example, I want to use amber, yellow or pure cyan LEDs, perhaps with the original RGB channels, is it possible to implement this in code. Which files are responsible for this? How do I provide my color scheme to the interface?

That’s something you would need to code yourself.

Thanks, I understand this
Where is the code that responsible for color conversion
Not sure that it in color.cpp
Any clues?

feels like it in bus manager? Looks little bit harcoded

Code from bus_mahanger
 void setPixelColor(uint16_t pix, uint32_t c) {
    if (pix != 0 || !_valid) return; //only react to first pixel
		if (_type != TYPE_ANALOG_3CH) c = autoWhiteCalc(c);
    if (_cct >= 1900 && (_type == TYPE_ANALOG_3CH || _type == TYPE_ANALOG_4CH)) {
      c = colorBalanceFromKelvin(_cct, c); //color correction from CCT
    uint8_t r = R(c);
    uint8_t g = G(c);
    uint8_t b = B(c);
    uint8_t w = W(c);
    uint8_t cct = 0; //0 - full warm white, 255 - full cold white
    if (_cct > -1) {
      if (_cct >= 1900)    cct = (_cct - 1900) >> 5;
      else if (_cct < 256) cct = _cct;
    } else {
      cct = (approximateKelvinFromRGB(c) - 1900) >> 5;

		uint8_t ww, cw;
		#ifdef WLED_USE_IC_CCT
		ww = w;
		cw = cct;
		//0 - linear (CCT 127 = 50% warm, 50% cold), 127 - additive CCT blending (CCT 127 = 100% warm, 100% cold)
		if (cct       < _cctBlend) ww = 255;
		else ww = ((255-cct) * 255) / (255 - _cctBlend);

		if ((255-cct) < _cctBlend) cw = 255;
		else cw = (cct       * 255) / (255 - _cctBlend);

		ww = (w * ww) / 255; //brightness scaling
		cw = (w * cw) / 255;

    switch (_type) {
      case TYPE_ANALOG_1CH: //one channel (white), relies on auto white calculation
        _data[0] = w;
      case TYPE_ANALOG_2CH: //warm white + cold white
        _data[1] = cw;
        _data[0] = ww;
      case TYPE_ANALOG_5CH: //RGB + warm white + cold white
        // perhaps a non-linear adjustment would be in order. need to test
        _data[4] = cw;
        w = ww;
      case TYPE_ANALOG_4CH: //RGBW
        _data[3] = w;
      case TYPE_ANALOG_3CH: //standard dumb RGB
        _data[0] = r; _data[1] = g; _data[2] = b;

no. bus manager is low level pixel interface. it has nothing to do with colors.

If you mean color palette when you say “color scheme” those are in separate .h file. You can mangle them as much as you like but beware that integrations may look weird in such case.

I want to try to implement some really strange things
I wouldn’t be too embarrassed if it looks weird in code
Now I want to try to connect the UV-strip as channel 4 and make it look “normal” on existing presets

UV is just a regular analog strip. nothing fancy about it.
You need MOSFET to drive it.

Yep, techically I understand. I can say more, Im using DMX with my slightly modified firmware)
But it’s not an RGBW scheme, but RGB+UV and the existing presets won’t work the way I want. I need my own interpolation (RGBW / RGB → RGB+UV) and I want to figure out where to implement it in code.

Also, later I think to try implement another schemes like Y + R + C + W or something more weird with Amber leds

so you need to replace White with UV?
just control White channel independently.

for non-RGB color spaces (not schemes) just implement CMYK, LAB or other transformation.

for non-RGB color spaces (not schemes) just implement CMYK, LAB or other transformation.

Exactly! Color spaces, thank you! I forgot the right term
Where it possible to look at? Little bit confused

The RGB+UV color space is also not a simple RGB/RGBA. Existing out-of-the-box presets will work oddly with it, but I want to achieve some consistency without hacks. But your idea is brilliant, thank you, in case of I not succeeded I’ll try that

@blazoncek Can I ask you to give me a hint?

Unfortunately the best I can give you is make your own auto-white calculation (bus_manager) to control W channel from RGB values. How? I have no idea.

Since UV is not a color in normal terms I still think the best way is to create (a) custom effect(s) that know how to handle W channel as UV and then use manual white control. A bit tedious I admit but IMO the only proper way.

This tip looks nice!
I guess I’m more interested in “where” than “how.”. I want to understand how the concept of “color” is formed and how this value is given to the channels. It turns out that the bus manager is responsible for this? I have already looked at it, it seems that there is a choice between strips and PWM.

So 4th and 5th channels are calculated automatically for some layouts — rgbw/rgbwn?

Thank you @blazoncek, you understand better than anyone how it works.

A starting point: Color theory - Wikipedia

I’m talking about code, not about color theory
by the way, I’m familiar with color spaces and color transformations — have a lot of experience in computer graphics

I probably imagined that there is some class that “technically correctly” converts color to RGBW/RGBWN. I see that the white channel is a bit hard-coded for this conversion in the code. Maybe better starting point was an explanation how RGBW/RGBWN code works in WLED? And how it related to presets / color wheel / palettes?

Reading your posts it seems you wanted information on how colors are constructed.
R+G+B emitting light sources will produce different hues of color depending on the amount of each primary.

There is no mention of UV in that regards. You cannot reproduce UV with RGB. Period.

If you want to include UV in your effects there is no way you can achieve that with whatever is in WLED ATM.

Also, all UV LEDs I’ve come across are analog which means you will need to treat them as PWM 1 channel LEDs as far as WLED is concerned. As such they can be controlled using separate White channel (in WLED terms) which WLED supports. Still, WLED has the ability to automatically calculate amount of white in particular RGB combination if you want automatic white calculation. But this is assuming RGB values (which produce shades of white if all of them are equal).

If we go back to your original request: There is no way to automatically generate UV part of color spectrum using whatever is built into WLED. If you want UV in your effects you will need to program it yourself using White channel as a means to activate UV LEDs.

  1. You don’t have to explain to me how colors work. I know. You know too, I’ve seen it in code.

  2. I’m not asking you “can you implement RGB+UV” - I want to implement it myself. At this point, I barely understand how color conversion works in WLED, where the source of rgbw layouts — Is there a color managment system in code?

  3. I’m asking about the code. How does WLED do white in rgbw/rgbwn layouts (and why is it so hardcoded), where can I find the transformation, does it depend on rgb, do you use linear spaces, LUTs and many other code related questions (and only then about color). I understand I can’t require you to do this in code, but I would expect there to be a clear strategy about color and how it is displayed and I was hoping I could get an explanation of how it works in code

  4. There was an idea to implement some kind of color management. But your explanations don’t explain anything, but now I have a lack of confidence that this is a good idea.

I can’t understand why It so hard to explain.
I’ll come back when I read the source to be clearer.

no. bus manager is low level pixel interface. it has nothing to do with colors.

You said the bus manager is a low-level pixel interface, but why does it have a hard-coded cct color conversion? Or am I wrong? If it were transparent and clear, I wouldn’t ask.