diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml index 7d0d76459..c6445bea5 100644 --- a/.github/dependabot.yaml +++ b/.github/dependabot.yaml @@ -281,6 +281,12 @@ updates: interval: "daily" labels: - "autosubmit" + - package-ecosystem: "pub" + directory: "simple_sdf/" + schedule: + interval: "daily" + labels: + - "autosubmit" - package-ecosystem: "pub" directory: "simple_shader/" schedule: diff --git a/README.md b/README.md index c7ad27a04..4fd96daad 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ Googler's, you can freely add samples to the [flutter/demos] repository. * [`navigation_and_routing`] - A sample that shows how to use [go_router] API to handle common navigation scenarios. * [`pedometer`] - A demo of a plugin that leverages FFIgen & JNIgen to call platform APIs directly from Dart code. * [`platform_design`] - This sample project shows a Flutter app that maximizes application code reuse while adhering to different design patterns on Android and iOS. +* [`simple_sdf`] - A simple [Flutter fragment shaders] sample project showing how to use Signed Distance Functions. * [`simple_shader`] - A simple [Flutter fragment shaders] sample project. * [`testing_app`] - A sample app that shows different types of testing in Flutter. * [`web_embedding`] - This directory contains examples of how to embed Flutter in web apps (without iframes). @@ -123,6 +124,7 @@ If you run into a bug in one of the samples, please file an issue in the [`navigation_and_routing`]: ./navigation_and_routing [`pedometer`]: ./pedometer [`platform_design`]: ./platform_design +[`simple_sdf`]: ./simple_sdf [`simple_shader`]: ./simple_shader [`testing_app`]: ./testing_app [`web_embedding`]: ./web_embedding diff --git a/pubspec.yaml b/pubspec.yaml index e425740e3..a4a3adbf4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -35,6 +35,7 @@ workspace: - platform_channels - platform_design - platform_view_swift + - simple_sdf - simple_shader - testing_app - tool diff --git a/simple_sdf/.gitignore b/simple_sdf/.gitignore new file mode 100644 index 000000000..24476c5d1 --- /dev/null +++ b/simple_sdf/.gitignore @@ -0,0 +1,44 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/simple_sdf/README.md b/simple_sdf/README.md new file mode 100644 index 000000000..9f5aee8b1 --- /dev/null +++ b/simple_sdf/README.md @@ -0,0 +1,9 @@ +# `simple_sdf` + +A simple [Flutter fragment shaders][] sample project showing how to use Signed Distance Functions. + +Use `flutter create --no-overwrite .` to initialize the project. + + [Flutter fragment shaders]: https://docs.flutter.dev/development/ui/advanced/shaders + +![Screenshot of the `simple_sdf` app](screenshot.png) diff --git a/simple_sdf/analysis_options.yaml b/simple_sdf/analysis_options.yaml new file mode 100644 index 000000000..13d6fe105 --- /dev/null +++ b/simple_sdf/analysis_options.yaml @@ -0,0 +1 @@ +include: package:analysis_defaults/flutter.yaml diff --git a/simple_sdf/lib/main.dart b/simple_sdf/lib/main.dart new file mode 100644 index 000000000..e314f91bf --- /dev/null +++ b/simple_sdf/lib/main.dart @@ -0,0 +1,59 @@ +import 'dart:ui' as ui; + +import 'package:flutter/material.dart'; +import 'package:flutter_shaders/flutter_shaders.dart'; + +void main() { + runApp(const MyApp()); +} + +class MyApp extends StatelessWidget { + const MyApp({super.key}); + + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Simple Shader Demo', + theme: ThemeData(colorSchemeSeed: Colors.blue), + home: const MyHomePage(), + ); + } +} + +class MyHomePage extends StatelessWidget { + const MyHomePage({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: const Text('Simple Shader Demo')), + body: ShaderBuilder( + assetKey: 'shaders/simple.frag', + (context, shader, child) => CustomPaint( + size: MediaQuery.of(context).size, + painter: ShaderPainter(shader: shader), + ), + child: const Center(child: CircularProgressIndicator()), + ), + ); + } +} + +class ShaderPainter extends CustomPainter { + ShaderPainter({required this.shader}); + ui.FragmentShader shader; + + @override + void paint(Canvas canvas, Size size) { + shader.setFloat(0, size.width); + shader.setFloat(1, size.height); + + final paint = Paint()..shader = shader; + canvas.drawRect(Rect.fromLTWH(0, 0, size.width, size.height), paint); + } + + @override + bool shouldRepaint(covariant CustomPainter oldDelegate) { + return false; + } +} diff --git a/simple_sdf/pubspec.yaml b/simple_sdf/pubspec.yaml new file mode 100644 index 000000000..7b61da32b --- /dev/null +++ b/simple_sdf/pubspec.yaml @@ -0,0 +1,23 @@ +name: simple_sdf +description: Using a shader, simply. +publish_to: 'none' +version: 1.0.0+1 +resolution: workspace + +environment: + sdk: ^3.9.0-0 + +dependencies: + flutter: + sdk: flutter + flutter_shaders: ^0.1.0 + +dev_dependencies: + analysis_defaults: + path: ../analysis_defaults + flutter_test: + sdk: flutter +flutter: + uses-material-design: true + shaders: + - shaders/simple.frag diff --git a/simple_sdf/screenshot.png b/simple_sdf/screenshot.png new file mode 100644 index 000000000..2e8df52e4 Binary files /dev/null and b/simple_sdf/screenshot.png differ diff --git a/simple_sdf/shaders/simple.frag b/simple_sdf/shaders/simple.frag new file mode 100644 index 000000000..20075c9ee --- /dev/null +++ b/simple_sdf/shaders/simple.frag @@ -0,0 +1,25 @@ +#version 460 core + +#include + +precision mediump float; + +uniform vec2 resolution; +out vec4 fragColor; + +vec3 flutterBlue = vec3(5, 83, 177) / 255; +vec3 flutterNavy = vec3(4, 43, 89) / 255; +vec3 flutterSky = vec3(2, 125, 253) / 255; + +void main() { + vec2 st = FlutterFragCoord().xy / resolution.xy; + + vec3 color = vec3(0.0); + vec3 percent = vec3((st.x + st.y) / 2); + + color = + mix(mix(flutterSky, flutterBlue, percent * 2), + mix(flutterBlue, flutterNavy, percent * 2 - 1), step(0.5, percent)); + + fragColor = vec4(color, 1); +} diff --git a/simple_sdf/test/widget_test.dart b/simple_sdf/test/widget_test.dart new file mode 100644 index 000000000..794023811 --- /dev/null +++ b/simple_sdf/test/widget_test.dart @@ -0,0 +1,9 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:simple_sdf/main.dart'; + +void main() { + testWidgets('Smoke test', (tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(const MyApp()); + }); +}