import 'dart:ui' as ui; import 'dart:typed_data'; import 'package:flutter_test/flutter_test.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); test( 'glass samples and bends background pixels while keeping the centre stable', () async { const width = 160, height = 100; final sourceRecorder = ui.PictureRecorder(); final sourceCanvas = ui.Canvas(sourceRecorder); for (var x = 0; x < width; x++) { sourceCanvas.drawRect( ui.Rect.fromLTWH(x.toDouble(), 0, 1, height.toDouble()), ui.Paint()..color = ui.Color.fromARGB(255, 40 + x, 70, 90), ); } final sourcePicture = sourceRecorder.endRecording(); final source = await sourcePicture.toImage(width, height); final program = await ui.FragmentProgram.fromAsset( 'shaders/liquid_glass.frag', ); final shader = program.fragmentShader() ..setFloat(0, width.toDouble()) ..setFloat(1, height.toDouble()) ..setFloat(2, 0) ..setFloat(3, 0) ..setFloat(4, width.toDouble()) ..setFloat(5, height.toDouble()) ..setImageSampler(0, source); Future draw(double strength) async { shader.setFloat(6, strength); final recorder = ui.PictureRecorder(); ui.Canvas(recorder).drawRect( ui.Rect.fromLTWH(0, 0, width.toDouble(), height.toDouble()), ui.Paint()..shader = shader, ); final picture = recorder.endRecording(); final image = await picture.toImage(width, height); picture.dispose(); return image; } final plain = await draw(0), refracted = await draw(1); final a = (await plain.toByteData())!, b = (await refracted.toByteData())!; int red(ByteData data, int x) => data.getUint8((50 * width + x) * 4); expect(red(a, 12), closeTo(52, 1)); expect((red(b, 12) - red(a, 12)).abs(), greaterThan(3)); expect(red(b, 80), closeTo(red(a, 80), 1)); expect(b.getUint8((50 * width + 12) * 4 + 3), 255); shader.dispose(); plain.dispose(); refracted.dispose(); source.dispose(); sourcePicture.dispose(); }, ); }