-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Closed
Closed
Copy link
Labels
P2Important issues not at the top of the work listImportant issues not at the top of the work liste: impellerImpeller rendering backend issues and features requestsImpeller rendering backend issues and features requestsengineflutter/engine related. See also e: labels.flutter/engine related. See also e: labels.found in release: 3.32Found to occur in 3.32Found to occur in 3.32found in release: 3.33Found to occur in 3.33Found to occur in 3.33has reproducible stepsThe issue has been confirmed reproducible and is ready to work onThe issue has been confirmed reproducible and is ready to work onr: fixedIssue is closed as already fixed in a newer versionIssue is closed as already fixed in a newer versionteam-engineOwned by Engine teamOwned by Engine teamtriaged-engineTriaged by Engine teamTriaged by Engine team
Description
Steps to reproduce
When trying to find a workaround for #170792 I stumbled on another roadblock.
In an Impeller build, do the following:
- create a
BackdropFilterLayerwith its filter set toImageFilter.combined, with inner being a blur and outer being a shader - When you change
sigmaXandsigmaY, the size of the texture that's passed to the shader seems to change, but not in a uniform way
Check the code sample for a reliable repro.
Expected results
The red circle stays in the same position with the same size the entire time.
Actual results
See video
Code sample
Code sample
// main.dart
import 'dart:ui';
import 'package:flutter/material.dart';
void main() async {
final shader = await FragmentProgram.fromAsset('shaders/circle.frag');
runApp(MainApp(shader: shader));
}
class MainApp extends StatefulWidget {
const MainApp({super.key, required this.shader});
final FragmentProgram shader;
@override
State<MainApp> createState() => _MainAppState();
}
class _MainAppState extends State<MainApp> with SingleTickerProviderStateMixin {
late final animationController = AnimationController(
vsync: this,
lowerBound: 0,
upperBound: 10,
duration: Duration(seconds: 2),
)..repeat(reverse: true);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: ListenableBuilder(
listenable: animationController,
builder: (context, child) {
return Scaffold(
body: Stack(
children: [
const Center(child: FlutterLogo(size: 100)),
Positioned.fill(
child: LayoutBuilder(
builder: (context, constraints) {
return BackdropFilter(
filter: ImageFilter.compose(
inner: ImageFilter.blur(
sigmaX: animationController.value,
sigmaY: animationController.value,
tileMode: TileMode.clamp,
),
outer: ImageFilter.shader(
widget.shader.fragmentShader()
..setFloat(2, 100) // uCirclePos.x (center)
..setFloat(3, 100) // uCirclePos.y (center)
..setFloat(4, 100.0), // uCircleRadius
),
),
child: Center(
child: Text(
animationController.value.toStringAsFixed(2),
),
),
);
},
),
),
],
),
);
},
),
);
}
}
With this fragment shader:
#version 320 es
precision mediump float;
uniform vec2 uResolution;
uniform vec2 uCirclePos;
uniform float uCircleRadius;
uniform sampler2D uTexture;
out vec4 fragColor;
#include <flutter/runtime_effect.glsl>
float sdfCircle(vec2 p, float radius) {
return length(p) - radius;
}
void main() {
vec2 fragCoord = FlutterFragCoord().xy;
vec2 screenUV = fragCoord / uResolution;
vec2 normalizedCoord = (fragCoord - uResolution * 0.5) / min(uResolution.x, uResolution.y);
vec2 normalizedCirclePos = (uCirclePos - uResolution * 0.5) / min(uResolution.x, uResolution.y);
float normalizedRadius = uCircleRadius / min(uResolution.x, uResolution.y);
float distance = sdfCircle(normalizedCoord - normalizedCirclePos, normalizedRadius);
float circleAlpha = 1.0 - smoothstep(-0.01, 0.01, distance);
vec4 backgroundColor = texture(uTexture, screenUV);
vec4 circleColor = vec4(1.0, 0.0, 0.0, circleAlpha);
fragColor = mix(backgroundColor, circleColor, circleAlpha * 0.8);
}Screenshots or Video
Screenshots / Video demonstration
CleanShot.2025-06-18.at.19.51.11.mp4
Logs
No response
Flutter Doctor output
Doctor output
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.32.4, on macOS 15.5 24F74 darwin-arm64, locale en-US)
[✓] Android toolchain - develop for Android devices (Android SDK version 35.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 16.4)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2024.2)
[✓] VS Code (version 1.101.0)
[✓] Connected device (2 available)
! Error: Browsing on the local area network for iPhone von mir. Ensure the device is
unlocked and attached with a cable or associated with the same local area network
as this Mac.
The device must be opted into Developer Mode to connect wirelessly. (code -27)
! Error: Browsing on the local area network for Tim’s iPad. Ensure the device is
unlocked and attached with a cable or associated with the same local area network
as this Mac.
The device must be opted into Developer Mode to connect wirelessly. (code -27)
[✓] Network resourcessbis04, insinfo, Murasame2333, sangddn, binemmanuel and 78 moreville-socialbinemmanuel, ville-social, Healthspan2024 and mazzonem
Metadata
Metadata
Assignees
Labels
P2Important issues not at the top of the work listImportant issues not at the top of the work liste: impellerImpeller rendering backend issues and features requestsImpeller rendering backend issues and features requestsengineflutter/engine related. See also e: labels.flutter/engine related. See also e: labels.found in release: 3.32Found to occur in 3.32Found to occur in 3.32found in release: 3.33Found to occur in 3.33Found to occur in 3.33has reproducible stepsThe issue has been confirmed reproducible and is ready to work onThe issue has been confirmed reproducible and is ready to work onr: fixedIssue is closed as already fixed in a newer versionIssue is closed as already fixed in a newer versionteam-engineOwned by Engine teamOwned by Engine teamtriaged-engineTriaged by Engine teamTriaged by Engine team