diff --git a/lib/web_ui/lib/src/engine/layers.dart b/lib/web_ui/lib/src/engine/layers.dart
index 6f7a67450f1f2..f3658ddee3c4c 100644
--- a/lib/web_ui/lib/src/engine/layers.dart
+++ b/lib/web_ui/lib/src/engine/layers.dart
@@ -35,6 +35,11 @@ class BackdropFilterOperation implements LayerOperation {
 
   @override
   PlatformViewStyling createPlatformViewStyling() => const PlatformViewStyling();
+
+  // The backdrop filter actually has an effect on the scene even if it contains
+  // no pictures, so we return true here.
+  @override
+  bool get shouldDrawIfEmpty => true;
 }
 
 class ClipPathLayer
@@ -70,6 +75,9 @@ class ClipPathOperation implements LayerOperation {
   PlatformViewStyling createPlatformViewStyling() {
     return PlatformViewStyling(clip: PlatformViewPathClip(path));
   }
+
+  @override
+  bool get shouldDrawIfEmpty => false;
 }
 
 class ClipRectLayer
@@ -105,6 +113,9 @@ class ClipRectOperation implements LayerOperation {
   PlatformViewStyling createPlatformViewStyling() {
     return PlatformViewStyling(clip: PlatformViewRectClip(rect));
   }
+
+  @override
+  bool get shouldDrawIfEmpty => false;
 }
 
 class ClipRRectLayer
@@ -140,6 +151,9 @@ class ClipRRectOperation implements LayerOperation {
   PlatformViewStyling createPlatformViewStyling() {
     return PlatformViewStyling(clip: PlatformViewRRectClip(rrect));
   }
+
+  @override
+  bool get shouldDrawIfEmpty => false;
 }
 
 class ColorFilterLayer
@@ -165,6 +179,9 @@ class ColorFilterOperation implements LayerOperation {
 
   @override
   PlatformViewStyling createPlatformViewStyling() => const PlatformViewStyling();
+
+  @override
+  bool get shouldDrawIfEmpty => false;
 }
 
 class ImageFilterLayer
@@ -207,6 +224,9 @@ class ImageFilterOperation implements LayerOperation {
       return const PlatformViewStyling();
     }
   }
+
+  @override
+  bool get shouldDrawIfEmpty => false;
 }
 
 class OffsetLayer
@@ -236,6 +256,9 @@ class OffsetOperation implements LayerOperation {
   PlatformViewStyling createPlatformViewStyling() => PlatformViewStyling(
     position: PlatformViewPosition.offset(ui.Offset(dx, dy))
   );
+
+  @override
+  bool get shouldDrawIfEmpty => false;
 }
 
 class OpacityLayer
@@ -276,6 +299,9 @@ class OpacityOperation implements LayerOperation {
     position: offset != ui.Offset.zero ? PlatformViewPosition.offset(offset) : const PlatformViewPosition.zero(),
     opacity: alpha.toDouble() / 255.0,
   );
+
+  @override
+  bool get shouldDrawIfEmpty => false;
 }
 
 class TransformLayer
@@ -307,6 +333,9 @@ class TransformOperation implements LayerOperation {
   PlatformViewStyling createPlatformViewStyling() => PlatformViewStyling(
     position: PlatformViewPosition.transform(matrix),
   );
+
+  @override
+  bool get shouldDrawIfEmpty => false;
 }
 
 class ShaderMaskLayer
@@ -346,6 +375,9 @@ class ShaderMaskOperation implements LayerOperation {
 
   @override
   PlatformViewStyling createPlatformViewStyling() => const PlatformViewStyling();
+
+  @override
+  bool get shouldDrawIfEmpty => false;
 }
 
 class PlatformView {
@@ -414,6 +446,11 @@ abstract class LayerOperation {
   void post(SceneCanvas canvas, ui.Rect contentRect);
 
   PlatformViewStyling createPlatformViewStyling();
+
+  /// Indicates whether this operation's `pre` and `post` methods should be
+  /// invoked even if it contains no pictures. (Most operations don't need to
+  /// actually be performed at all if they don't contain any pictures.)
+  bool get shouldDrawIfEmpty;
 }
 
 class PictureDrawCommand {
@@ -771,7 +808,7 @@ class LayerBuilder {
   }
 
   void flushSlices() {
-    if (pendingPictures.isNotEmpty) {
+    if (pendingPictures.isNotEmpty || (operation?.shouldDrawIfEmpty ?? false)) {
       // Merge the existing draw commands into a single picture and add a slice
       // with that picture to the slice list.
       final ui.Rect drawnRect = picturesRect ?? ui.Rect.zero;
diff --git a/lib/web_ui/test/ui/scene_builder_test.dart b/lib/web_ui/test/ui/scene_builder_test.dart
index fee4e87e6b74a..fc77fd98c2d39 100644
--- a/lib/web_ui/test/ui/scene_builder_test.dart
+++ b/lib/web_ui/test/ui/scene_builder_test.dart
@@ -215,6 +215,34 @@ Future<void> testMain() async {
       await matchGoldenFile('scene_builder_backdrop_filter.png', region: region);
     });
 
+    test('empty backdrop filter layer with clip', () async {
+      // Note that this test does not actually render properly in skwasm due to
+      // a Skia bug. See https://g-issues.skia.org/issues/362552959 and
+      // https://github.com/flutter/flutter/issues/152026
+      final ui.SceneBuilder sceneBuilder = ui.SceneBuilder();
+
+      sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) {
+        // Create a red and blue checkerboard pattern
+        final ui.Paint redPaint = ui.Paint()..color = const ui.Color(0xFFFF0000);
+        final ui.Paint bluePaint = ui.Paint()..color = const ui.Color(0xFF0000FF);
+        for (double y = 0; y < 300; y += 10) {
+          for (double x = 0; x < 300; x += 10) {
+            final ui.Paint paint = ((x + y) % 20 == 0) ? redPaint : bluePaint;
+            canvas.drawRect(ui.Rect.fromLTWH(x, y, 10, 10), paint);
+          }
+        }
+      }));
+
+      sceneBuilder.pushClipRect(const ui.Rect.fromLTRB(100, 100, 200, 200));
+
+      sceneBuilder.pushBackdropFilter(ui.ImageFilter.blur(
+        sigmaX: 3.0,
+        sigmaY: 3.0,
+      ));
+      await renderScene(sceneBuilder.build());
+      await matchGoldenFile('scene_builder_empty_backdrop_filter_with_clip.png', region: region);
+    });
+
     test('image filter layer', () async {
       final ui.SceneBuilder sceneBuilder = ui.SceneBuilder();
       sceneBuilder.pushImageFilter(ui.ImageFilter.blur(