Skip to content

BackdropFilter shader UV sampling is incorrect on beta when using ClipRect #178798

Description

@timcreatedit

This issue might be related to #170820

Steps to reproduce

  1. Run the code sample on the current beta channel, and on 3.38.0 (stable)
  2. They produce different outputs

Expected results

The UV's of BackdropFilter used to stay consistent, even if it was clipped. Output on 3.38.0:

Image

Notice how the top left of the shader's rect is not entirely black, and the purple border isn't visible, because UV (0,0) is the top left of the screen, not of the clip rect.

Actual results

Output on 3.39.0-0.1.pre:

Image

Notice how the UV now seem to be in the coordinate space of the ClipRectLayer

Code sample

Code sample

assets/shaders/uv.frag:

#version460 core
precisionmediumpfloat;
#include <flutter/runtime_effect.glsl>uniformvec2 uSize;
uniformsampler2D uTexture;
outvec4 fragColor;
void main() {
vec2 fragCoord = FlutterFragCoord().xy;
vec2 screenUV =vec2(fragCoord.x / uSize.x, fragCoord.y / uSize.y); vec4 texColor = texture(uTexture, screenUV);
 #ifdef IMPELLER_TARGET_OPENGLES
screenUV.y =1.0- screenUV.y;
 #endif// Check if we're within 20px of any edgefloat borderWidth =20.0;
bool inBorder = fragCoord.x < borderWidth || fragCoord.x > (uSize.x - borderWidth) ||
fragCoord.y < borderWidth || fragCoord.y > (uSize.y - borderWidth);
if (inBorder) {
fragColor =vec4(0.5, 0.0, 0.5, 1.0); // Purple border
} else {
fragColor =vec4(screenUV, 0.0, 1.0);
fragColor =mix(fragColor, texColor, .5);
}
}

pubspec.yaml

name: flutter_sandboxdescription: "A new Flutter project."publish_to: 'none'version: 0.1.0environment:
sdk: ^3.9.2dependencies:
flutter:
sdk: flutterflutter_shaders: ^0.1.3dev_dependencies:
flutter_test:
sdk: flutterflutter_lints: ^5.0.0flutter:
uses-material-design: trueshaders:
- assets/shaders/uv.frag

lib/main.dart:

import'dart:ui';
import'package:flutter/material.dart';
import'package:flutter/rendering.dart';
import'package:flutter_shaders/flutter_shaders.dart';
voidmain() {
runApp(constMainApp());
}
classMainAppextendsStatelessWidget {
constMainApp({super.key});
@overrideWidgetbuild(BuildContext context) {
returnMaterialApp(
home:Scaffold(
body:Stack(
children: [
Positioned.fill(child:GridPaper()),
Positioned.fill(
child:ShaderBuilder(
assetKey:'assets/shaders/uv.frag',
(context, shader, child) =>MyShaderWidget(shader: shader),
),
),
],
),
),
);
}
}
classMyShaderWidgetextendsSingleChildRenderObjectWidget {
constMyShaderWidget({super.key, requiredthis.shader, super.child});
finalFragmentShader shader;
@overrideRenderObjectcreateRenderObject(BuildContext context) {
returnRenderMyShader(shader);
}
}
classRenderMyShaderextendsRenderProxyBox {
RenderMyShader(this.shader);
finalFragmentShader shader;
finalLayerHandle<ClipRectLayer> _clipRectLayer =LayerHandle<ClipRectLayer>();
finalLayerHandle<BackdropFilterLayer> _backdropFilterLayer =LayerHandle<BackdropFilterLayer>();
staticconst inset =EdgeInsets.all(66);
@overridevoidpaint(PaintingContext context, Offset offset) {
final rect = offset & size;
_clipRectLayer.layer = context.pushClipRect(
true,
offset,
inset.deflateRect(rect),
(context, offset) {
final layer = _backdropFilterLayer.layer ??=BackdropFilterLayer();
layer.filter =ImageFilter.shader(shader);
context.pushLayer(layer, (context, offset) {}, offset);
},
oldLayer: _clipRectLayer.layer,
);
super.paint(context, offset);
}
@overridevoiddispose() {
_clipRectLayer.layer =null;
_backdropFilterLayer.layer =null;
super.dispose();
}
}

Logs

No response

Flutter Doctor output

Doctor output
[✓] Flutter (Channel beta, 3.39.0-0.1.pre, on macOS 15.7.2 24G325 darwin-arm64, locale en-US)[✓] Android toolchain - develop for Android devices (Android SDK version 36.1.0-rc1)[✓] Xcode - develop for iOS and macOS (Xcode 26.0)[✓] Chrome - develop for the web[✓] Connected device (4 available)[✓] Network resources• No issues found!

Metadata

Metadata

Assignees

Labels

P2Important issues not at the top of the work liste: impellerImpeller rendering backend issues and features requeststeam-engineOwned by Engine teamtriaged-engineTriaged by Engine team

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions