mirror of
https://github.com/flutter/samples.git
synced 2026-04-25 00:11:49 +00:00
Add new sample simple_sdf (#2835)
Add a new sample, `simple_sdf`. This is similar to `simple_shader`, but it focuses on using Signed Distance Functions within the fragment shader. Relates to issue [#183043](https://github.com/flutter/flutter/issues/183043) ## Pre-launch Checklist - [x] I read the [Flutter Style Guide] _recently_, and have followed its advice. - [x] I signed the [CLA]. - [x] I read the [Contributors Guide]. - [ ] I have added sample code updates to the [changelog]. - [x] I updated/added relevant documentation (doc comments with `///`). If you need help, consider asking for advice on the #hackers-devrel channel on [Discord]. <!-- Links --> [Flutter Style Guide]: https://github.com/flutter/flutter/blob/master/docs/contributing/Style-guide-for-Flutter-repo.md [CLA]: https://cla.developers.google.com/ [Discord]: https://github.com/flutter/flutter/blob/master/docs/contributing/Chat.md [Contributors Guide]: https://github.com/flutter/samples/blob/main/CONTRIBUTING.md [changelog]: ../CHANGELOG.md
This commit is contained in:
6
.github/dependabot.yaml
vendored
6
.github/dependabot.yaml
vendored
@@ -281,6 +281,12 @@ updates:
|
|||||||
interval: "daily"
|
interval: "daily"
|
||||||
labels:
|
labels:
|
||||||
- "autosubmit"
|
- "autosubmit"
|
||||||
|
- package-ecosystem: "pub"
|
||||||
|
directory: "simple_sdf/"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
|
labels:
|
||||||
|
- "autosubmit"
|
||||||
- package-ecosystem: "pub"
|
- package-ecosystem: "pub"
|
||||||
directory: "simple_shader/"
|
directory: "simple_shader/"
|
||||||
schedule:
|
schedule:
|
||||||
|
|||||||
@@ -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.
|
* [`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.
|
* [`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.
|
* [`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 draw Signed Distance Functions with the FragmentShader API.
|
||||||
* [`simple_shader`] - A simple [Flutter fragment shaders] sample project.
|
* [`simple_shader`] - A simple [Flutter fragment shaders] sample project.
|
||||||
* [`testing_app`] - A sample app that shows different types of testing in Flutter.
|
* [`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).
|
* [`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
|
[`navigation_and_routing`]: ./navigation_and_routing
|
||||||
[`pedometer`]: ./pedometer
|
[`pedometer`]: ./pedometer
|
||||||
[`platform_design`]: ./platform_design
|
[`platform_design`]: ./platform_design
|
||||||
|
[`simple_sdf`]: ./simple_sdf
|
||||||
[`simple_shader`]: ./simple_shader
|
[`simple_shader`]: ./simple_shader
|
||||||
[`testing_app`]: ./testing_app
|
[`testing_app`]: ./testing_app
|
||||||
[`web_embedding`]: ./web_embedding
|
[`web_embedding`]: ./web_embedding
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ workspace:
|
|||||||
- platform_channels
|
- platform_channels
|
||||||
- platform_design
|
- platform_design
|
||||||
- platform_view_swift
|
- platform_view_swift
|
||||||
|
- simple_sdf
|
||||||
- simple_shader
|
- simple_shader
|
||||||
- testing_app
|
- testing_app
|
||||||
- tool
|
- tool
|
||||||
|
|||||||
44
simple_sdf/.gitignore
vendored
Normal file
44
simple_sdf/.gitignore
vendored
Normal file
@@ -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
|
||||||
9
simple_sdf/README.md
Normal file
9
simple_sdf/README.md
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# `simple_sdf`
|
||||||
|
|
||||||
|
A simple [Flutter fragment shaders][] sample project showing how to draw Signed Distance Functions with the FragmentShader API.
|
||||||
|
|
||||||
|
Use `flutter create --no-overwrite .` to initialize the project.
|
||||||
|
|
||||||
|
[Flutter fragment shaders]: https://docs.flutter.dev/development/ui/advanced/shaders
|
||||||
|
|
||||||
|

|
||||||
1
simple_sdf/analysis_options.yaml
Normal file
1
simple_sdf/analysis_options.yaml
Normal file
@@ -0,0 +1 @@
|
|||||||
|
include: package:analysis_defaults/flutter.yaml
|
||||||
59
simple_sdf/lib/main.dart
Normal file
59
simple_sdf/lib/main.dart
Normal file
@@ -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 SDF 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 SDF Demo')),
|
||||||
|
body: ShaderBuilder(
|
||||||
|
assetKey: 'shaders/SDF.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;
|
||||||
|
}
|
||||||
|
}
|
||||||
23
simple_sdf/pubspec.yaml
Normal file
23
simple_sdf/pubspec.yaml
Normal file
@@ -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/SDF.frag
|
||||||
BIN
simple_sdf/screenshot.png
Normal file
BIN
simple_sdf/screenshot.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 112 KiB |
62
simple_sdf/shaders/SDF.frag
Normal file
62
simple_sdf/shaders/SDF.frag
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
#version 460 core
|
||||||
|
|
||||||
|
#include <flutter/runtime_effect.glsl>
|
||||||
|
|
||||||
|
precision mediump float;
|
||||||
|
|
||||||
|
uniform vec2 resolution;
|
||||||
|
out vec4 fragColor;
|
||||||
|
|
||||||
|
vec3 pink = vec3(255, 105, 180) / 255;
|
||||||
|
|
||||||
|
// dot2 and sdHeart from https://iquilezles.org/articles/distfunctions2d/
|
||||||
|
//
|
||||||
|
// The MIT License
|
||||||
|
// Copyright © 2015 Inigo Quilez
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions: The above copyright
|
||||||
|
// notice and this permission notice shall be included in all copies or
|
||||||
|
// substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS",
|
||||||
|
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||||
|
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||||
|
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
|
||||||
|
// THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
// https://www.youtube.com/c/InigoQuilez
|
||||||
|
// https://iquilezles.org
|
||||||
|
|
||||||
|
float dot2(vec2 v) { return dot(v, v); }
|
||||||
|
float sdHeart(in vec2 p) {
|
||||||
|
p.x = abs(p.x);
|
||||||
|
|
||||||
|
if (p.y + p.x > 1.0)
|
||||||
|
return sqrt(dot2(p - vec2(0.25, 0.75))) - sqrt(2.0) / 4.0;
|
||||||
|
return sqrt(min(dot2(p - vec2(0.00, 1.00)),
|
||||||
|
dot2(p - 0.5 * max(p.x + p.y, 0.0)))) *
|
||||||
|
sign(p.x - p.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 st = FlutterFragCoord().xy / resolution.xy;
|
||||||
|
// Remap coordinates.
|
||||||
|
// Flutter normalized coordinates have range [0,1] but sdHeart expects [-1,1].
|
||||||
|
st = (st - vec2(0.5)) * vec2(2.0);
|
||||||
|
// Center the heart.
|
||||||
|
// sdHeart is written such that the bottom point is at (0,0) and it's about 1
|
||||||
|
// unit tall.
|
||||||
|
st.y -= 0.5;
|
||||||
|
// Invert Y coordinate.
|
||||||
|
st.y *= -1;
|
||||||
|
|
||||||
|
// Calculate the color of this pixel according to the heart SDF, using
|
||||||
|
// smoothstep to anti-alias the edges.
|
||||||
|
vec3 color = vec3(0.0);
|
||||||
|
color = mix(pink, color, smoothstep(0.01, 0.02, sdHeart(st)));
|
||||||
|
|
||||||
|
fragColor = vec4(color, 1);
|
||||||
|
}
|
||||||
9
simple_sdf/test/widget_test.dart
Normal file
9
simple_sdf/test/widget_test.dart
Normal file
@@ -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());
|
||||||
|
});
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user