gfx-rs / gfx

[maintenance mode] A low-overhead Vulkan-like GPU API for Rust.
http://gfx-rs.github.io/
Apache License 2.0
5.36k stars 547 forks source link

Inconsistent SRGB behavior between GL and DX11 #997

Open rpjohnst opened 8 years ago

rpjohnst commented 8 years ago

The gl/glutin backend uses an SRGB format for the default framebuffer regardless of whether ColorFormat is Rgba8 (like in the examples) or Srgba8. The dx11/dxgi backend, on the other hand, only uses an SRGB format for its RenderTargetView if ColorFormat is Srgba8, not Rgba8.

The gl backend's behavior is an okay default, since typically the OS compositor accepts a linear format but treats it as SRGB-like; though I'm not sure why glutin is going with SRGB since gfx looks like it calls with_srgb properly. To convert the dx11 backend to the gl behavior, gfx_device_dx11::create could override its format argument's channel type when creating its render target view.

On the other hand, this behavior makes it impossible for applications to use a different color encoding- for example, the Oculus Rift SDK requires that the application output actually-linear data because it does its own gamma correction taking its display's precise characteristics into account.

kvark commented 8 years ago

Thanks for filing the issue! I think what's going on is that GL context always gives us sRGB surface, so we simply shouldn't rely on it being consistent with what we ask. Instead, our GL backend should switch sRGB on optionally, depending on the init arguments, and the windowing backends should pass the proper value according to requested formats.

parasyte commented 6 years ago

@kvark Maybe you saw some of my earlier messages in the linked ticket. But I'm currently going insane with color space issues (again). I'm referring to the gamma example, which has a screenshot showing a linear ramp: https://github.com/gfx-rs/gfx/tree/master/examples/render/gamma#screenshot

Compare to the linear and perceptual (gamma-correct) ramps in this article: http://blog.johnnovak.net/2016/09/21/what-every-coder-should-know-about-gamma/#light-emission-vs-perceptual-brightness

In the gamma example screenshot, the mid-gray background is sRGB(188, 188, 188), which matches the mid-gray bar in the linear ramp. It also matches the "absolute whiteness" mid gray as described in the Wikipedia article. AFAICT, this is the correct behavior for the linear color space.

My question is what is the recommended way to get perceptually-correct rasterization from gfx? A smooth gradient should look like the image below, which is from the example with the sRGB framebuffer disabled (see the linked issue for details):

screen shot 2018-04-08 at 4 09 25 pm
kvark commented 5 years ago

triaged: GL context handling of sRGB is sad, leaving open for a bit longer

LukasKalbertodt commented 5 years ago

This is probably related to these:

But I'm currently going insane with color space issues

At least then I'm not the only one...