Skip to content

Commit 46eb615

Browse files
authored
Separate "Getting Started" and "How Shaders Work" pages (#14)
1 parent 8c1e86d commit 46eb615

8 files changed

+146
-196
lines changed

source/getting-started.md

Lines changed: 10 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ directory: getting-started/
77
---
88

99
# Getting Started with Flutter Shaders
10+
1011
Shaders in Flutter allow you to create stunning visual effects and performant graphics directly in
1112
your Flutter applications. This guide will take you from basic concepts to implementing real shader
1213
effects in your apps.
@@ -21,43 +22,6 @@ TL;DR: To use a shader from this website:
2122
5. **Create a CustomPainter** similar to the example above
2223
6. **Set the required uniforms** in the `paint` method
2324

24-
## What Are Fragment Shaders?
25-
Fragment shaders are small GPU programs that determine the color of each pixel on the screen. Think
26-
of them as functions that run in parallel for every pixel, where:
27-
28-
- **Input**: The pixel's position (coordinates) and custom parameters called uniforms
29-
- **Output**: A single color value for that pixel
30-
31-
**NOTE**: Shaders run on the GPU, making them incredibly fast. Fragment shaders are typically the
32-
final step in the graphics pipeline, which is why they're so efficient for real-time effects.
33-
34-
## Flutter + Fragment Shaders
35-
Flutter is hardware-accelerated, meaning it leverages GPU shaders for rendering. Every widget you
36-
see - from a simple `Container` to complex blur effects - is ultimately rendered using optimized
37-
shaders. This is what makes Flutter so smooth and performant across platforms.
38-
39-
## Types of Shader Usage in Flutter
40-
There are three main ways to use custom shaders in Flutter:
41-
42-
### 1. Paint from Scratch
43-
Create visual effects directly without any underlying content:
44-
- Custom graphics and animations
45-
- Procedural patterns and textures
46-
- Mathematical visualizations
47-
48-
### 2. Modify Widget Content
49-
Transform the appearance of existing widgets:
50-
- Apply filters and effects to images
51-
- Distort or animate widget content
52-
- Create transitions between states
53-
54-
### 3. Backdrop Effects
55-
Modify content behind widgets:
56-
- Blur backgrounds
57-
- Create glass-like effects
58-
- Background distortions
59-
60-
6125
## Step-by-Step Setup
6226
Follow these steps to create your first Flutter shader project:
6327

@@ -232,115 +196,14 @@ You should see a colorful animated shader effect!
232196

233197
![Animated Colors Effect](animated_colors.gif)
234198

235-
## Different Approaches to Using Shaders in Flutter
236-
237-
### Available Shader Approaches
238-
239-
#### 1. CustomPainter + FragmentShader
240-
- **Use Case**: Paint from scratch using the GPU
241-
- **Pros**: Direct access to raw shader API
242-
- **Cons**: More complex setup and boilerplate code
243-
244-
#### 2. ImageFiltered + ImageFilter.shader
245-
- **Use Case**: Apply shader effects to child widgets
246-
- **Pros**: Easy to apply shader effects to any widget
247-
- **Cons**: Requires Impeller renderer; cannot control the first two uniforms (vec2 for texture
248-
size and sampler2D) as they are set by the Flutter engine
249-
250-
#### 3. BackdropFilter + ImageFilter.shader
251-
- **Use Case**: Apply shader effects to background content
252-
- **Pros**: Easy backdrop shader effects
253-
- **Cons**: Requires Impeller renderer;cannot control the first two uniforms (vec2 for texture
254-
size and sampler2D) as they are set by the Flutter engine
255-
256-
#### 4. flutter_shaders Package
257-
- **Use Case**: Simplified shader usage - easily transform any widget into a shader-compatible image
258-
- **Pros**: Less boilerplate code; full control over all unifroms.
259-
- **Cons**: Requires an external dependency; Can't integrate with BackdropFilter widget
260-
261-
262-
### Key Differences: ImageFilter.shader vs. flutter_shaders
263-
264-
**ImageFilter.shader** (Native Flutter API):
265-
266-
* **Integration**: Built directly into the Flutter framework (`dart:ui`).
267-
* **Rendering Backend**: **Requires the Impeller rendering engine.** It will not work with other
268-
backends.
269-
* **BackdropFilter**: **Supports `BackdropFilter`**, allowing you to apply shader effects to the
270-
content behind a widget.
271-
* **API Flexibility**: Operates on a "convention over configuration" model. It simplifies the
272-
process by automatically providing and managing core uniforms (like the input texture), but this
273-
reduces flexibility as you have less control over the shader's direct inputs.
274-
* **Dependencies**: None, as it's part of the Flutter SDK.
275-
276-
**flutter_shaders** (Third-party Package):
199+
Now that you've successfully created your first shader effect, let's explore the different ways you can use shaders in a Flutter app. The following examples demonstrate various techniques, from using `CustomPainter` for drawing effects from scratch to applying shaders to existing widgets with `ImageFilter`.
277200

278-
* **Integration**: A community-created package that needs to be added as a dependency.
279-
* **Rendering Backend**: **Backend-agnostic**, making it compatible with various rendering
280-
backends, not just Impeller.
281-
* **BackdropFilter**: **Does not directly support `BackdropFilter`**. Its effects are generally
282-
limited to the widgets it's applied to.
283-
* **API Flexibility**: Provides more direct control over the `FragmentShader` object. You have
284-
full responsibility for declaring and managing all uniforms, which offers maximum flexibility and
285-
power at the cost of potentially more boilerplate code.
286-
* **Dependencies**: Requires adding the `flutter_shaders` package to your `pubspec.yaml`.
287-
288-
### Rendering Pipeline Performance Impact
289-
A critical difference between these approaches lies in **when and how many times rendering occurs**
290-
during the Flutter frame lifecycle:
291-
292-
**ImageFilter.shader** (Native Flutter API):
293-
- Starts during the **build phase** and integrates directly with Flutter's compositing layer
294-
- Processes in **single-pass rendering** within the normal pipeline
295-
- **Does not trigger additional raster operations** beyond the standard frame rendering
296-
297-
You'll notice in the timeline that this process doesn't trigger any additional raster operations
298-
beyond what's standard for a frame (compared to the below example).
299-
300-
![ImageFilter starts during build phase](using_image_filter_starts_during_build_phase.png)
301-
302-
High-level view of the frame lifecycle:
303-
304-
![ImageFilter does not trigger raster operation](using_image_filter_starts_during_build_phase_and_does_not_trigger_raster_operation.png)
305-
306-
**flutter_shaders** (Third-party Package):
307-
- Starts during the **compositing phase** using `AnimatedSampler` to capture widget subtrees
308-
- Requires **2 raster frames per UI frame** due to texture capture overhead via `toImageSync()`
309-
- **Triggers additional raster operations** for texture creation and shader application
310-
311-
The timeline shows this extra raster work initiated by the package.
312-
313-
![flutter_shaders starts during compositing phase](using_flutter_shaders_starts_during_compositing_phase.png)
314-
315-
High-level view of the frame lifecycle:
316-
317-
![flutter_shaders triggers raster operation](using_flutter_shaders_starts_during_compositing_phase_and_does_trigger_raster_operation.png)
318-
319-
### When to use which?
320-
* Use **ImageFilter.shader** for:
321-
* Applying shader effects as a BackdropFilter.
322-
* Projects where you can rely on the Impeller rendering engine.
323-
* Avoiding third-party dependencies.
324-
* Optimal performance with single-pass rendering.
325-
* Use the **flutter_shaders** package for:
326-
* Broader compatibility across different Flutter rendering backends (Skia and Impeller).
327-
* Complex effects requiring fine-grained control over all shader uniforms (for example size
328-
unifrom).
329-
330-
## Impeller Status by Platform
331-
**ImageFilter.shader** requires Impeller. Check platform availability:
332-
333-
- **iOS**: Impeller default (Flutter 3.29+)
334-
- **Android**: Impeller default (API 29+), falls back to OpenGL on older versions
335-
- **macOS**: Impeller behind flag
336-
- **Windows/Linux**: Impeller experimental
337-
- **Web**: Uses Skia (no Impeller yet)
338-
339-
For detailed status across Flutter versions, see the [official Flutter team spreadsheet](https://docs.google.com/spreadsheets/d/1AebMvprRkxP-D6ndx920lbvDBbhg-sNNRJ64XY2P2t0/edit?gid=0#gid=0).
201+
For a deeper dive into the technical differences between these approaches and to understand when to use each one, be sure to read our guide on [How Shaders Work](/how-shaders-work/).
340202

203+
Let's look at the examples.
341204

342205
## Example 1: CustomPainter + FragmentShader
343-
**Creates visual effects from scratch using the GPU**
206+
**Creates visual effects from scratch**
344207

345208
![Gradient Flow Effect](gradient_flow.gif)
346209

@@ -433,7 +296,7 @@ class ShaderPainter extends CustomPainter {
433296

434297

435298
## Example 2: flutter_shaders Package
436-
**Simplified shader usage with automatic texture management**
299+
**Simplified shader usage with ShaderBuilder**
437300

438301
![Stripes Pattern Effect](stripes.gif)
439302

@@ -614,10 +477,9 @@ class _ImageFilterDemoState extends State<ImageFilterDemo>
614477
);
615478
},
616479
),
617-
),
618-
);
619-
},
620-
),
480+
);
481+
},
482+
),
621483
);
622484
}
623485
@@ -753,4 +615,4 @@ class _BackdropFilterDemoState extends State<BackdropFilterDemo>
753615
super.dispose();
754616
}
755617
}
756-
```
618+
```

source/how-shaders-work.jinja

Lines changed: 0 additions & 48 deletions
This file was deleted.

source/how-shaders-work.md

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
---
2+
title: How Shaders Work in Flutter
3+
description: Understand the core concepts of fragment shaders, how they integrate with Flutter, and the different rendering approaches available.
4+
layout: layouts/content_page.jinja
5+
directory: how-shaders-work/
6+
---
7+
8+
# How Shaders Work in Flutter
9+
This guide explores the fundamental concepts behind shaders in Flutter, from the basics of fragment shaders to the different ways you can use them in your applications.
10+
11+
## What Are Fragment Shaders?
12+
Fragment shaders are small GPU programs that determine the color of each pixel on the screen. Think of them as functions that run in parallel for every pixel, where:
13+
14+
- **Input**: The pixel's position (coordinates) and custom parameters called uniforms
15+
- **Output**: A single color value for that pixel
16+
17+
**NOTE**: Shaders run on the GPU, making them incredibly fast. Fragment shaders are typically the final step in the graphics pipeline, which is why they're so efficient for real-time effects.
18+
19+
## Flutter + Fragment Shaders
20+
Flutter is hardware-accelerated, meaning it leverages GPU shaders for rendering. Every widget you see - from a simple `Container` to complex blur effects - is ultimately rendered using optimized shaders. This is what makes Flutter so smooth and performant across platforms.
21+
22+
## Types of Shader Usage in Flutter
23+
There are three main ways to use custom shaders in Flutter:
24+
25+
![Types of Shader Usage in Flutter](usage_examples.png)
26+
27+
28+
### 1. Paint from Scratch
29+
Create visual effects directly without any underlying content:
30+
- Custom graphics and animations
31+
- Procedural patterns and textures
32+
- Mathematical visualizations
33+
34+
### 2. Modify Widget Content
35+
Transform the appearance of existing widgets:
36+
- Apply filters and effects to images
37+
- Distort or animate widget content
38+
- Create transitions between states
39+
40+
### 3. Backdrop Effects
41+
Modify content behind widgets:
42+
- Blur backgrounds
43+
- Create glass-like effects
44+
- Background distortions
45+
46+
## Different Approaches to Using Shaders in Flutter
47+
48+
#### 1. CustomPainter + FragmentShader
49+
- **Use Case**: Paint from scratch using the GPU
50+
- **Pros**: Direct access to raw shader API
51+
- **Cons**: More complex setup and boilerplate code
52+
53+
#### 2. ImageFiltered + ImageFilter.shader
54+
- **Use Case**: Apply shader effects to child widgets
55+
- **Pros**: Easy to apply shader effects to any widget
56+
- **Cons**: Requires Impeller renderer; cannot control the first two uniforms (vec2 for texture size and sampler2D) as they are set by the Flutter engine
57+
58+
#### 3. BackdropFilter + ImageFilter.shader
59+
- **Use Case**: Apply shader effects to background content
60+
- **Pros**: Easy backdrop shader effects
61+
- **Cons**: Requires Impeller renderer;cannot control the first two uniforms (vec2 for texture size and sampler2D) as they are set by the Flutter engine
62+
63+
#### 4. flutter_shaders Package
64+
- **Use Case**: Simplified shader usage - easily transform any widget into a shader-compatible image
65+
- **Pros**: Less boilerplate code; full control over all unifroms.
66+
- **Cons**: Requires an external dependency; Can't integrate with BackdropFilter widget
67+
68+
69+
### Key Differences: ImageFilter.shader vs. flutter_shaders
70+
71+
**ImageFilter.shader** (Native Flutter API):
72+
73+
* **Integration**: Built directly into the Flutter framework (`dart:ui`).
74+
* **Rendering Backend**: **Requires the Impeller rendering engine.** It will not work with other backends.
75+
* **BackdropFilter**: **Supports `BackdropFilter`**, allowing you to apply shader effects to the content behind a widget.
76+
* **API Flexibility**: Operates on a "convention over configuration" model. It simplifies the process by automatically providing and managing core uniforms (like the input texture), but this reduces flexibility as you have less control over the shader's direct inputs.
77+
* **Dependencies**: None, as it's part of the Flutter SDK.
78+
79+
**flutter_shaders** (Third-party Package):
80+
81+
* **Integration**: A community-created package that needs to be added as a dependency.
82+
* **Rendering Backend**: **Backend-agnostic**, making it compatible with various rendering backends, not just Impeller.
83+
* **BackdropFilter**: **Does not directly support `BackdropFilter`**. Its effects are generally limited to the widgets it's applied to.
84+
* **API Flexibility**: Provides more direct control over the `FragmentShader` object. You have full responsibility for declaring and managing all uniforms, which offers maximum flexibility and power at the cost of potentially more boilerplate code.
85+
* **Dependencies**: Requires adding the `flutter_shaders` package to your `pubspec.yaml`.
86+
87+
### Rendering Pipeline Performance Impact
88+
A critical difference between these approaches lies in **when and how many times rendering occurs** during the Flutter frame lifecycle:
89+
90+
**ImageFilter.shader** (Native Flutter API):
91+
- Starts during the **build phase** and integrates directly with Flutter's compositing layer
92+
- Processes in **single-pass rendering** within the normal pipeline
93+
- **Does not trigger additional raster operations** beyond the standard frame rendering
94+
95+
You'll notice in the timeline that this process doesn't trigger any additional raster operations beyond what's standard for a frame (compared to the below example).
96+
97+
![ImageFilter starts during build phase](using_image_filter_starts_during_build_phase.png)
98+
99+
High-level view of the frame lifecycle:
100+
101+
![ImageFilter does not trigger raster operation](using_image_filter_starts_during_build_phase_and_does_not_trigger_raster_operation.png)
102+
103+
**flutter_shaders** (Third-party Package):
104+
- Starts during the **compositing phase** using `AnimatedSampler` to capture widget subtrees
105+
- Requires **2 raster frames per UI frame** due to texture capture overhead via `toImageSync()`
106+
- **Triggers additional raster operations** for texture creation and shader application
107+
108+
The timeline shows this extra raster work initiated by the package.
109+
110+
![flutter_shaders starts during compositing phase](using_flutter_shaders_starts_during_compositing_phase.png)
111+
112+
High-level view of the frame lifecycle:
113+
114+
![flutter_shaders triggers raster operation](using_flutter_shaders_starts_during_compositing_phase_and_does_trigger_raster_operation.png)
115+
116+
### When to use which?
117+
* Use **ImageFilter.shader** for:
118+
* Applying shader effects as a BackdropFilter.
119+
* Projects where you can rely on the Impeller rendering engine.
120+
* Avoiding third-party dependencies.
121+
* Optimal performance with single-pass rendering.
122+
* Use the **flutter_shaders** package for:
123+
* Broader compatibility across different Flutter rendering backends (Skia and Impeller).
124+
* Complex effects requiring fine-grained control over all shader uniforms (for example size unifrom).
125+
126+
## Impeller Status by Platform
127+
**ImageFilter.shader** requires Impeller. Check platform availability:
128+
129+
- **iOS**: Impeller default (Flutter 3.29+)
130+
- **Android**: Impeller default (API 29+), falls back to OpenGL on older versions
131+
- **macOS**: Impeller behind flag
132+
- **Windows/Linux**: Impeller experimental
133+
- **Web**: Uses Skia (no Impeller yet)
134+
135+
For detailed status across Flutter versions, see the [official Flutter team spreadsheet](https://docs.google.com/spreadsheets/d/1AebMvprRkxP-D6ndx920lbvDBbhg-sNNRJ64XY2P2t0/edit?gid=0#gid=0).
136+
544 KB
Loading
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)