dantmnf / AMDColorTweaks

Calibrate monitors to sRGB or other color spaces on AMD GPUs, based on raw data or ICC profiles
MIT License
36 stars 1 forks source link

[enhance] support P3 primaries #8

Open brunogm0 opened 1 year ago

brunogm0 commented 1 year ago

Even if P3 content is usually in a Rec2020 container, for IO (source/destination) completeness option for P3 is needed.

bananakid commented 5 months ago

Hey @brunogm0, thanks for bringing this up!

@dantmnf, I second this request too. I studied API documentation and it looks like there's no DCI-P3 color space definition known to driver that can be added to drop-down menu easily with 2 lines of code. However I believe this can be remedied relatively easily by adding a Load ICC button for Source similar to existing one in Destination, so the button will load primaries and white point as Custom.

Such button will allow switching between even more color spaces easily. Like if you'd like to create and use a "middle ground" color space ICC between sRGB and Display P3 primaries to get a little bit punchier look to the output of your wide color gamut display without going overkill by using the entire Display P3 color space.

bananakid commented 5 months ago

I've set up the environment and loaded the solution to Visual Studio 2022, it appears @dantmnf has started working on it a while ago: <!--<Button Grid.Row="2" Grid.Column="1" Content="Load values from ICC profile..." IsEnabled="False" HorizontalAlignment="Left" VerticalAlignment="Bottom" Padding="4,2" Margin="0,4,0,0"/>--> is there…

AMDColorTweaks

But it's not ready yet. Only upon looking into project you can see that it took some extreme effort and skill to implement this tool!

dantmnf commented 5 months ago

I think it doesn't make much sense to use source gamut other than sRGB. Almost all applications that need wide-gamut output are ICC-aware, assigning the device profile with Windows Color System should be sufficient.

bananakid commented 5 months ago

@dantmnf, while I generally agree sRGB is the golden standard (and looks fine with Gamma 2.2 TRC instead of sRGB), DCI-P3 gamut is becoming a "new sRGB" as displays get better, e.g. it is the default color space of all Apple products (even photos taken with iPhone 7 end above include Display P3 ICC reference) and Samsung's Android smartphones (since Galaxy S10, and recent S22 and above uses DCI-P3 as a default option for RAW export). I'm not a fan of both (Xiaomi and POCO is better value) but market share is huge.

E.g. in macOS, iOS and some Android releases the color profile is applied system-wide (just like MCH2 does in Windows), so it affects non-ICC-aware applications without extra steps. So while it may be not the intended visual output (sRGB being the standard for mastering digital content), it's perfectly fine to have DCI-P3 color space as an option during web development to examine output for different platform such as iOS (as an example, you can quickly switch between color spaces without relaunching your browser).

Lastly, but most importantly, a DCI-P3 gamut clamp allows a much better gaming experience option than "just use all colors my display can do" or "just clamp to sRGB". On a right display it looks like "Vivid Gaming" preset (available in AMD Software control panel) done right. Besides, you can't control most games with ICC (most of the time), only a driver-level solution will do that ii about 100% of the time!

Thus a DCI-P3 option in drop-down and/or an option to load ICC will become more valuable over time.

If it's absolutely not possible to implement, would you kindly give me a hint how do I replace default 0.0 for the custom fields? See, at the moment leaving 0.0 or other wrong value in any of the custom fields of AMDColorTweaks gives you a system crash (I crashed so many times because of mistypes when testing). Replacing default 0 values of Custom Primaries and White point with sRGB/DCI-P3 values will make it possible to mitigate accidental crashing. I can build the project.

I have success in changing Parametric EOTF A0—g defaults in TransferViewModel.cs by this edit:

        public string Channel { get; init; } = "Unknown";
        public double A0 { get; set; } = 0.0031308;
        public double A1 { get; set; } = 12.92;
        public double A2 { get; set; } = 0.055;
        public double A3 { get; set; } = 0.055;
        public double Gamma { get; set; } = 2.4;

This way I can switch back to sRGB curve values quickly when I load my ICC, then TransferEdit → switch to Parametric EOTF and click OK. This reverts output back to Gamma 2.2 once applied as I described in different message with verification request). It's clunky but it's faster than to input values by hand or to load sRGB LUT from CSV.

I also believe there's an issue with describing default Transfer (if you hit Reset) because it's kind of unclear this is Inverse EOTF. It says Transfer is sRGB, but because it's applied as Inverse EOFT by display this effectively transfers display output back to it's default EOTF, which is Gamma 2.2 (for most displays). I have changed sRGB to sRGB (gamma 2.2 output) or sRGB (→ Gamma 2.2) in line 368 of TransferViewModel.cs to accommodate for that.

Unfortunately I failed setting default values for R G B of Custom Primaries in GamutViewModel.cs (as I believe it's the right place for hard-coding default non-zero custom value for R G B), it's something different to what's described in the "how-to" article I followed. I'm not that good in programming (like, I see C# code for the first time in my life) and some help in hacking your code would be very welcome!

P.S. Speaking of games, while skimming through AMDColorTweaks code I found a Transfer option spec that is labeled as Rec. 709 (AMD definition). I have tested it by eyeballing against a true Gamma 2.4 and it's quite close, but it doesn't pass the ACES test. AMDColorTweaks – Rec  709 Transfer So according to Rec. 709 spec, the transfer formula for EOTF are different that for sRGB. Would you kindly clarify if AMDColorTweaks uses a different transfer function formula for this option? See, if I understand code correctly, it's just using A0=0.018, A1=4.5, A2=0.099, A3=0.099, g=2.2 with sRGB's transfer function formula, which to me appears to be wrong. This this can be fixed by using the appropriate formula (I'm not sure if regular or inverse one from Wiki), ultimately leading to users having all most common inverse EOTF transfers for Destination: sRGB, Gamma 2.2 and Gamma 2.4. Thus we will have an option for full Rec. 709 emulation (which is very welcome because it makes a huge difference in game presentation, e.g. Resident Evil 2+ remake all have Rec. 709 mode).

bananakid commented 5 months ago

@dantmnf, I managed to figure out how to add loading of ICC values to Source since most of the code was already there. I also tweaked the UI a little bit here and there so it's pixel perfect at 200% scaling. I'll be happy to contribute this back to the project!

AMDColorTweaks