I am using the SkiaRenderer to render a 2d user interface on top of a 3d scene, basically:
SkiaRenderer → RenderEntity (AfterScene) → RootScene → SceneWindow
The interface is intended for the end user, not just for debugging.
Unfortunatly with the new Angle implementation of the SkiaRenderer colors are not rendered correctly.
The differences are subtle and they seem not to show when posting images here, I’ll attach a zip containing screenshots showing the issue.
Also and this is (even) more of a problem the font rendering got worse. The difference also seems subtle but it makes a big difference with small fontsizes.
Tested with 2021.4.0-0321 (Angle) and 2021.4.0-0265 (Old).
Is there any chance this will be addressed in the near future? Is it possible to get the old implementation back either directly with stride or as extra package?
The way it is now, it is not really passable imho and I really don’t want to go back to an old preview.
Switched to gamma color space now as demonstrated in the other thread. Spend a lot of time tweaking, colors, materials, lights and postfx to get the “old” look of the 3d scene back. In my opinion a regular user shouldn’t have to jump through those hoops “just” to get correct color representation and nice font rendering.
Also interesting that “old” renderer in 2021.3.3 behaves the same as “new” renderer - in between was a SkiaSharp update from 1.68.2 to 2.80.3. In other words there was only a short period where it looked “correct” (SkiaSharp 2.80.3 & NV_interop_2). But honestly I’ve no idea why that particular combination produced the correct result :/
Tried that as well - then the colors are completely off. The render target format is still R8G8B8_sRGB and we can’t remove the _sRGB on the render target view, that would only work for typeless formats. But one can’t setup a typeless swap chain I believe. And once it’s present, the hardware conversion will apply.
Is the 3d scene rendered to a different surface in between or is it directly rendering to the back buffer of the swap chain? If it’s rendering into an intermediate target, then I wonder whether it would be an option to setup the swap chain with a non-sRGB format so - as you say - we’re truly in gamma space after the scene is rendered?
Like I said, that didn’t help. Setting it to non-linear when device is linear and vice versa breaks the colors completely. Tried a lot of combinations there - even exposed all the subtle settings as pins once and clicked my way through by trial and error but with no luck.
the rendering issues with small text also look more like a blending/alpha issue. might this help?
Color management steps
unpremultiply if the source color is premultiplied – alpha is not involved in color management, and we need to divide it out if it’s multiplied in
linearize the source color using the source color space’s transfer function
convert those unpremultiplied, linear source colors to XYZ D50 gamut by multiplying by a 3x3 matrix
convert those XYZ D50 colors to the destination gamut by multiplying by a 3x3 matrix
encode that color using the inverse of the destination color space’s transfer function
premultiply by alpha if the destination is premultiplied
If you poke around in our code the clearest place to see this logic is in a type called SkColorSpaceXformSteps. You’ll see it as 5 steps there: we always merge the innermost two operations into a single 3x3 matrix multiply.
the settings for alpha/blending seem to be independent of the color management (RGB), but I couldn’t find any settings for the alpha channel or blend mode.
this sounds interesing:
In Skia, all color sources are converted into the destination color space and the blending is done in the destination color space by applying the linear blend function. Skia does not convert into a linear space, apply the linear blend, and convert back to the encoded space. If the destination color space does not have a linear encoding this will lead to ‘incorrect’ blending. The idea is that there are essentially two kinds of users of Skia. First there are existing systems which are already using a non-linear encoding with a linear blend function. While the blend isn’t correct, these users generally don’t want anything to change due to expectations. Second there are those who want everything done correctly and they are willing to pay for a linearly encoded destination in which the linear blend function is correct.
I’ve recently asked in the skia forums about this issue and got an answer yesterday. the skia developers have added a new color type 3 weeks ago that should work with our setup. however, we have to wait until SkiaSharp adds this or we have to make PR and push for it.
That probably doesn’t exist in SkiaSharp yet, but when it does, I think the correct SkSurface configuration to get linear blending would be to use that color type, and a linear color space (eg, SkColorSpace::MakeSRGBLinear).
Couldn’t find out how they choose the version they use as base, but I assume it will take some time till “the fix” arrives in gamma. In my opinion there should be some disclaimer / hint, explaining the issue. Maybe in the (nonexistent) SkiaRenderer Help Patch.