gfx-rs/wgpu-rs

Incorrect LoadOp::Clear results

vickles opened this issue · 3 comments

When using a clear color with color components that aren't either 0 or 1, the contents of the render target don't contain exactly the color provided to the LoadOp. I modified hello-triangle to clear with a middle grey instead of Color::GREEN, as bellow:

color_attachments: &[wgpu::RenderPassColorAttachment {
    view: &frame.view,
    resolve_target: None,
    ops: wgpu::Operations {
        load: wgpu::LoadOp::Clear(wgpu::Color { r: 0.5, g: 0.5, b: 0.5, a: 1.0 }),
        store: true,
    },
}]

A snippet of the result:
hello-triangle

The grey here is 0.73, 0.73, 0.73, brighter than the grey expected. I initially noticed this in a project I was working on using 0.7.0, and I just reproduced again on both 0.8 and wgpu-rs master.

Hi! 👋

The color values that are rendered here will depend on the color space used for the render targets. The idea is that we can choose which color space to use for textures in general by specifying sRGB or not.

There's a small section in the WebGPU specification about this at https://gpuweb.github.io/gpuweb/#texture-formats that mentions this, but in general it should work the same way as most other graphic APIs/applications that use color spaces. I'm not sure of the best resource for this, but there's some explanation in articles like https://learnopengl.com/Advanced-Lighting/Gamma-Correction that talk about how it works in OpenGL, so most of the concepts are still relevant.

In this case the 0.73 value can be calculated (roughly) from something like 0.5^(1/2.2) ~= 0.73.

Thanks for the help, this was definitely on me. By setting the swapchain format in hello-triangle to wgpu::TextureFormat::Bgra8Unorm things worked as I'd have expected.

I'm gonna have to go have a solid read about sRGB color spaces now :)

Awesome :) glad it's working now!