diff --git a/wgpu/src/quad/gradient.rs b/wgpu/src/quad/gradient.rs index 3c5fc33f..351e941d 100644 --- a/wgpu/src/quad/gradient.rs +++ b/wgpu/src/quad/gradient.rs @@ -97,6 +97,8 @@ impl Pipeline { "../shader/quad/gradient.wgsl" ), "\n", + include_str!("../shader/color.wgsl"), + "\n", include_str!("../shader/color/oklab.wgsl") ) } else { @@ -109,6 +111,8 @@ impl Pipeline { "../shader/quad/gradient.wgsl" ), "\n", + include_str!("../shader/color.wgsl"), + "\n", include_str!( "../shader/color/linear_rgb.wgsl" ) diff --git a/wgpu/src/quad/solid.rs b/wgpu/src/quad/solid.rs index 317a248c..fa1db172 100644 --- a/wgpu/src/quad/solid.rs +++ b/wgpu/src/quad/solid.rs @@ -74,6 +74,8 @@ impl Pipeline { label: Some("iced_wgpu.quad.solid.shader"), source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed( concat!( + include_str!("../shader/color.wgsl"), + "\n", include_str!("../shader/quad.wgsl"), "\n", include_str!("../shader/vertex.wgsl"), diff --git a/wgpu/src/shader/color.wgsl b/wgpu/src/shader/color.wgsl new file mode 100644 index 00000000..a8066368 --- /dev/null +++ b/wgpu/src/shader/color.wgsl @@ -0,0 +1,14 @@ +fn premultiply(color: vec4) -> vec4 { + return vec4(color.xyz * color.a, color.a); +} + +fn unpack_color(data: vec2) -> vec4 { + return premultiply(unpack_u32(data)); +} + +fn unpack_u32(data: vec2) -> vec4 { + let rg: vec2 = unpack2x16float(data.x); + let ba: vec2 = unpack2x16float(data.y); + + return vec4(rg.y, rg.x, ba.y, ba.x); +} diff --git a/wgpu/src/shader/color/oklab.wgsl b/wgpu/src/shader/color/oklab.wgsl index 343eaa15..0dc37ba6 100644 --- a/wgpu/src/shader/color/oklab.wgsl +++ b/wgpu/src/shader/color/oklab.wgsl @@ -20,7 +20,7 @@ fn interpolate_color(from_: vec4, to_: vec4, factor: f32) -> vec4 var color = to_rgb * (mixed * mixed * mixed); // Alpha interpolation - color = to_ * factor + from_ * (1.0 - factor); + color.a = mix(from_.a, to_.a, factor); return color; } diff --git a/wgpu/src/shader/quad.wgsl b/wgpu/src/shader/quad.wgsl index ff9fdae6..b213c8cf 100644 --- a/wgpu/src/shader/quad.wgsl +++ b/wgpu/src/shader/quad.wgsl @@ -5,10 +5,6 @@ struct Globals { @group(0) @binding(0) var globals: Globals; -fn premultiply(color: vec4) -> vec4 { - return vec4(color.xyz * color.a, color.a); -} - fn distance_alg( frag_coord: vec2, position: vec2, diff --git a/wgpu/src/shader/quad/gradient.wgsl b/wgpu/src/shader/quad/gradient.wgsl index e8c54790..a1b4b107 100644 --- a/wgpu/src/shader/quad/gradient.wgsl +++ b/wgpu/src/shader/quad/gradient.wgsl @@ -196,14 +196,3 @@ fn gradient_fs_main(input: GradientVertexOutput) -> @location(0) vec4 { return mixed_color * radius_alpha; } - -fn unpack_color(data: vec2) -> vec4 { - return premultiply(unpack_u32(data)); -} - -fn unpack_u32(data: vec2) -> vec4 { - let rg: vec2 = unpack2x16float(data.x); - let ba: vec2 = unpack2x16float(data.y); - - return vec4(rg.y, rg.x, ba.y, ba.x); -} diff --git a/wgpu/src/shader/triangle/gradient.wgsl b/wgpu/src/shader/triangle/gradient.wgsl index 1a8ae3b5..31a48026 100644 --- a/wgpu/src/shader/triangle/gradient.wgsl +++ b/wgpu/src/shader/triangle/gradient.wgsl @@ -87,14 +87,14 @@ fn gradient( @fragment fn gradient_fs_main(input: GradientVertexOutput) -> @location(0) vec4 { let colors = array, 8>( - unpack_u32(input.colors_1.xy), - unpack_u32(input.colors_1.zw), - unpack_u32(input.colors_2.xy), - unpack_u32(input.colors_2.zw), - unpack_u32(input.colors_3.xy), - unpack_u32(input.colors_3.zw), - unpack_u32(input.colors_4.xy), - unpack_u32(input.colors_4.zw), + unpack_color(input.colors_1.xy), + unpack_color(input.colors_1.zw), + unpack_color(input.colors_2.xy), + unpack_color(input.colors_2.zw), + unpack_color(input.colors_3.xy), + unpack_color(input.colors_3.zw), + unpack_color(input.colors_4.xy), + unpack_color(input.colors_4.zw), ); let offsets_1: vec4 = unpack_u32(input.offsets.xy); @@ -122,13 +122,6 @@ fn gradient_fs_main(input: GradientVertexOutput) -> @location(0) vec4 { return gradient(input.raw_position, input.direction, colors, offsets, last_index); } -fn unpack_u32(color: vec2) -> vec4 { - let rg: vec2 = unpack2x16float(color.x); - let ba: vec2 = unpack2x16float(color.y); - - return vec4(rg.y, rg.x, ba.y, ba.x); -} - fn random(coords: vec2) -> f32 { return fract(sin(dot(coords, vec2(12.9898,78.233))) * 43758.5453); } diff --git a/wgpu/src/shader/triangle/solid.wgsl b/wgpu/src/shader/triangle/solid.wgsl index 9ef81982..b0d8057b 100644 --- a/wgpu/src/shader/triangle/solid.wgsl +++ b/wgpu/src/shader/triangle/solid.wgsl @@ -12,7 +12,7 @@ struct SolidVertexOutput { fn solid_vs_main(input: SolidVertexInput) -> SolidVertexOutput { var out: SolidVertexOutput; - out.color = input.color; + out.color = premultiply(input.color); out.position = globals.transform * vec4(input.position, 0.0, 1.0); return out; diff --git a/wgpu/src/triangle.rs b/wgpu/src/triangle.rs index 6d0b0322..a3f850dd 100644 --- a/wgpu/src/triangle.rs +++ b/wgpu/src/triangle.rs @@ -595,7 +595,7 @@ fn fragment_target( ) -> wgpu::ColorTargetState { wgpu::ColorTargetState { format: texture_format, - blend: Some(wgpu::BlendState::ALPHA_BLENDING), + blend: Some(wgpu::BlendState::PREMULTIPLIED_ALPHA_BLENDING), write_mask: wgpu::ColorWrites::ALL, } } @@ -754,6 +754,8 @@ mod solid { include_str!("shader/triangle.wgsl"), "\n", include_str!("shader/triangle/solid.wgsl"), + "\n", + include_str!("shader/color.wgsl"), )), ), }); @@ -913,6 +915,8 @@ mod gradient { "shader/triangle/gradient.wgsl" ), "\n", + include_str!("shader/color.wgsl"), + "\n", include_str!("shader/color/oklab.wgsl") ) } else { @@ -923,6 +927,8 @@ mod gradient { "shader/triangle/gradient.wgsl" ), "\n", + include_str!("shader/color.wgsl"), + "\n", include_str!( "shader/color/linear_rgb.wgsl" )