-
Notifications
You must be signed in to change notification settings - Fork 61
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 color spaces white point aware #56
Conversation
To-Do:
|
Looks like a good start 👍 Just a few things I thought about:
|
Not really. Its just that I have to add a few more and right now its not clear what the correct x,y values are. I''l remove it in the end when I add the remaining white points.
D65Fov10 is already camel case. Are you talking about something else? Oh and if you can think of a better name, let me know :)
Ok |
Ok, I was just checking. I have been thinking about phasing out some macros, in general, but that's a separate topic.
Those are correctly cased. I'm talking about the type parameters, like
I'll see what I can come up with, but you have most likely witnessed how bad I am at naming things. The name "Palette" is a masterpiece among my creations ;) Speaking of which, you are always welcome to suggest alternate names for things I contribute with. |
Yeah, those need to be changed. I thought trait bounds were all caps, but they need to be camel case too. |
They are temporary types, so it's the same rule for them as well, but they are usually only one letter long, so it's easy to forget :) |
I have implemeted the white point for lab and changed the into iterator from
to
I get an error for converting xyz to rgb
error
This works
Is there any other altenative? |
Is the white point of |
For now I am not implementing the White Point for Xyz and Yxy. I'll implement it for everything else and only then add it in for Yxy and Xyz if it makes sense. I've been using the convert as notation for now. Let's see how it shapes up. |
Well, it can't possibly know what white is if it's not specified, so that's most likely the reason :) |
Tests still fail due to color enum. I will update it next. |
Why are you renaming almost every color to |
I am expecting only a small subset of users to care about white point, so i was trying to make it simple for them. This also has the effect of being compatible with the earlier version of the library. I have defined the original colors to use the default white point
I am expecting this to work as usual before and after the white point change
For users who need a custom white point will need to use
Is it unnecessary since we are setting the defaults in the struct definition? |
Oh, ok. Well, most users should not be affected by the change, unless most users uses an other float type than f32. Adding the extra white point shouldn't be a huge step from changing the precision, and they can always make their own custom aliases when they need to. I see the point and I understand that it may become tedious in some situations, but the fact that users can make their own aliases makes me think that it's probably not such a big deal, after all. |
I'll revert to using the short names. Having the defaults pretty much makes it unnecessary. |
We can do something about it later if it turns out to be a problem. There may even be a better solution then. Who knows? You have probably noticed, but type aliases and the documentation don't really play nice together. You can't see any implementations for aliases, which is why I made the links for the alpha aliases. You can write |
Tests still fail for Srgb, Gamma rgb and color enum conversion. |
I have mostly skimmed through the changes, but I think it looks good so far. The only things I can really comment on at the moment is that I'm leaning towards making the white point fields public, to allow You can't know what XYZ for white is if you haven't specified a white point, and the requirement of |
The project builds, but tests fails due to private _wp field.
I was just thinking the same thing. I can't think of a downside to this. Is wp a good enough name or should I make it white_point (instead os _wp).
I am not convinced that Xyz and Yxy need a white point.
But the same is not the case for the other colors.
Also, The conversions Color -> Xyz will depend only on the source white_point and Xyz -> Color will only depend on the target white point and we should not run into any issues in the conversions. |
We must not mix up perceptive and numeric equality. The Take this snowy house, for example. The snow looks mostly white because the colors are adapted to sunlight, but it's blue in the shadows, where it's only illuminated by the sky. We could adapt the colors to make the shadows look white/gray, but the rest would then look yellow. Both the sunlit and shadowy snow is still "white", though, since the snow will reflect more or less equal amounts of every wavelength. |
I'll continue my example with some code and numbers. Let's pretend that the sky itself is a let snow_shadow: Rgb<D50, _> = Rgb::new(1.0, 1.0, 1.0);
let snow_shadow_xyz: Xyz = snow_shadow.into();
//This is no longer numerically the same as Rgb::new(1.0, 1.0, 1.0),
//meaning that it will look different.
let snow_shadow_photo: Rgb<D65, _> = snow_shadow_xyz.into(); Let's say that we want to know if the shadowy snow reflects the same amount of light as the sunlit snow, and therefore should look the same under the same light. That's where we have to do a chromatic adaption: let snow_shadow: Rgb<D50, _> = Rgb::new(1.0, 1.0, 1.0);
let snow_shadow_xyz: Xyz = snow_rgb.into();
//Chromatically adapt from D50 to D65,
//or move snow from the shadow into the sunlight
let snow_photo_xyz: Xyz = snow_shadow_xyz.adapt::<D50, D65>();
//This should now be equal to Rgb::new(1.0, 1.0, 1.0)
let snow_photo: Rgb<D65, _> = snow_photo_xyz.into(); The white point does matter to XYZ, but not in the same way as to RGB. It's still important for knowing how the signals are perceived, while RGB needs it to know what the signals should be. This is the first example again, but with a white point aware let snow_shadow: Rgb<D50, _> = Rgb::new(1.0, 1.0, 1.0);
let snow_shadow_xyz: Xyz<D50, _> = snow_shadow.into();
//Adapt our brain to the sunlight, so the same numbers, but different white point.
let snow_shadow_photo_xyz: Xyz<D65, _> = snow_shadow_xyz.with_white_point();
//This is no longer numerically the same as Rgb::new(1.0, 1.0, 1.0),
//meaning that it will look different.
let snow_shadow_photo: Rgb<D65, _> = snow_shadow_photo_xyz.into(); ...and the second example: let snow_shadow: Rgb<D50, _> = Rgb::new(1.0, 1.0, 1.0);
let snow_shadow_xyz: Xyz<D50, _> = snow_rgb.into();
//Chromatically adapt from D50 to D65,
//or move snow from the shadow into the sunlight
let snow_photo_xyz: Xyz<D65, _> = snow_shadow_xyz.adapt();
//This should now be equal to Rgb::new(1.0, 1.0, 1.0)
let snow_photo: Rgb<D65, _> = snow_photo_xyz.into(); It's still possible to do the same calculations without the white point on |
Yeah, Xyz also needs an illuminant. For chromatic adaptation needing to do xyz_src to xyz_dst pretty makes this necessary. I'll make the change. Right now the Color conversions do not take chromatic adaptation into account. They only convert from and into the same white point. What I am concerned about needing white point annotation in conversions. For example, rgb -> hsb should just work assuming the same white point without having to specify it. White Point annotation is only necessary when chormatic adpatation is needed.
Can we use the existing FromColor and IntoColor to make this happen? |
just run into a usablility issue. This code fails
with the following error even though the default (D65 and f32) are defined for the lab space.
This works
Can we do anything to infer the default white points? |
I think that's good. Chromatic adaption can be more destructive than normal conversion, so I think it should be done explicitly.
Those conversions should just work. The white point becomes a part of the type, so it should be restricted in the same way as the float type. I wrote them out in my example to make sure it was clear, but it should only be necessary if something other than
I don't know. It my depend on the context. Is it just the struct syntax? Is it only when the type isn't specified anywhere else? |
So
You can check the last commit for all the places I has to explicitly specify the type. It's pretty much everywhere. |
That's not what I meant. I think it's good that chromatic adaption is explicit and not a part of
Oh, no! It looks like we have stumbled upon an unfinished feature. See this playpen: http://is.gd/qFU2o5 I'm not sure what to do here... This problem will also be present in the planned Edit: this is the closest to a workaround I have found, but I don't like it: http://is.gd/myfW21 |
How is HashMap default hasher impelmentation working then? |
Looks like We could do something similar: http://is.gd/AIkZ09 But the situation is different, because the white point is never passed to a function. |
We can use something like this http://is.gd/do9sEJ |
It never ends, does it? 😖 We should make sure we use the correct one for sRGB, and maybe provide the others as well. Maybe group them in modules. I don't know. At least make sure sRGB conforms to its standard for this PR, and maybe improve the rest later. We must draw the line somewhere. |
Does everything look good. As as far as I can see I have made all the recommended changes. |
There are very small differences between, like in the 4th decimal place 0..3271 and 0.3272. We should be ok. |
I suppose it's fine, then. I hope nobody thinks this is suitable for super high precision life-at-stake applications 😉 I'm still checking some of the new stuff, but I'm quite sure there's nothing more. Just that typo. |
I can't find the |
Yup, not sure if it makes sense |
It does, as a regression test, to check that nothing odd is going on. That, and the typo fix, should be all. |
Let me merge all commit and take another look |
Ok, just tell me when you feel ready. I'll be busy with all sorts of other things, so no hurry. |
5585a51
to
a8e6273
Compare
Fixed up a few typos and changed the docs for chromatic adaptation, Xyz( referenced only D65 ) and Yxy. Should be good to go! |
Nice! I'll, however, have to postpone my final review until tomorrow. |
///X is the scale of what can be seen as a response curve for the cone | ||
///cells in the human eye. It goes from 0.0 to 0.95047. | ||
///cells in the human eye. It's range depends |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"It's" should be "Its". Same for z
.
I found a couple of typos that I couldn't ignore, so I took the liberty to point out a couple of strange indentations as well. It's otherwise great and I would have merged it straight away. |
Done! |
Great! Thank you! It's exciting how this library has grown from the original idea of just being a simple color calculations library. It's still a color calculations library, and it's still about as simple to use, but it has so much more power. And more is coming. @homu r+ |
📌 Commit 2ed7fd2 has been approved by |
⚡ Test exempted - status |
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
This is a breaking change.
closes #14