Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions sites/docs/src/content/perf/antialiasing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
---
title: Impeller anti-aliasing
description: How does Impeller perform anti-aliasing?
---

Aliasing is the visual artifacts that result from drawing geometry to a grid of
Comment thread
gaaclarke marked this conversation as resolved.
pixels (rasterization). The artifacts show up as jagged or rough edges on
shapes. Impeller employs a couple techniques to smooth out the mapping to raster
graphics (anti-aliasing).

## Techniques

### Multisample anti-aliasing (MSAA)

[MSAA][] is a global anti-aliasing technique that operates on the whole contents
of the screen. It is an optimization over rendering the whole screen at a larger
Comment thread
sfshaza2 marked this conversation as resolved.
scale and shrinking it down ([SSAA][]). Instead of doing the fragment operation
for each fragment in a region, if it is determined they have the same coverage,
only one fragment operation is calculated. This limits smoothing to edges.
Mobile phone GPUs have special hardware to optimize this process (
[Tiled rendering][]). It comes in varying degrees of how many samples to
consider.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure how you are defining "fragment operation". If it is "execution of a fragment program" then I don't think this is correct.

For any given pixel I believe it only performs one fragment shader operation on the center of a pixel for any pixel, whether it has all the same MSAA coverage or not. The only thing that MSAA adds is which of the sub-samples it propagates that single result to.

The text above implies that it only runs the fragment shader once for wholly enclosed interior pixels - and??? runs it multiple times for edge pixles? (I don't think it works that way).


On desktop and mobile 4x MSAA is used for all rendering calls.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps mention the consequences of the MSAA #, such as "the quantization of the coverage for edge pixels is limited to the number of MSAA samples" (so edge pixels are always only one of 0%, 25%, 50%, 75%, or 100% covered with MSAA 4).


### Signed distance fields ([SDFs][])

Typically, hardware accelerated computer graphics define a series of points and
edges (a [mesh][]) and [shaders][]. Instead, SDF renders shapes in the fragment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"... and the color sample for pixels is either 0% or 100% the result of the fragment shader (color source?) for each pixel depending on whether it falls in the mesh or not"...?

shader program as signed distance fields. Since the shape is defined in the
fragment shader the edges can be smoothed at the fragment level instead of
relying on the rasterization of a mesh.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"smoothed ... by computing the coverage of the shape over each individual pixel at a high resolution (or precision?) and used to proportionally apply the color sample to that pixel"...?


On desktop, rendering with SDFs is enabled. On mobile platforms, SDFs are an
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"... enabled by default"?

option that defaults to false.

This technique is prioritized on desktop because SDF rendering puts more demand
on the GPU and Flutter supports older mobile phones. Also, the physical pixel
sizes on desktop computers are typically bigger than those of mobile phones. So
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Desktop computers don't have pixels. ;)

"desktop displays"?

Perhaps provide some example statistics?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, bigger in terms of field of view. Mobile phones are viewed closer than desktop displays, but their much higher pixel count still wins out in terms of pixel angular viewing angle thingy bopper...

any imperfection will be more evident there.

### Examples

| No AA | MSAA 4x | MSAA 4x + SDF |
| ------------------------------------------- | ---------------------------------------------- | ------------------------------------------------------- |
| ![No AA](/assets/images/docs/perf/noaa.png) | ![MSAA 4x](/assets/images/docs/perf/msaa4.png) | ![MSAA 4x + SDF](/assets/images/docs/perf/msaa4sdf.png) |
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The images are subtle. One other option is to show a very slightly rotated line where the stepping is far more abrupt with MSAA and it is easy to see more steps with SDF.


## Working with anti-aliasing

### SDFs with the FragmentShader API

Standard primitive shapes in Flutter are drawn automatically with SDFs. If a
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

automatically -> by default unless the developer changes the "?antialiased?" setting in the Paint object...?

Flutter developer wants to define their own custom graphics with SDFs they can
do so with the [FragmentShader API][]. Using the [drawPath()][] is sufficient
for most use cases without resorting to high quality SDF rendering. Not all
drawn paths are guaranteed to result in SDF rendering though.
Comment thread
sfshaza2 marked this conversation as resolved.

An example of rendering SDFs with the FragmentShader API can be found at
[`simple_sdf`][].

### Enabling SDFs on iOS

SDFs can be enabled on iOS by adding a new field to the `Info.plist` for the
project.

```xml
<key>FLTEnableSDFs</key>
<true/>
```

[MSAA]: https://en.wikipedia.org/wiki/Multisample_anti-aliasing
[SSAA]: https://en.wikipedia.org/wiki/Supersampling
[Tiled rendering]: https://en.wikipedia.org/wiki/Tiled_rendering
[SDFs]: https://en.wikipedia.org/wiki/Signed_distance_function
[mesh]: https://en.wikipedia.org/wiki/Polygon_mesh
[shaders]: https://en.wikipedia.org/wiki/Shader
[FragmentShader API]: /ui/design/graphics/fragment-shaders
[drawPath()]: {{site.api}}/flutter/dart-ui/Canvas/drawPath.html
[`simple_sdf`]: {{site.github}}/flutter/samples/tree/main/simple_sdf
2 changes: 2 additions & 0 deletions sites/docs/src/content/perf/impeller.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ check out the [README.md][] file in the source tree.

## Additional information

* [Impeller anti-aliasing][impeller-antialiasing]
* [Frequently asked questions][impeller-faq]
* [Impeller's coordinate system][impeller-coords]
* [How to set up Xcode for GPU frame captures with metal][impeller-xcode-capture]
Expand All @@ -151,6 +152,7 @@ check out the [README.md][] file in the source tree.
* [Guidance for writing efficient shaders][impeller-shader-optimization]
* [How color blending works in Impeller][impeller-blending]

[impeller-antialiasing]: /perf/antialiasing
[impeller-faq]: {{site.repo.flutter}}/blob/main/docs/engine/impeller/docs/faq.md
[impeller-coords]: {{site.repo.flutter}}/blob/main/docs/engine/impeller/docs/coordinate_system.md
[impeller-xcode-capture]: {{site.repo.flutter}}/blob/main/docs/engine/impeller/docs/xcode_frame_capture.md
Expand Down
2 changes: 2 additions & 0 deletions sites/docs/src/data/sidenav/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,8 @@
permalink: /perf
- title: Impeller
permalink: /perf/impeller
- title: Impeller anti-aliasing
permalink: /perf/antialiasing
- title: Performance best practices
permalink: /perf/best-practices
- title: App size
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added sites/docs/web/assets/images/docs/perf/noaa.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading