-
Notifications
You must be signed in to change notification settings - Fork 60
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make it possible to specify a custom white point #14
Comments
@sidred has some experiments going on for this, so I'm currently saving this for him. |
Here is a rough working version of what I have so far. Use a single color struct with phantom types for color space and white point and define a few common color spaces.
Color spaces are defined by an empty trait and empty struct variants. RgbVariants need the red, blue and green points as part of the trait to help in conversions
The WhitePoint trait returns the Yxy values for the white point (for conversion use) and implemented for empty structs
So all colors will just be traits implementing getters and setters and the rest can be implemented by default (like add, substract, mix etc)
Here is how the conversions would work xyz -> lab (whitepoint aware)
The end user usage will be
Some advantages of this are:
To-Do / Questions:
|
link to a proof of concept repo - https://github.com/sidred/color_space |
I'm not sure this level of generalization is the way to go. Some things I'm a bit concerned by from the start:
I can see the advantages, but I can't yet say if it's really worth making such a drastic change this early. I mean, it has only been downloaded 53 times from crates.io and I have barely seen how it's used by the users. We can, of course, cherry pick the parts that are applicable today, like the white point phantom type for the spaces where it matters. Regarding you to-do/questions:
|
I get your concerns regarding the ergonomics and I am not sure of the best way to proceed. Encoding the color space and white point seems specially useful for the rgb variants. It makes the conversions a lot simpler and we can support a lot more variants easily.
|
I guess we would end up in more or less the same situation as with the
That's a bit of a problem...
Fair point, in that case.
Yea, it's something, but comes at a runtime cost. We would also need
The primaries for sRGB and AdobeRGB are different, so the conversion is not that trivial. AdobeRGB would need its own HSL/HSV types if it's supposed to be compile time checked.
We'll see how that ends up. I'm more geared towards having them encoded into the library as constants, to avoid runtime costs. A build script can also be used to generate them.
Yes, the point of the white point is to have a reference that says what "white" is. Having a color without a white point is not very useful. You could say that it's currently fixed to D65 with the 2 degree observer, but making it parametric will be quite useful and I'm all for that. The types in the current design that would need a white point parameter is XYZ, the future xyY, Lab, Lch and perhaps Luma, since none of those have it built into their specifications. sRGB uses D65 and that affects HSV and HSL, as well. I'm currently ignoring CMYK, since it's a special kind of crazy, but the naive variant is affected in the same way as HSL and HSV. The way I see it is that we are actually discussing two separable problems here:
I'm still skeptic towards your proposal for the first problem, since I think it's a bit early to know if it will be too limiting for the user, but I think the way you have implemented variable white points has a very good potential. I'm suggesting that we isolate the white point part and try to make it work in the big picture. We can put the other proposal in a separate issue to keep this discussion focused on white points. What do you think about that? |
So implement Rgb<WP,T>, Srgb<WP,T>, Xyz<WP,T> etc? This implies ignoring all other rgb variants ( excpet srgb and adobergb ) listed in http://www.brucelindbloom.com/Eqn_RGB_XYZ_Matrix.html for now. I was wrong earlier. Xyz and Yxy are white point independent. The chomatic adaptation formulas need the xyz value of the actual whitepoints for conversions. This is what I was referring to earlier. |
Yes, the adaption will have to be performed in XYZ space. The matrices in my link has the white points encoded into them, so it's just a matter of combining type pair and matrix. I guess D65 can be used as the default, since that's what the common modern spaces seem to be using, so |
All the ICC color profiles use D50 as the reference. So sRGB with D50 might also be fairly common even though D65 is the defined white point. There is actually no XYZ and XYZ. The white points value are defined in the XYZ/Yxy space. These color spaces do not have a concept of white points. |
Sure, they are, but I'm still sure we can wait with that part until the basics are in. I feel like that's a deeper hole than what it looks like from above, and I'm trying to slice all of this down to bite size problems.
They will still have to remember the white point to make conversions like sRGB -> XYZ -> Lab -> XYZ -> sRGB sane. The white point information will otherwise be lost in the sRGB -> XYZ step. |
I'm nominating this for version 0.3.0 |
So lets focus on the CIE types for now. So we will have
and do that for each of the types Xyx, Yxy, Lch . Does that make sense? I am not convinced in having a white point for Xyz and Yxy.
So in your example does it matter if the intermediate lab's are using d50 or d65 white points? All that matters is that the sRGB in the end has the same white point as the source sRGB, white can be specified in the type for the output. |
Lab is normalized using the white point, so it matters a lot. I think it's also nice to get compile time errors when you are trying to use D50 adapted colors as if they were D65. |
We can add a note stating the white points for Xyz and Yzy are for helping in conversion and not really relevant on these color spaces. Do we still keep a NoWhitePoint type for the WhitePoint trait or just use D65 as the default for Xyz and Yxy? I think its nice to have the NoWhitePoint type we define the default white point x and y coordinates. I makes things clearer. |
What's white in NoWhitePoint? Would it be whatever it's converted to or is it the same as the unit spectrum (x: 0.3, y: 0.3)? |
I haven't come across the default white point values. What is your source for the 0.3 values? |
Sorry, 1/3, not 0.3.
Over at https://en.wikipedia.org/wiki/White_point. I haven't yet checked other sources, but it looks like that's how XYZ is designed. |
Yeah look like the white point for Illiminant E. Using Yxy = (1, 0.3, 0.3) gives XYZ as (1,1,1) and that will avoid any scaling in XYZ <-> Lab conversions |
Exactly. The concept of no white point feels a bit strange, but thinking about it makes me think that it's just signals without interpretation. Conversion to and from it would not cause any chromatic adaption, since there is nothing to adapt to, right? |
looks like the conversion will cause chromatic adaptation. Look at the matrices for white point E at http://www.brucelindbloom.com/Eqn_ChromAdapt.html. None of them are identity matrices. I'll start with the NoWhitePoint (1/3, 1/3 ,1.0) and lets see if it makes sense. |
That's why I thought it made little sense. You can pretend that a D50 color is an E color, but they wouldn't look the same. I would, by the way, suggest calling it E, since that's what it is. |
Make color spaces white point aware This is a breaking change. - All colors now have an additional trait bound on WhitePoint. - All "new" methods on colors now assume a default white point of D65. Use "with_wp" method to get color with another white point. - Delete tristimulus module. - Add Xyz values for standard observers and illuminants (D65, D50 etc). - Implement methods for chromatic adaptation using Bradford, VonKries and Xyz scaling. - Add Srgb primaries for Rgb <-> Xyz converison. - Make Rgb to luma conversion to convert via xyz. closes #14
Some color conversions depends on a white point, and Palette is currently making some assumptions in this area. Avoiding these assumptions would of course allow a lot more freedom, so it would be nice to find a good way to customize which white point to use when converting. Even better if it was encoded into the color types, themselves, when relevant.
The text was updated successfully, but these errors were encountered: