From daa5130dd61ac6a2ce18922962b61e659b2fd452 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Sun, 8 Dec 2024 13:06:27 -0800 Subject: [PATCH] egui: switch to gamma space blending, fix blend mode --- blade-egui/shader.wgsl | 17 ++++++++++------- blade-egui/src/lib.rs | 15 +++++++++++++-- docs/CHANGELOG.md | 2 ++ 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/blade-egui/shader.wgsl b/blade-egui/shader.wgsl index ceff1c65..b204af02 100644 --- a/blade-egui/shader.wgsl +++ b/blade-egui/shader.wgsl @@ -21,10 +21,10 @@ struct Vertex { } var r_vertex_data: array; -fn linear_from_srgb(srgb: vec3) -> vec3 { - let cutoff = srgb < vec3(10.31475); - let lower = srgb / vec3(3294.6); - let higher = pow((srgb + vec3(14.025)) / vec3(269.025), vec3(2.4)); +fn linear_from_gamma(srgb: vec3) -> vec3 { + let cutoff = srgb < vec3(0.04045); + let lower = srgb / vec3(12.92); + let higher = pow((srgb + vec3(0.055)) / vec3(1.055), vec3(2.4)); return select(higher, lower, cutoff); } @@ -35,8 +35,7 @@ fn vs_main( let input = r_vertex_data[v_index]; var out: VertexOutput; out.tex_coord = vec2(input.tex_coord_x, input.tex_coord_y); - let color = unpack4x8unorm(input.color); - out.color = vec4(pow(color.xyz, vec3(2.2)), color.a); + out.color = unpack4x8unorm(input.color); out.position = vec4( 2.0 * input.pos_x / r_uniforms.screen_size.x - 1.0, 1.0 - 2.0 * input.pos_y / r_uniforms.screen_size.y, @@ -51,5 +50,9 @@ var r_sampler: sampler; @fragment fn fs_main(in: VertexOutput) -> @location(0) vec4 { - return in.color * textureSample(r_texture, r_sampler, in.tex_coord); + //Note: we always assume rendering to linear color space, + // but Egui wants to blend in gamma space, see + // https://github.com/emilk/egui/pull/2071 + let blended = in.color * textureSample(r_texture, r_sampler, in.tex_coord); + return vec4f(linear_from_gamma(blended.xyz), blended.a); } diff --git a/blade-egui/src/lib.rs b/blade-egui/src/lib.rs index 533a269b..7af3d5ba 100644 --- a/blade-egui/src/lib.rs +++ b/blade-egui/src/lib.rs @@ -62,7 +62,7 @@ struct GuiTexture { impl GuiTexture { fn create(context: &blade_graphics::Context, name: &str, size: blade_graphics::Extent) -> Self { - let format = blade_graphics::TextureFormat::Rgba8UnormSrgb; + let format = blade_graphics::TextureFormat::Rgba8Unorm; let allocation = context.create_texture(blade_graphics::TextureDesc { name, format, @@ -147,7 +147,18 @@ impl GuiPainter { fragment: shader.at("fs_main"), color_targets: &[blade_graphics::ColorTargetState { format: info.format, - blend: Some(blade_graphics::BlendState::ALPHA_BLENDING), + blend: Some(blade_graphics::BlendState { + color: blade_graphics::BlendComponent { + src_factor: blade_graphics::BlendFactor::One, + dst_factor: blade_graphics::BlendFactor::OneMinusSrcAlpha, + operation: blade_graphics::BlendOperation::Add, + }, + alpha: blade_graphics::BlendComponent { + src_factor: blade_graphics::BlendFactor::OneMinusDstAlpha, + dst_factor: blade_graphics::BlendFactor::One, + operation: blade_graphics::BlendOperation::Add, + }, + }), write_mask: blade_graphics::ColorWrites::all(), }], }); diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 88c0636b..82044156 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -18,6 +18,8 @@ Changelog for Blade - destroy old surface on resize - Vulkan: - support unused bind groups +- egui: + - fix blending color space ## blade-egui-0.5 (09 Nov 2024)