From 1354425066b7bda976bb56fb4257483ee32a5b8a Mon Sep 17 00:00:00 2001 From: Adam Burns Date: Wed, 25 Feb 2026 08:04:46 +1000 Subject: [PATCH 1/2] Fix for #1619 --- crates/rendering/src/mask.rs | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/crates/rendering/src/mask.rs b/crates/rendering/src/mask.rs index 7b6b9a693b..86fb36fa2d 100644 --- a/crates/rendering/src/mask.rs +++ b/crates/rendering/src/mask.rs @@ -70,7 +70,9 @@ pub fn interpolate_masks( ) -> Vec { let mut prepared = Vec::new(); - for segment in segments.iter().filter(|s| s.enabled) { + let enabled: Vec<&MaskSegment> = segments.iter().filter(|s| s.enabled).collect(); + + for (i, segment) in enabled.iter().enumerate() { if frame_time < segment.start || frame_time > segment.end { continue; } @@ -85,11 +87,30 @@ pub fn interpolate_masks( let fade_duration = segment.fade_duration.max(0.0); if fade_duration > 0.0 { + let adjacent_before = enabled + .iter() + .enumerate() + .any(|(j, other)| i != j && (segment.start - other.end).abs() < fade_duration); + + let adjacent_after = enabled + .iter() + .enumerate() + .any(|(j, other)| i != j && (other.start - segment.end).abs() < fade_duration); + let time_since_start = (frame_time - segment.start).max(0.0); let time_until_end = (segment.end - frame_time).max(0.0); - let fade_in = (time_since_start / fade_duration).min(1.0); - let fade_out = (time_until_end / fade_duration).min(1.0); + let fade_in = if adjacent_before { + 1.0 + } else { + (time_since_start / fade_duration).min(1.0) + }; + + let fade_out = if adjacent_after { + 1.0 + } else { + (time_until_end / fade_duration).min(1.0) + }; intensity *= fade_in * fade_out; } From 7c69bfde592cd1d4026d7affe47ffc86caf46959 Mon Sep 17 00:00:00 2001 From: Adam Burns Date: Wed, 25 Feb 2026 08:11:44 +1000 Subject: [PATCH 2/2] fix: use small epsilon for adjacency detection instead of fade_duration Prevents suppressing fades on segments that have an intentional gap. Co-authored-by: Cursor --- crates/rendering/src/mask.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/rendering/src/mask.rs b/crates/rendering/src/mask.rs index 86fb36fa2d..a6882ff6e2 100644 --- a/crates/rendering/src/mask.rs +++ b/crates/rendering/src/mask.rs @@ -87,15 +87,17 @@ pub fn interpolate_masks( let fade_duration = segment.fade_duration.max(0.0); if fade_duration > 0.0 { + let adjacency_epsilon = 1e-3; + let adjacent_before = enabled .iter() .enumerate() - .any(|(j, other)| i != j && (segment.start - other.end).abs() < fade_duration); + .any(|(j, other)| i != j && (segment.start - other.end).abs() < adjacency_epsilon); let adjacent_after = enabled .iter() .enumerate() - .any(|(j, other)| i != j && (other.start - segment.end).abs() < fade_duration); + .any(|(j, other)| i != j && (other.start - segment.end).abs() < adjacency_epsilon); let time_since_start = (frame_time - segment.start).max(0.0); let time_until_end = (segment.end - frame_time).max(0.0);