Closed mahkoh closed 1 week ago
The tiny_skia::Pixmap
docs does mention that premultiplied colors are used.
Docs might be a more clear about it, but I wouldn't call this feature undocumented.
I was aware that the colors are both pre-multiplied and sRGB. But the order of operations is undocumented. Vulkan images assume the opposite order of operations.
What do you mean by "order of operations"? Are you expect me to document how to use resvg output with Vulcan? What's the point?
What do you mean by "order of operations"?
Vulkan assumes the first, resvg does the second.
Sorry, but that's too Vulkan specific. It has nothing to do with resvg. In fact, resvg follows the Skia logic here, so blame them instead.
The current behavior is very surprising because it is useless. Premultiplication is only relevant if you have transparency. If you have transparency, then you need to do blending. Blending can only be done correctly in linear space. Therefore you must first convert the sRGB values to linear space. But to get the sRGB values, you must first undo the premultiplication done by resvg. It's a huge waste of time.
But do as you wish.
There is nothing surprising about the current behavior. Every 2D graphics library I know works in the same way: Skia, CoreGraphics, Qt, Cairo.
Blending can only be done correctly in linear space.
Sort of. But Most 2D graphics libraries do not do this. resvg
works "correctly" according to the SVG spec. That's the only thing that matters.
Assume that an SVG contains the following CSS color:
rgb(255 255 255 0.5)
.Then resvg will output the following bytes:
[128, 0, 0, 128]
.Recall that CSS colors are in sRGB space. This means that resvg emits color channels that are pre-multiplied in sRGB space.
This is not incorrect, but it is incompatible with the vulkan R8G8B8A8_SRGB format. If one uploads the output of resvg to such an image and uses it in a shader, the sampled colors will be incorrect. This is because vulkan performs the sRGB -> linear conversion directly on the electrical values.
This should be documented so that users know that they must manually convert the bytes emitted by resvg if necessary: