Merge pull request #2925 from iced-rs/fix/quad-shader-blending
Fix `quad` shader blending
This commit is contained in:
commit
3a3a02beef
9 changed files with 57 additions and 62 deletions
|
|
@ -317,18 +317,7 @@ fn color_target_state(
|
|||
) -> [Option<wgpu::ColorTargetState>; 1] {
|
||||
[Some(wgpu::ColorTargetState {
|
||||
format,
|
||||
blend: Some(wgpu::BlendState {
|
||||
color: wgpu::BlendComponent {
|
||||
src_factor: wgpu::BlendFactor::SrcAlpha,
|
||||
dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
|
||||
operation: wgpu::BlendOperation::Add,
|
||||
},
|
||||
alpha: wgpu::BlendComponent {
|
||||
src_factor: wgpu::BlendFactor::One,
|
||||
dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
|
||||
operation: wgpu::BlendOperation::Add,
|
||||
},
|
||||
}),
|
||||
blend: Some(wgpu::BlendState::PREMULTIPLIED_ALPHA_BLENDING),
|
||||
write_mask: wgpu::ColorWrites::ALL,
|
||||
})]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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"),
|
||||
|
|
|
|||
14
wgpu/src/shader/color.wgsl
Normal file
14
wgpu/src/shader/color.wgsl
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
fn premultiply(color: vec4<f32>) -> vec4<f32> {
|
||||
return vec4(color.xyz * color.a, color.a);
|
||||
}
|
||||
|
||||
fn unpack_color(data: vec2<u32>) -> vec4<f32> {
|
||||
return premultiply(unpack_u32(data));
|
||||
}
|
||||
|
||||
fn unpack_u32(data: vec2<u32>) -> vec4<f32> {
|
||||
let rg: vec2<f32> = unpack2x16float(data.x);
|
||||
let ba: vec2<f32> = unpack2x16float(data.y);
|
||||
|
||||
return vec4<f32>(rg.y, rg.x, ba.y, ba.x);
|
||||
}
|
||||
|
|
@ -56,7 +56,7 @@ fn gradient_vs_main(input: GradientVertexInput) -> GradientVertexOutput {
|
|||
out.offsets = input.offsets;
|
||||
out.direction = input.direction * globals.scale;
|
||||
out.position_and_scale = vec4<f32>(pos, scale);
|
||||
out.border_color = input.border_color;
|
||||
out.border_color = premultiply(input.border_color);
|
||||
out.border_radius = border_radius * globals.scale;
|
||||
out.border_width = input.border_width * globals.scale;
|
||||
|
||||
|
|
@ -119,14 +119,14 @@ fn gradient(
|
|||
@fragment
|
||||
fn gradient_fs_main(input: GradientVertexOutput) -> @location(0) vec4<f32> {
|
||||
let colors = array<vec4<f32>, 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<f32> = unpack_u32(input.offsets.xy);
|
||||
|
|
@ -179,7 +179,7 @@ fn gradient_fs_main(input: GradientVertexOutput) -> @location(0) vec4<f32> {
|
|||
internal_distance
|
||||
);
|
||||
|
||||
mixed_color = mix(mixed_color, input.border_color, vec4<f32>(border_mix, border_mix, border_mix, border_mix));
|
||||
mixed_color = mix(mixed_color, input.border_color, border_mix);
|
||||
}
|
||||
|
||||
var dist: f32 = distance_alg(
|
||||
|
|
@ -194,12 +194,5 @@ fn gradient_fs_main(input: GradientVertexOutput) -> @location(0) vec4<f32> {
|
|||
border_radius + 0.5,
|
||||
dist);
|
||||
|
||||
return vec4<f32>(mixed_color.x, mixed_color.y, mixed_color.z, mixed_color.w * radius_alpha);
|
||||
}
|
||||
|
||||
fn unpack_u32(color: vec2<u32>) -> vec4<f32> {
|
||||
let rg: vec2<f32> = unpack2x16float(color.x);
|
||||
let ba: vec2<f32> = unpack2x16float(color.y);
|
||||
|
||||
return vec4<f32>(rg.y, rg.x, ba.y, ba.x);
|
||||
return mixed_color * radius_alpha;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,13 +56,13 @@ fn solid_vs_main(input: SolidVertexInput) -> SolidVertexOutput {
|
|||
);
|
||||
|
||||
out.position = globals.transform * transform * vec4<f32>(vertex_position(input.vertex_index), 0.0, 1.0);
|
||||
out.color = input.color;
|
||||
out.border_color = input.border_color;
|
||||
out.color = premultiply(input.color);
|
||||
out.border_color = premultiply(input.border_color);
|
||||
out.pos = input.pos * globals.scale + snap;
|
||||
out.scale = input.scale * globals.scale;
|
||||
out.border_radius = border_radius * globals.scale;
|
||||
out.border_width = input.border_width * globals.scale;
|
||||
out.shadow_color = input.shadow_color;
|
||||
out.shadow_color = premultiply(input.shadow_color);
|
||||
out.shadow_offset = input.shadow_offset * globals.scale;
|
||||
out.shadow_blur_radius = input.shadow_blur_radius * globals.scale;
|
||||
|
||||
|
|
@ -97,7 +97,7 @@ fn solid_fs_main(
|
|||
internal_distance
|
||||
);
|
||||
|
||||
mixed_color = mix(input.color, input.border_color, vec4<f32>(border_mix, border_mix, border_mix, border_mix));
|
||||
mixed_color = mix(input.color, input.border_color, border_mix);
|
||||
}
|
||||
|
||||
var dist: f32 = distance_alg(
|
||||
|
|
@ -113,7 +113,7 @@ fn solid_fs_main(
|
|||
dist
|
||||
);
|
||||
|
||||
let quad_color = vec4<f32>(mixed_color.x, mixed_color.y, mixed_color.z, mixed_color.w * radius_alpha);
|
||||
let quad_color = mixed_color * radius_alpha;
|
||||
|
||||
if input.shadow_color.a > 0.0 {
|
||||
let shadow_radius = select_border_radius(
|
||||
|
|
@ -121,17 +121,11 @@ fn solid_fs_main(
|
|||
input.position.xy - input.shadow_offset,
|
||||
(input.pos + input.scale * 0.5).xy
|
||||
);
|
||||
let shadow_distance = max(rounded_box_sdf(input.position.xy - input.pos - input.shadow_offset - (input.scale / 2.0), input.scale / 2.0, shadow_radius), 0.);
|
||||
|
||||
let shadow_alpha = 1.0 - smoothstep(-input.shadow_blur_radius, input.shadow_blur_radius, shadow_distance);
|
||||
let shadow_color = input.shadow_color;
|
||||
let base_color = mix(
|
||||
vec4<f32>(shadow_color.x, shadow_color.y, shadow_color.z, 0.0),
|
||||
quad_color,
|
||||
quad_color.a
|
||||
);
|
||||
|
||||
return mix(base_color, shadow_color, (1.0 - radius_alpha) * shadow_alpha);
|
||||
let shadow_distance = max(rounded_box_sdf(input.position.xy - input.pos - input.shadow_offset - (input.scale / 2.0), input.scale / 2.0, shadow_radius), 0.);
|
||||
let shadow_alpha = 1.0 - smoothstep(-input.shadow_blur_radius, input.shadow_blur_radius, shadow_distance);
|
||||
|
||||
return mix(quad_color, input.shadow_color, (1.0 - radius_alpha) * shadow_alpha);
|
||||
} else {
|
||||
return quad_color;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,14 +87,14 @@ fn gradient(
|
|||
@fragment
|
||||
fn gradient_fs_main(input: GradientVertexOutput) -> @location(0) vec4<f32> {
|
||||
let colors = array<vec4<f32>, 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<f32> = unpack_u32(input.offsets.xy);
|
||||
|
|
@ -122,13 +122,6 @@ fn gradient_fs_main(input: GradientVertexOutput) -> @location(0) vec4<f32> {
|
|||
return gradient(input.raw_position, input.direction, colors, offsets, last_index);
|
||||
}
|
||||
|
||||
fn unpack_u32(color: vec2<u32>) -> vec4<f32> {
|
||||
let rg: vec2<f32> = unpack2x16float(color.x);
|
||||
let ba: vec2<f32> = unpack2x16float(color.y);
|
||||
|
||||
return vec4<f32>(rg.y, rg.x, ba.y, ba.x);
|
||||
}
|
||||
|
||||
fn random(coords: vec2<f32>) -> f32 {
|
||||
return fract(sin(dot(coords, vec2(12.9898,78.233))) * 43758.5453);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<f32>(input.position, 0.0, 1.0);
|
||||
|
||||
return out;
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue