Steps to reproduce
- Run
flutter create bug and open the project.
- Add a runtime shader asset
shaders/derivatives_repro.frag (see shader code below).
- In pubspec.yaml, register the shader:
flutter:
shaders:
- shaders/derivatives_repro.frag
- Replace main.dart with the code below.
- Run on Flutter Web:
⚠️ Note: This issue is Web-only. See the platform notes below.
Expected results
On Flutter Web, the runtime shader should:
- Run correctly when derivative functions (
dFdx / dFdy / fwidth) are supported by the underlying browser backend (e.g. WebGL2), or
- Fail with a clear runtime capability error indicating that derivatives are not supported on the active Web backend, with actionable guidance.
Behavior should be consistent with other platforms and with WebGL expectations.
Actual results
On Flutter Web only, the shader fails at runtime when the FragmentProgram is instantiated.
Derivative builtins are rejected during runtime effect creation:
RuntimeEffect error error: 22: no match for dFdx(float)
dx = dFdx(uv.x);
^^^^^^^^^^
error: 23: no match for dFdy(float)
dy = dFdy(uv.y);
^^^^^^^^^^
error: 24: no match for fwidth(float)
fw = fwidth((uv.x + uv.y) + (sin(iTime) * 0.0));
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3 errors
Platform comparison
- ✅ macOS (Skia): works correctly
- ✅ macOS (Impeller disabled): works correctly
- ✅ Android: works correctly
- ✅ iOS: works correctly
- ❌ Web (Chrome, JS & WASM): fails at runtime
The same browser (Chrome) successfully runs derivative-based shaders on ShaderToy, indicating that the Web platform itself supports derivatives.
The same runtime failure occurs when running with --wasm; the behavior is identical to the JS backend.
This suggests a Flutter Web–specific runtime shader validation / translation issue, rather than a general SkSL or shader logic problem.
Code sample
Code sample
// lib/main.dart
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
// Preload shader so failure is obvious and happens immediately.
final ui.FragmentProgram program =
await ui.FragmentProgram.fromAsset('shaders/derivatives_repro.frag');
runApp(MaterialApp(
home: Scaffold(
body: Center(
child: CustomPaint(
size: const Size(512, 512),
painter: _ShaderPainter(program),
),
),
),
));
}
class _ShaderPainter extends CustomPainter {
_ShaderPainter(this.program);
final ui.FragmentProgram program;
@override
void paint(Canvas canvas, Size size) {
final shader = program.fragmentShader();
// Pass uniforms (by index) for runtime_effect.glsl:
// iResolution: vec2, iTime: float
shader
..setFloat(0, size.width)
..setFloat(1, size.height)
..setFloat(2, 0.0);
canvas.drawRect(Offset.zero & size, Paint()..shader = shader);
}
@override
bool shouldRepaint(covariant _ShaderPainter oldDelegate) => false;
}
// shaders/derivatives_repro.frag
#include <flutter/runtime_effect.glsl>
precision highp float;
precision highp int;
uniform vec2 iResolution;
uniform float iTime;
out vec4 fragColor;
void main() {
vec2 fragCoord = FlutterFragCoord().xy;
vec2 uv = fragCoord / max(iResolution, vec2(1.0));
float dx = 0.0;
float dy = 0.0;
float fw = 0.0;
dx = dFdx(uv.x);
dy = dFdy(uv.y);
fw = fwidth((uv.x + uv.y) + (sin(iTime) * 0.0));
vec3 rgb = vec3(abs(dx), abs(dy), abs(fw)) * 200.0;
fragColor = vec4(clamp(rgb, 0.0, 1.0), 1.0);
}
Logs
Logs
RuntimeEffect error error: 22: no match for dFdx(float)
dx = dFdx(uv.x);
^^^^^^^^^^
error: 23: no match for dFdy(float)
dy = dFdy(uv.y);
^^^^^^^^^^
error: 24: no match for fwidth(float)
fw = fwidth((uv.x + uv.y) + (sin(iTime) * 0.0));
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3 errors
Flutter Doctor output
Doctor output
[✓] Flutter (Channel stable, 3.38.4, on macOS 26.2 25C56 darwin-arm64, locale zh-Hans-CN)
• Flutter version 3.38.4 on channel stable
• Framework revision 66dd93f9a2
• Engine revision a5cb96369e
• Dart version 3.10.3
• DevTools version 2.51.1
[✓] Android toolchain - develop for Android devices (Android SDK version 36.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 26.1.1)
[✓] Chrome - develop for the web
• Google Chrome 143.0.7499.193
[✓] Connected device (3 available)
• Chrome (web) • chrome • web-javascript • Google Chrome 143.0.7499.193
Steps to reproduce
flutter create bugand open the project.shaders/derivatives_repro.frag(see shader code below).flutter run -d chromeExpected results
On Flutter Web, the runtime shader should:
dFdx/dFdy/fwidth) are supported by the underlying browser backend (e.g. WebGL2), orBehavior should be consistent with other platforms and with WebGL expectations.
Actual results
On Flutter Web only, the shader fails at runtime when the
FragmentProgramis instantiated.Derivative builtins are rejected during runtime effect creation:
Platform comparison
The same browser (Chrome) successfully runs derivative-based shaders on ShaderToy, indicating that the Web platform itself supports derivatives.
The same runtime failure occurs when running with
--wasm; the behavior is identical to the JS backend.This suggests a Flutter Web–specific runtime shader validation / translation issue, rather than a general SkSL or shader logic problem.
Code sample
Code sample
Logs
Logs
Flutter Doctor output
Doctor output