Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Yesterday, when I was implementing #18, I noticed text was rendering differently using
gfx
vswgpu
.Here is how it looked when using OpenGL:
Here is how it looked when using Vulkan:
It's a subtle difference, but the OpenGL version is way more readable (look at the uppercase
I
glyph). The difference? Gamma correction.This made me start researching about color spaces and how to deal with them, which almost drove me to insanity... But I think I figured out the problem, and the solution is quite simple.
Monitors display colors in the sRGB color space. Therefore, if you have a framebuffer with a
(0.5, 0.5, 0.5)
color value, it will always display the same grey, independently of the format of the framebuffer.wgpu_glyph
stores a cache of glyphs in a texture of alpha values. This value is then combined with the font color in thewgpu_glyph
fragment shader. Then, the blending stage happens.The blending stage basically combines the color outputs of the fragment shader with the color of the target buffer. If your buffer is not marked as
Srgb
, then the values from the target buffer will be read as if they were linear and combined with the fragment shader outputs directly. Finally, the combined color will be written directly into the target buffer. Thus, you end up with linear values in your frame buffer, which then are displayed by your monitor as if they were sRGB. Bad! This causes grey values to look darker than they should, like you can observe in the Vulkan example above.However, when the target buffer is marked as
Srgb
, the values will be read asSrgb
and converted into linear before blending. Additionally, the combined color will be converted back intoSrgb
on write. This is what the OpenGL implementation was doing.This PR fixes the
wgpu
graphics backend to useSrgb
buffers for textures and render targets, except for theSwapChain
which we are currently copying into. It also fixes font and clear color, by converting theColor
type (which is sRGB) into linear. I have also added acolors
example to test that colors are rendering properly in both graphics backends.