Home Artists Posts Import Register
Join the new SimpleX Chat Group!

Content

In this screenshot, X, Y and Z are basically R, G and B. Instead of using standard color arithmetics, Retroquad uses vector arithmetics to compute color properties, because it's more accurate.

For example, the standard way of computing lightness is L = (highest_channel_value + lowest_channel_value) / 2. I find this standard way to be grossly innacurate for saturated colors, because it ignores the contribution of the middle channel value entirely.

The middle channel must not be ignored when computing lightness, because we're not dealing with pure light coming from a single light source; we're dealing with light composed from 3 different light sources (red, green and blue spots in the pixel grid of the screen).

Here is a very good article on this: Lode's Computer Graphics Tutorial - Light and Color. In the real world, most saturated colors are monochromatic, made up of one single pure frequency of light. When dealing with monochromatic colors, the standard way of computing lightness is correct, because you're getting the midpoint of the values of that single frequency.

However, the colors in all electronic screens used nowadays are multichromatic; instead of outputting a single light frequency per pixel, they output 3 different light frequencies from 3 different color elements: red, green and blue. The color we see from a single pixel is a mix of those 3 frequencies. And this is why the standard way of computing lightness is wrong in computer graphics: it completely ignores the contribution of the middle color channel, as if the middle color channel was always at the midpoint between the highest and lowest color channels. This is grossly wrong because the more saturated a color is, the lower are the chances of the middle color channel being at the midpoint. For fully saturated colors, only 1/256=0,4% of the possible values for the middle color channel are at the midpoint; 99,6% of the other possible values makes the standard lightness calculation return innacurate values.

This is why the color arithmetic algorithms in Retroquad uses vector math. In Retroquad, the lightness is computed as the length of the vector formed by the R, G and B values, normalized to the length of the vector formed by pure white (when R = G = B = 100%).

As an example, in Retroquad the lightness of pure red (100%, 0%, 0%) is 57.7%, while the lightness of pure yellow (100%, 100%, 0%) is 81.6%. Despite the maximum and minimum channel values staying the same, variations in the middle channel value can make over 40% of difference in the actual value of the resulting lightness.

With that said, I need help. I'm having trouble creating the color algorithm that will be used to generate the color transformation tables for colored lighting.

It needs a color vector computed in a very specific way, but I'm having trouble figuring out how to compute the final offset. I must compute an equilateral vector offset that, when added to XYZ2 in that spreadsheet, results in a XYZ3 vector that has L3 identical to Lsrc.

L2 is the length of the vector XYZ2. Lsrc is the length that the resulting color vector (XYZ3) should have. XYZ3 is generated from XYZ2 + a vector offset. However, the vector offset I'm calculating is wrong, because the length of the resulting color (L3) doesn't match the desired length (Lsrc).

I've narrowed the problem down to the fact that Lsrc and L2 are essentially the lengths of two sides of a triangle. So, the vector offset must be computed in a way that its length is the exact value of the third side of the triangle (but with equiaxial values), while Lsrc must belong to a vector whose axes matches the vector offset + XYZ2.

If you can solve this problem, or know of anyone who can solve it, please try to help.

This post is public so you can share it.

Files

Comments

Pritchard

I do a bit of vector math as a hobbyist gamedev, but I think this is a bit beyond my abilities. I'll have a look at it a bit more when I get the chance though.