Closed expenses closed 3 years ago
Actually, the web format "Bgra8Unorm" is highly misleading. It's not the final output format for the canvas (I should remove that check for the format).
Shaders normaly operate in linear space, so that you can properly calculate your lightning. The API normaly takes care of converting textures that are encoded in sRGB gamma to linear space and also makes sure to later convert the back buffer into the correct output format for your system (currently mainly sRGB based). We in the shader make sure that the color values we upload are in linear space, since native APIs expect this behavior.
The web is weird. The WGL and to an extend WebGPU don't specifiy the color spaces / gamma encodings .... And most browsers actually expect you to output sRGB from your shaders (so if you would like to have properly looking shaders / lighning you would need to do sRGB -> linear -> shader operations -> SRGB).
To quote:
The color space of content displayed in an HTMLCanvasElement via 2D Canvas, WebGL, or WebGPU, is not explicitly defined. The de facto behavior of most browers is to limit this content to the sRGB color space, with 8 bits per color. This presents a significant limitation compared to the capabilities of display devices and the demands of content creators.
https://github.com/WICG/canvas-color-space/blob/main/CanvasColorSpaceProposal.md
Since we don't do any shading / lighning here, we could indeed just upload the sRGB encoded data, without converting it into linear space.
It should most likely a second fragent shader that is gated behing a compile flag ("target = web...").
Please have a look at the current HEAD were I tried to fix the issue.
Awesome! Great write-up and the changes you've made solve this problem well. The one thing I'd suggest is that instead of doing #[cfg(target_arch = "wasm32")]
, you add a feature flag and use #[cfg(feature = "web")]
, as a native wasm32
target could use wgpu with a srgb render attachment.
Added the suggested changes to HEAD.
Perfect! Think we can close this now.
I would like to be able to run this on the web, however as mentioned in https://github.com/hasenbanck/egui_wgpu_backend/issues/9, the web display format is non-srgb, e.g.
Bgra8Unorm
. We're currently converting from linear colour to srgb colour in the vertex shader which looks wrong on wasm but if we change this line: https://github.com/hasenbanck/egui_wgpu_backend/blob/9d03ad345d15d1e44165849b242d3562fdf3e859/src/shader/egui.vert#L26 toThen the output looks perfect on wasm!
The best way to go about this is probably to have 2 shaders, and switch between them either on
output_format
or a feature flag.