You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Implement anti-aliased DrawPath for MetalSDF #185117
I prototyped a method that uses the convex shadow code which avoids overlapping vertices so it should work very easily with a shader that just takes the coverage (SDF value) from the vertex attributes. But, that algorithm isn't 100% trustworthy on all convex shapes because it sometimes gets confused trying to arbitrate the interior intersections.
Another option is to use the stroking code which just ignores the interior intersections, but it would require us to deal with the overlapping geometry somehow - using an accumulation buffer?
I'm really glad to see the Flutter team exploring this.
I've also been exploring ways to render paths with analytical anti-aliasing in our 2D renderer. After looking into Servo Pathfinder
, Linebender Vello's sparse strips
, and several related papers, I feel that dividing the path into tiles is a very promising approach.
More specifically, we can partition the render target into tiles such as 16×16 or 4×4, with the tile size chosen based on the needs of the project. We then classify each tile by its relationship to the path: a tile may lie completely outside the path, in which case it can be skipped entirely; it may lie fully inside the path, in which case the whole tile can be filled directly; or it may intersect the path boundary. Only in this last case do we need to perform more fine-grained analytical AA calculations for the pixels inside that tile.
This way, the expensive edge-processing work is limited to a relatively small number of boundary tiles, instead of applying complex per-pixel calculations across the entire render target, which can significantly improve overall rendering performance.
And if you'd like to use an SDF-based approach, it's worth taking a look at Vger
. It splits paths horizontally into slabs, then determines in the fragment function whether a pixel lies inside the path and computes its distance to the path edge. For the classic Tiger SVG
, it can render the whole image in a single draw call.
@ColdPaleLight, I think your tiling approach is applicable to all of the SDF rendering we've implemented so far. This is a good optimization that we should consider if performance becomes an issue with our SDF rendering.
Activity
[-]Implement anti-aliased DrawPath[/-][+]Implement anti-aliased DrawPath for MetalSDF[/+]flar commentedon Apr 16, 2026
I prototyped a method that uses the convex shadow code which avoids overlapping vertices so it should work very easily with a shader that just takes the coverage (SDF value) from the vertex attributes. But, that algorithm isn't 100% trustworthy on all convex shapes because it sometimes gets confused trying to arbitrate the interior intersections.
Another option is to use the stroking code which just ignores the interior intersections, but it would require us to deal with the overlapping geometry somehow - using an accumulation buffer?
ColdPaleLight commentedon Apr 28, 2026
I'm really glad to see the Flutter team exploring this.
I've also been exploring ways to render paths with analytical anti-aliasing in our 2D renderer. After looking into Servo Pathfinder
, Linebender Vello's sparse strips
, and several related papers, I feel that dividing the path into tiles is a very promising approach.
More specifically, we can partition the render target into tiles such as 16×16 or 4×4, with the tile size chosen based on the needs of the project. We then classify each tile by its relationship to the path: a tile may lie completely outside the path, in which case it can be skipped entirely; it may lie fully inside the path, in which case the whole tile can be filled directly; or it may intersect the path boundary. Only in this last case do we need to perform more fine-grained analytical AA calculations for the pixels inside that tile.
This way, the expensive edge-processing work is limited to a relatively small number of boundary tiles, instead of applying complex per-pixel calculations across the entire render target, which can significantly improve overall rendering performance.
Here are some related articles:
https://gasiulis.name/vector-graphics-on-gpu/
https://nical.github.io/posts/a-look-at-pathfinder.html
And if you'd like to use an SDF-based approach, it's worth taking a look at Vger
. It splits paths horizontally into slabs, then determines in the fragment function whether a pixel lies inside the path and computes its distance to the path edge. For the classic Tiger SVG
, it can render the whole image in a single draw call.
walley892 commentedon Jun 9, 2026
I've written a design that explores a few approaches https://docs.google.com/document/d/1wFDhoPfyobAMPeOVw-XrKn-jvTQ8nUaWHbGiMkUcm4g/edit?usp=sharing
@ColdPaleLight, I think your tiling approach is applicable to all of the SDF rendering we've implemented so far. This is a good optimization that we should consider if performance becomes an issue with our SDF rendering.
Add path rendering benchmarks (flutter#188654)
flar commentedon Aug 10, 2026
See also #183960 if we find a solution for convex-only paths.
flar commentedon Aug 10, 2026
See also #183959 which contains other suggestions than the ones provided above.