Colors are not displayed correctly when using the Angle version of SkiaRenderer and font rendering is worse

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.

I guess this is related to:

SkiaRenderer.7z (75.9 KB)

Did you try switching the color space like discussed in the other thread?

Yes but that messed up the colors of the 3d scene so I didn’t pursue it further.

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.


Seems we’re not the only ones:

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 :/

AfterScene is also after PostFX and the render target is in gamma space. So SkiaRenderer should use gamma space as color space setting for that stage.

Maybe that worked for some versions…?

render target is in gamma space

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?

Obviously I don’t know what I am talking about but might setting/changing the skia colorspace help?

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.

Ah ok I thought you meant stride colorspace.

the rendering issues with small text also look more like a blending/alpha issue. might this help?

Color management steps

  1. 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
  2. linearize the source color using the source color space’s transfer function
  3. convert those unpremultiplied, linear source colors to XYZ D50 gamut by multiplying by a 3x3 matrix
  4. convert those XYZ D50 colors to the destination gamut by multiplying by a 3x3 matrix
  5. encode that color using the inverse of the destination color space’s transfer function
  6. 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.


adding this info here as well:

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.

We just recently added a new SkColorType that corresponds to a HW _SRGB format:

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).

related issue: