Rick Brewster Posted May 31 Author Share Posted May 31 15 hours ago, _koh_ said: and those two give me the same result with handful of rounding errors. This probably won't help, as I've already configured everything to use Float32 by default, but sometimes it's still useful to manually set the Precision property to Float32. So you should try that out to see if it helps accuracy further. In the Mandelbrot fractal effect implementation, it uses a CompositionEffect. For some reason I had to manually set it to use Float32, otherwise it was producing incorrect output. And Hue/Saturation's use of a particular custom pixel shader was causing an issue in one of @BoltBait's plugins -- even though the device context's EffectBufferPrecision was already set to Float32, and the render target (the bitmap attached to the device context) was Float32 as well, and nothing was set to anything else. There may be an underlying mistake somewhere else in the whole effect graph, maybe even in how the source images are created, but I was not able to find one. Quote The Paint.NET Blog: https://blog.getpaint.net/ Donations are always appreciated! https://www.getpaint.net/donate.html Link to comment Share on other sites More sharing options...
_koh_ Posted May 31 Share Posted May 31 1 hour ago, Rick Brewster said: This probably won't help, as I've already configured everything to use Float32 by default, but sometimes it's still useful to manually set the Precision property to Float32. So you should try that out to see if it helps accuracy further. Thanks. I'll look into that. One thing I know is sRGB -> DeviceColorSpace.ScRgb -> sRGB sRGB -> LinearizedColorContext -> sRGB give me slightly different results and later is more accurate than former. Quote Link to comment Share on other sites More sharing options...
Rick Brewster Posted May 31 Author Share Posted May 31 On 5/30/2024 at 5:20 PM, _koh_ said: going through scRGB is more useful than I thought. Microsoft intends for scRGB to be a sort of interchange color space. They have placed big bets on it as the "CCCS", or Common Composition Color Space. It's what DWM uses for composition when the display is set to HDR or WCG mode, it's what DXGI requires for FP16 swapchains, etc. They declare that it can encode any physically possible color. The modern rendering/presentation pipeline uses a Flip Mode + FP16 swapchain encoded as scRGB, after which DWM transforms to the display's color space/profile (this is called "Automatic Color Management" which is always enabled in HDR and WCG mode). One of the key things that PDN's CME wrapper does is to use linearized color profiles as interchanges between non-linearized profiles (those with TRCs, i.o.w.). So if you use CME to transform from DP3 to sRGB, it will convert that into a chain of 3 effects that go from DP3 to DP3-Linear, and then from DP3-Linear to scRGB via a 4x4 matrix transform (not via D2D's CME), and then from scRGB to sRGB through the standard sRGB transfer function (not via D2D's CME). As best I can tell this eliminates as much clamping as possible, and it made a big difference. But if you strictly require [0,1] clamping, then add a ClampEffect to your graph. Quote The Paint.NET Blog: https://blog.getpaint.net/ Donations are always appreciated! https://www.getpaint.net/donate.html Link to comment Share on other sites More sharing options...
Rick Brewster Posted May 31 Author Share Posted May 31 2 hours ago, _koh_ said: give me slightly different results and later is more accurate than former. Is this with PDN's CME, or with D2D's CME? Asking for the linearized version of sRGB should be special cased to hand you back scRGB, assuming you created the sRGB color context through WIC (via ExifColorSpace.Srgb) or D2D (via DeviceColorSpace.Srgb). It should produce identical results if you're using PDN's CME. If not, show me your code and I can look into it to see if this is a mistake or not. Quote The Paint.NET Blog: https://blog.getpaint.net/ Donations are always appreciated! https://www.getpaint.net/donate.html Link to comment Share on other sites More sharing options...
_koh_ Posted May 31 Share Posted May 31 51 minutes ago, Rick Brewster said: It should produce identical results if you're using PDN's CME. If not, show me your code and I can look into it to see if this is a mistake or not. My bad. Seems like this is PDN 5.0 to 5.1 difference. When I ported my plugins to 5.1, I found sRGB <-> Linear is more accurate. I thought this has to do with DeviceColorSpace.ScRgb to LinearizedColorContext but... 58 minutes ago, Rick Brewster said: and then from scRGB to sRGB through the standard sRGB transfer function (not via D2D's CME). Yeah, this is the reason. Now it's doing actual math instead of table lookup. Same reason I was using my own shader for sRGB <-> Linear in 5.0. Can you also give DP3 a special treat? Which is using the same TRC as sRGB. Quote Link to comment Share on other sites More sharing options...
Rick Brewster Posted May 31 Author Share Posted May 31 1 hour ago, _koh_ said: Can you also give DP3 a special treat? Which is using the same TRC as sRGB. If you want to convert between DP3 and DP3-Linear, and if it's using the same TRC as sRGB, then you can just use SrgbToLinearEffect / LinearToSrgbEffect. That's what PDN's CME wrapper uses for sRGB <-> scRGB. Quote The Paint.NET Blog: https://blog.getpaint.net/ Donations are always appreciated! https://www.getpaint.net/donate.html Link to comment Share on other sites More sharing options...
_koh_ Posted June 1 Share Posted June 1 1 hour ago, Rick Brewster said: If you want to convert between DP3 and DP3-Linear, and if it's using the same TRC as sRGB, then you can just use SrgbToLinearEffect / LinearToSrgbEffect. Ah maybe. But if (ColorContext == DisplayP3) is more difficult part I guess. PDN already doing this for sRGB, right? If there is a simple way to do this, I can also treat Adobe RGB separately. As I reported, D2D CME's handling of Adobe RGB is a bit iffy. Quote Link to comment Share on other sites More sharing options...
Rick Brewster Posted June 1 Author Share Posted June 1 DisplayP3 isn't a named profile, you have to provide it yourself and use CreateColorContext(ReadOnlySpan<byte>). You can get a DP3 profile from any number of places, and there's no guarantee they specify exactly the same things. So no, you can't just do (ColorContext == DisplayP3). Same as you can't with an sRGB profile created from a span of bytes. You can't even use the description in the profile itself, as those are often abbreviated or truncated in various ways to save bytes. D2D's handling of AdobeRGB is based on the profile that WIC creates when you use ImagingFactory.CreateColorContext(ExifColorSpace.AdobeRgb). So, from what I understand, it's not actually D2D's fault. If WIC's Adobe RGB profile is iffy then you can provide your own profile and use CreateColorContext(ReadOnlySpan<byte>). That way you can find one that behaves in the way you expect. Edit: btw the DP3 profile that PDN uses internally, to populate Image->Color Profile, is @saucecontrol's from https://github.com/saucecontrol/Compact-ICC-Profiles/tree/master/profiles (DisplayP3-v4.icc) Quote The Paint.NET Blog: https://blog.getpaint.net/ Donations are always appreciated! https://www.getpaint.net/donate.html Link to comment Share on other sites More sharing options...
_koh_ Posted June 1 Share Posted June 1 10 hours ago, Rick Brewster said: You can get a DP3 profile from any number of places, and there's no guarantee they specify exactly the same things. So no, you can't just do (ColorContext == DisplayP3). Same as you can't with sRGB. I see. Thanks. Thought maybe I could treat ExifColorSpace.AdobeRgb profile separately, but once assigned to the image, it already has different bytes so I gave up😅 edit: Ah, since I learned how to convert RGB to XYZ, I can extract RGB primaries from ColorContext. A bit hacky but can test any profile. 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.