Repository navigation
Closed
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 requestsf: scrollingViewports, list views, slivers, etc.Viewports, list views, slivers, etc.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.33frameworkflutter/packages/flutter repository. See also f: labels.flutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onThe issue has been confirmed reproducible and is ready to work onp: material_uimaterial_ui package in flutter/packagesmaterial_ui package in flutter/packagesr: fixedIssue is closed as already fixed in a newer versionIssue is closed as already fixed in a newer versionteam-frameworkOwned by Framework teamOwned by Framework teamtriaged-frameworkTriaged by Framework teamTriaged by Framework team
Description
Hi, I'm experiencing render issues when playing around with perspective in Flutter.
I have a "Road" like widget that is basically a ListView under perspective, but for certain matrix values it breaks.
I've raised similar issues in the past:
#155450
#154104
And got some help from @jason-simmons, so 🤞 its resolvable this time around as well.
I've provided minimal repro and a video, where it's visible for which values the ListView starts breaking (-0.003 on the device I was testing) (iPhone 16 Pro Simulator).
- Using y scale makes the situation worse.
- Changing the height of the Container does not seem to matter.
- I am confident this is not device, platform or debug mode specific, as our actual app experiences this for both ios and android + release and debug.
Steps to reproduce
Create a ListView, wrap it in a Transform and setEntry(3,1, highEnoughValueLike0point005), see it disappear.
Code sample
Code sample
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Perspective Issues',
theme: ThemeData(primarySwatch: Colors.blue),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
double _yScale = 1.0;
double _perspective = 0.000;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Perspective Issues')),
body: Stack(
alignment: Alignment.bottomCenter,
children: [
Transform(
transform: Matrix4.identity()
..setEntry(3, 1, _perspective)
..scale(1.0, _yScale, 1.0),
alignment: Alignment.center,
child: ListView.builder(
reverse: true,
itemBuilder: (context, index) {
final hue = (index * 137.5) % 360;
final color = HSLColor.fromAHSL(1.0, hue, 0.6, 0.5).toColor();
return Container(
height: 100.0,
color: color,
child: Center(
child: Text(
'Index: $index',
style: const TextStyle(color: Colors.white, fontSize: 20, fontWeight: FontWeight.bold),
),
),
);
},
),
),
_buildDebugControls(),
],
),
);
}
Widget _buildDebugControls() {
return Card(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 12.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
_buildSlider(
label: 'Perspective',
value: _perspective,
max: 0,
min: -0.005,
defaultValue: 0.000,
onChanged: (value) => setState(() => _perspective = value),
),
_buildSlider(
label: 'Y Scale',
value: _yScale,
min: 1.0,
max: 5.0,
defaultValue: 1.0,
onChanged: (value) => setState(() => _yScale = value),
),
],
),
),
);
}
Widget _buildSlider({
required String label,
required double value,
required double min,
required double max,
required double defaultValue,
required ValueChanged<double> onChanged,
}) {
return Column(
children: [
Text('$label: ${value.toStringAsFixed(4)}'),
Row(
children: [
Expanded(
child: Slider(
value: value,
min: min,
max: max,
label: value.toStringAsFixed(4),
onChanged: onChanged,
),
),
const SizedBox(width: 8.0),
IconButton(icon: const Icon(Icons.refresh, size: 20), onPressed: () => onChanged(defaultValue)),
],
),
],
);
}
}
Screenshots or Video
Details
Simulator.Screen.Recording.-.iPhone.16.Pro.-.2025-08-01.at.14.32.53.mp4
Logs
Logs
Nothing in the logs
Flutter Doctor output
Doctor output
[✓] Flutter (Channel stable, 3.32.6, on macOS 14.5 23F79 darwin-arm64, locale en-PL)
[!] Android toolchain - develop for Android devices (Android SDK version 35.0.0)
! Some Android licenses not accepted. To resolve this, run: flutter doctor --android-licenses
[✓] Xcode - develop for iOS and macOS (Xcode 16.2)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2024.3)
[✓] VS Code (version 1.102.3)
[✓] Connected device (3 available)
...
[✓] Network resources
Reacted by BoyanCreo, Michael Stachowicz, OliverNarramore, evgeniy-yanev and Jumes
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 requestsf: scrollingViewports, list views, slivers, etc.Viewports, list views, slivers, etc.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.33frameworkflutter/packages/flutter repository. See also f: labels.flutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onThe issue has been confirmed reproducible and is ready to work onp: material_uimaterial_ui package in flutter/packagesmaterial_ui package in flutter/packagesr: fixedIssue is closed as already fixed in a newer versionIssue is closed as already fixed in a newer versionteam-frameworkOwned by Framework teamOwned by Framework teamtriaged-frameworkTriaged by Framework teamTriaged by Framework team
Activity
tirth-patel-nc commentedon Aug 1, 2025
Thanks for the report. Seeing the same behaviour with latest SDK versions. Reproducible on Android, iOS & macOS. Can't reproduce on Web (Chrome).
Android, iOS, macOS
Screen.Recording.2025-08-01.at.6.56.02.PM.mov
also noticed a rendering glitch (white)
Chrome
Screen.Recording.2025-08-01.at.6.57.34.PM.mov
FufferKS commentedon Aug 1, 2025
Thanks for the quick triage 🙌
jason-simmons commentedon Aug 7, 2025
This is related to Impeller's handling of perspective and clipping. It renders as expected with Skia.
@bdero
FufferKS commentedon Oct 16, 2025
Any news on this being worked on perhaps 🙏 ?
Quite crucial to the UI of our app.
FufferKS commentedon Oct 16, 2025
one new finding:
alignment: Alignment.center,setting this tobottomCenterseems to make it much more stableflar commentedon Jan 16, 2026
Simplifying the child of the transform to just a container shows no anomalies, i.e.:
But adding a ClipRect summons the bug:
flar commentedon Jan 16, 2026
This playground test (added to any of the impeller
aiks_dl_..._unittests.ccfiles) also demonstrates the problem if the perspective percentage goes past 56 and the clip is set. Turning the clip off allows the full perspective range (the computed val for 0-100% ranges from 0.0 to -0.005 as per the test case submitted).Update: I added a checkbox for switching between intersect and diff clips and both types of clip fail at the same time. The intersect clip fails by clipping everything out suddenly, and the diff clip fails by just not carving out the center chunk as it is supposed to. But, both types of clip fail at around 56% perspective.
Playground test with controls for perspective %, clip/diff clip/no clip
[Impeller] Fix interpolation error in Rect::TransformAndClipBounds (#…
[Impeller] Fix perspective clips with a large perspective bias (#181434)
github-actions commentedon Feb 9, 2026
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of
flutter doctor -vand a minimal reproduction of the issue.[Impeller] Fix perspective clips with a large perspective bias (flutt…
[Impeller] Fix perspective clips with a large perspective bias (#181434)