nlguillemot · GitHub

Colors in linear spaces currently aren't acting linearly. For example, if you create an ImGui::ColorButton with (0.5,0.5,0.5), you get a pixel with exactly (128,128,128) as the RGB components showing up on your screen. This value of (128,128,128) is actually darker than mid-grey because display devices have a non-linear response to color. (see: http://docs.cryengine.com/pages/viewpage.action?pageId=1605651)
If you render to an sRGB framebuffer, then the ColorButton will appear correctly as mid-grey. However, the rest of ImGui is too bright. This problem appears many times in the screenshot thread (#123), where different aspects of ImGui are either too dark or too bright depending on whether the renderer is writing to an sRGB framebuffer or not.

Compare:
srgb
linear

In both screenshots there's an example green-blue-ish "clear color" slider. Despite having values generally over 128, it appears darker than a proper sRGB mid-grey (see below). This is because the sliders represent an already encoded sRGB color, meaning that settings the sliders to (128,128,128) will produce a color much darker than mid-grey.

toodark

For example, this also affects the color palette the in custom rendering example in the README (below). The exact middle of the palette is (128,128,0), which means that the exact middle of the palette is not actually a yellow shade of mid-grey, instead it appears much darker. The line between the red and green half should actually be yellow, rather than brown.

palette

When manipulating RGBA8 colors, it makes sense for ImGui to treat them as already encoded in sRGB space, since allocating more bits to darker colors means allocating more bits to differences in color more noticeable to humans. However, when manipulating RGBA32F colors, there's no reason to use this compression. Instead, RGBA32F colors should be in linear space, since this is required for blending to be correct. Another confusing aspect is that the font textures are linear RGBA8 (I think?), so the multiplication of non-linear RGB (from eg ColorButton) with the fonts' linear RGB in the pixel shader is just plain wrong.

There's many ways to fix these problems. First off, we should be certain about which color space should be used where in ImGui. Secondly, I suggest that ImGui outputs linear colors in the end, with an optional post-processing step to convert everything to sRGB for renderers that expect everything to arrive already encoded in sRGB. Naturally, we should try to handle this in a way that doesn't break existing ImGui applications.

Good background info for this topic: https://www.youtube.com/watch?v=LKnqECcg6Gw

Read the original on github.com ↗