Skip to content

Commit bc22cd3

Browse files
committed
Improve blending and anti-aliasing in video frame shader
1 parent b583b33 commit bc22cd3

File tree

1 file changed

+21
-21
lines changed

1 file changed

+21
-21
lines changed

crates/rendering/src/shaders/composite-video-frame.wgsl

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,9 @@ fn fs_main(@builtin(position) frag_coord: vec4<f32>) -> @location(0) vec4<f32> {
148148
return mix(shadow_color, base_color, base_color.a);
149149
}
150150

151-
var accum = base_color;
152-
var weight_sum = 1.0;
151+
let base_weight = max(base_color.a, 0.001);
152+
var accum = base_color * base_weight;
153+
var weight_sum = base_weight;
153154

154155
if blur_mode < 1.5 {
155156
let motion_vec = uniforms.motion_blur_vector;
@@ -174,8 +175,11 @@ fn fs_main(@builtin(position) frag_coord: vec4<f32>) -> @location(0) vec4<f32> {
174175
var sample_color = sample_texture(sample_uv, crop_bounds_uv);
175176
sample_color = apply_rounded_corners(sample_color, sample_uv);
176177
let weight = 1.0 - t * 0.8;
177-
accum += sample_color * weight;
178-
weight_sum += weight;
178+
let sample_weight = weight * sample_color.a;
179+
if sample_weight > 1e-6 {
180+
accum += sample_color * sample_weight;
181+
weight_sum += sample_weight;
182+
}
179183
}
180184
}
181185
} else {
@@ -201,8 +205,11 @@ fn fs_main(@builtin(position) frag_coord: vec4<f32>) -> @location(0) vec4<f32> {
201205
var sample_color = sample_texture(sample_uv, crop_bounds_uv);
202206
sample_color = apply_rounded_corners(sample_color, sample_uv);
203207
let weight = 1.0 - t * 0.9;
204-
accum += sample_color * weight;
205-
weight_sum += weight;
208+
let sample_weight = weight * sample_color.a;
209+
if sample_weight > 1e-6 {
210+
accum += sample_color * sample_weight;
211+
weight_sum += sample_weight;
212+
}
206213
}
207214
}
208215
}
@@ -263,23 +270,16 @@ fn sample_texture(uv: vec2<f32>, crop_bounds_uv: vec4<f32>) -> vec4<f32> {
263270
}
264271

265272
fn apply_rounded_corners(current_color: vec4<f32>, target_uv: vec2<f32>) -> vec4<f32> {
266-
let target_coord = abs(target_uv * uniforms.target_size - uniforms.target_size / 2.0);
267-
let rounding_point = uniforms.target_size / 2.0 - uniforms.rounding_px;
268-
let target_rounding_coord = target_coord - rounding_point;
273+
// Compute the signed distance to the rounded rect in pixel space so we can
274+
// blend edges smoothly instead of hard-clipping them (which produced jaggies).
275+
let centered_uv = (target_uv - vec2<f32>(0.5)) * uniforms.target_size;
276+
let half_size = uniforms.target_size * 0.5;
277+
let distance = sdf_rounded_rect(centered_uv, half_size, uniforms.rounding_px, uniforms.rounding_type);
269278

270-
let distance_blur = 1.0;
279+
let anti_alias_width = max(fwidth(distance), 0.001);
280+
let coverage = clamp(1.0 - smoothstep(-anti_alias_width, anti_alias_width, distance), 0.0, 1.0);
271281

272-
if target_rounding_coord.x >= 0.0 && target_rounding_coord.y >= 0.0 {
273-
let local_coord = max(target_rounding_coord, vec2<f32>(0.0));
274-
let corner_norm = rounded_corner_norm(local_coord, uniforms.rounding_type);
275-
let distance = corner_norm - uniforms.rounding_px;
276-
277-
if distance >= -distance_blur / 2.0 {
278-
return vec4<f32>(0.0);
279-
}
280-
}
281-
282-
return current_color;
282+
return vec4(current_color.rgb, current_color.a * coverage);
283283
}
284284

285285
fn rand(co: vec2<f32>) -> f32 {

0 commit comments

Comments
 (0)