7
\$\begingroup\$

Ok. So I have a game I am working on with a bunch of colored particles. Each of them gets their own color however they are all close to a specific shade.

To explain that better I am using the HSV color space, and I have a global variable that is cycling from 0-360 (H) and each of the specific particles add or subtract a random amount from that.

enter image description here I use HSV because it is the easiest way for me to cycle through colors because you can just change H.

This looks very nice and all, however the particles are supposed to be pure light that is colored. Right now all they are are circles colored with the shade, but later on I might add glow effects and other shading techniques.

The problem is that not all shades (I dont mess with H or V) are equal as far as the brightness our eyes see, and this causes problems. For example when all of them are shades of blue things look pretty dark.

Obviously in the shader I have to convert these HSV colors to RGB colors and doing some math I quickly saw what was wrong... the colors didn't have equal luminance!

As I understand it luminance is roughly (0.2126*color.r + 0.7152*color.g + 0.0722*color.b) which is why everything is off.

Is their a way to get it so I can still get all of the different chroma (colors on the wheels degrees) while maintaining a high luminance? Perhaps I should work with a different type of color then HSV, or perhaps their is a formula that finds a color at degree x on the color wheel with luminance of y?

Thanks much!

\$\endgroup\$
5
  • \$\begingroup\$ There are limits to this unfortunately. If you look at a perceptually-uniform colour space like the Munsell colour system, you'll see that bright yellow has a much higher perceived value than a strong blue. That means if you want to keep uniform perceived value/luminance, then you can get either a rich royal blue paired with a dark ochre in the yellow hue, or a bright yellow with pale baby blue. Either way you sacrifice some saturation somewhere in the colour wheel. \$\endgroup\$
    – DMGregory
    Feb 15, 2016 at 15:17
  • 1
    \$\begingroup\$ As you noted, RGB and HSL are designed around possible screen colors and not around human eyes. Take a look at HUSL and HCL. Sometimes I'll use L*a*b* too. \$\endgroup\$
    – amitp
    Feb 15, 2016 at 17:05
  • \$\begingroup\$ @amitp those color spaces seem to be fairly new and I am seeing some difference in how they color spaces are defined, and how they are converted. Which source would be the most reliable for this? \$\endgroup\$
    – J.Doe
    Feb 16, 2016 at 6:25
  • \$\begingroup\$ I'm on a bus, so I better not write a formal answer, but here's what lies underneath the problem: you're going to need to solve a equation system where you plug three variables: Hue, Luminance and Saturation. So here you're searching for a specific Value, given H and S, that meets the condition of having certain luminance. Not quite hard. But you'll soon find out that some colors can't get as luminous as some (try finding a blue as luminous as a 100V yellow), so you may want to clamp the values, in order to get values representable on the screen. \$\endgroup\$ Feb 18, 2016 at 0:40
  • \$\begingroup\$ Yeah I've been working on that. I got a recursive formula going... AND a non recursive one (that isn't quite working). \$\endgroup\$
    – J.Doe
    Feb 18, 2016 at 0:43

1 Answer 1

2
\$\begingroup\$

HCY could be better for your needs. According to Wikipedia's HSL and HSV page, the problem you're having with HSV -- that the same "V" with different hues doesn't correspond to human perception -- is similar with HSL, but HCY could suit your needs -- the "Y" in HCY is for "luma":

Luma is roughly similar [in lightness to the original color image], but differs somewhat at high chroma. HSL L and HSV V, by contrast, diverge substantially from perceptual lightness.

HCY is described in the Wikipedia page as "luma/chroma/hue". This page, on the other hand, appears to use the "HCY" shorthand and shows how to convert it to and from RGB.

\$\endgroup\$
6
  • 2
    \$\begingroup\$ Your alternative division suggestion won't work for colours like blue (0, 0, 1) - because we can end up saturating the range of our primaries before reaching the desired luma. A blue phosphor on the player's screen can't be driven arbitrarily brightly (though HDR could dim the rest of the screen to try to give the illusion that the blue is as bright. Or you could set your luma target to 0.0722 to be able to divide any colour to that luma, at the cost of very dark colours overall) \$\endgroup\$
    – DMGregory
    Feb 15, 2016 at 15:02
  • \$\begingroup\$ Good point. I'll improve that part of the answer. \$\endgroup\$
    – Jibb Smart
    Feb 16, 2016 at 1:52
  • \$\begingroup\$ There are a bunch of ways to improve the alternative suggestion, but it gets quite complex before actually getting the kind of results OP likely wants, so I removed my alternative. HCY should suffice. \$\endgroup\$
    – Jibb Smart
    Feb 16, 2016 at 2:07
  • \$\begingroup\$ I am doing some experimentation with all of this. I will be updating in couple days to see how these color spaces preform. Thank you guys so much! \$\endgroup\$
    – J.Doe
    Feb 16, 2016 at 5:52
  • \$\begingroup\$ @DMGregory could you please explain more about what you mean by "set your luma target to 0.0722 to be able to divide any colour to that luma, at the cost of very dark colours overall"? \$\endgroup\$
    – J.Doe
    Feb 16, 2016 at 6:13

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .