Skip to content

Commit 8b4adf4

Browse files
authored
Desktop: Fix Vello rendering colors with doubly-applied gamma by converting to linear in the shader (#2998)
* Fix gamma issue by applying tone mapping in the shader Vello renders it's values to an RgbaUnorm texture but if we try to use this in the main rendering pipeline which renders to an Srgb surface gamma mapping is applied twice. * Add comment explaining why we do this to the shader * Rename variables
1 parent 2e13964 commit 8b4adf4

File tree

1 file changed

+19
-7
lines changed

1 file changed

+19
-7
lines changed

desktop/src/render/composite_shader.wgsl

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,29 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
4949
return ui;
5050
}
5151

52-
let vp_cord = (in.tex_coords - constants.viewport_offset) * constants.viewport_scale;
52+
let viewport_coordinate = (in.tex_coords - constants.viewport_offset) * constants.viewport_scale;
5353

54-
let ov = textureSample(t_overlays, s_diffuse, vp_cord);
55-
let vp = textureSample(t_viewport, s_diffuse, vp_cord);
54+
// Vello renders its values to an `RgbaUnorm` texture, but if we try to use this in the main rendering pipeline
55+
// which renders to an `Srgb` surface, gamma mapping is applied twice. This converts back to linear to compensate.
56+
let overlay_raw = textureSample(t_overlays, s_diffuse, viewport_coordinate);
57+
let overlay = vec4<f32>(srgb_to_linear(overlay_raw.rgb), overlay_raw.a);
58+
let viewport_raw = textureSample(t_viewport, s_diffuse, viewport_coordinate);
59+
let viewport = vec4<f32>(srgb_to_linear(viewport_raw.rgb), viewport_raw.a);
5660

57-
if (ov.a < 0.001) {
58-
return blend(ui, vp);
61+
if (overlay.a < 0.001) {
62+
return blend(ui, viewport);
5963
}
6064

61-
let comp = blend(ov, vp);
62-
return blend(ui, comp);
65+
let composite = blend(overlay, viewport);
66+
return blend(ui, composite);
67+
}
68+
69+
fn srgb_to_linear(srgb: vec3<f32>) -> vec3<f32> {
70+
return select(
71+
pow((srgb + 0.055) / 1.055, vec3<f32>(2.4)),
72+
srgb / 12.92,
73+
srgb <= vec3<f32>(0.04045)
74+
);
6375
}
6476

6577
fn blend(fg: vec4<f32>, bg: vec4<f32>) -> vec4<f32> {

0 commit comments

Comments
 (0)