From 4a38d36cd732cf8ea3f707bd98cfde42d62c85e0 Mon Sep 17 00:00:00 2001 From: Mike Welsh Date: Tue, 12 Apr 2022 22:28:02 -0700 Subject: [PATCH] wgpu: Output premultiplied alpha --- render/wgpu/shaders/color.wgsl | 3 ++- render/wgpu/shaders/common.wgsl | 24 ++++++++++++++++-------- render/wgpu/shaders/gradient.wgsl | 3 ++- render/wgpu/src/pipelines.rs | 16 ++++++++-------- 4 files changed, 28 insertions(+), 18 deletions(-) diff --git a/render/wgpu/shaders/color.wgsl b/render/wgpu/shaders/color.wgsl index c97687b60..b42c80d0b 100644 --- a/render/wgpu/shaders/color.wgsl +++ b/render/wgpu/shaders/color.wgsl @@ -13,5 +13,6 @@ fn main_vertex(in: VertexInput) -> VertexOutput { [[stage(fragment)]] fn main_fragment(in: VertexOutput) -> [[location(0)]] vec4 { - return in.color * transforms.mult_color + transforms.add_color; + let out = in.color * transforms.mult_color + transforms.add_color; + return vec4(out.rgb * out.a, out.a); } diff --git a/render/wgpu/shaders/common.wgsl b/render/wgpu/shaders/common.wgsl index 0cb318a1f..763d0dedb 100644 --- a/render/wgpu/shaders/common.wgsl +++ b/render/wgpu/shaders/common.wgsl @@ -43,16 +43,24 @@ var transforms: Transforms; /// Converts a color from linear to sRGB color space. fn linear_to_srgb(linear: vec4) -> vec4 { - let a = 12.92 * linear.rgb; - let b = 1.055 * pow(linear.rgb, vec3(1.0 / 2.4)) - 0.055; - let c = step(vec3(0.0031308), linear.rgb); - return vec4(mix(a, b, c), linear.a); + var rgb: vec3 = linear.rgb; + if( linear.a > 0.0 ) { + rgb = rgb / linear.a; + } + let a = 12.92 * rgb; + let b = 1.055 * pow(rgb, vec3(1.0 / 2.4)) - 0.055; + let c = step(vec3(0.0031308), rgb); + return vec4(mix(a, b, c) * linear.a, linear.a); } /// Converts a color from sRGB to linear color space. fn srgb_to_linear(srgb: vec4) -> vec4 { - let a = srgb.rgb / 12.92; - let b = pow((srgb.rgb + vec3(0.055)) / 1.055, vec3(2.4)); - let c = step(vec3(0.04045), srgb.rgb); - return vec4(mix(a, b, c), srgb.a); + var rgb: vec3 = srgb.rgb; + if( srgb.a > 0.0 ) { + rgb = rgb / srgb.a; + } + let a = rgb / 12.92; + let b = pow((rgb + vec3(0.055)) / 1.055, vec3(2.4)); + let c = step(vec3(0.04045), rgb); + return vec4(mix(a, b, c) * srgb.a, srgb.a); } diff --git a/render/wgpu/shaders/gradient.wgsl b/render/wgpu/shaders/gradient.wgsl index d0661056a..f037ca28c 100644 --- a/render/wgpu/shaders/gradient.wgsl +++ b/render/wgpu/shaders/gradient.wgsl @@ -101,5 +101,6 @@ fn main_fragment(in: VertexOutput) -> [[location(0)]] vec4 { if( gradient.interpolation != 0 ) { color = linear_to_srgb(color); } - return color * transforms.mult_color + transforms.add_color; + let out = color * transforms.mult_color + transforms.add_color; + return vec4(out.rgb * out.a, out.a); } diff --git a/render/wgpu/src/pipelines.rs b/render/wgpu/src/pipelines.rs index 7b9038d69..d273392d1 100644 --- a/render/wgpu/src/pipelines.rs +++ b/render/wgpu/src/pipelines.rs @@ -306,7 +306,7 @@ fn create_color_pipelines( }), &[wgpu::ColorTargetState { format, - blend: Some(wgpu::BlendState::ALPHA_BLENDING), + blend: Some(wgpu::BlendState::PREMULTIPLIED_ALPHA_BLENDING), write_mask, }], vertex_buffers_description, @@ -330,7 +330,7 @@ fn create_color_pipelines( }), &[wgpu::ColorTargetState { format, - blend: Some(wgpu::BlendState::ALPHA_BLENDING), + blend: Some(wgpu::BlendState::PREMULTIPLIED_ALPHA_BLENDING), write_mask, }], vertex_buffers_description, @@ -354,7 +354,7 @@ fn create_color_pipelines( }), &[wgpu::ColorTargetState { format, - blend: Some(wgpu::BlendState::ALPHA_BLENDING), + blend: Some(wgpu::BlendState::PREMULTIPLIED_ALPHA_BLENDING), write_mask, }], vertex_buffers_description, @@ -378,7 +378,7 @@ fn create_color_pipelines( }), &[wgpu::ColorTargetState { format, - blend: Some(wgpu::BlendState::ALPHA_BLENDING), + blend: Some(wgpu::BlendState::PREMULTIPLIED_ALPHA_BLENDING), write_mask, }], vertex_buffers_description, @@ -554,7 +554,7 @@ fn create_gradient_pipeline( }), &[wgpu::ColorTargetState { format, - blend: Some(wgpu::BlendState::ALPHA_BLENDING), + blend: Some(wgpu::BlendState::PREMULTIPLIED_ALPHA_BLENDING), write_mask, }], vertex_buffers_layout, @@ -578,7 +578,7 @@ fn create_gradient_pipeline( }), &[wgpu::ColorTargetState { format, - blend: Some(wgpu::BlendState::ALPHA_BLENDING), + blend: Some(wgpu::BlendState::PREMULTIPLIED_ALPHA_BLENDING), write_mask, }], vertex_buffers_layout, @@ -603,7 +603,7 @@ fn create_gradient_pipeline( }), &[wgpu::ColorTargetState { format, - blend: Some(wgpu::BlendState::ALPHA_BLENDING), + blend: Some(wgpu::BlendState::PREMULTIPLIED_ALPHA_BLENDING), write_mask, }], vertex_buffers_layout, @@ -627,7 +627,7 @@ fn create_gradient_pipeline( }), &[wgpu::ColorTargetState { format, - blend: Some(wgpu::BlendState::ALPHA_BLENDING), + blend: Some(wgpu::BlendState::PREMULTIPLIED_ALPHA_BLENDING), write_mask, }], vertex_buffers_layout,