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
Develop a general (convex or concave) path SDF renderer #183959
Impeller is adding many shape-specific renderers that will enable higher quality antialiasing on low-resolution devices like desktop screens, but we will also need a general solution that can render all paths.
Interestingly I'm working on a fairly similar problem. my thoughts are roughly:
For simple convex shapes, do a basic triangulation then use loop-blinn for curves. For conic, cubic, chop into quads.
For simple concave shapes, do ear clipping then similar loop blinn approach for exterior
For self intersecting ... I'm not sure yet. I was actually thinking about applying the slug algorithm. Not sure how well it will perform.
Besides the shapes themselves, once you start using SDFs the simple approach to blend modes Impeller was using no longer works. For example, BlendMode::clear will clear pixels that aren't "covered" by the SDF unless you're also using discard. But if you use discard then no AA.
Besides the shapes themselves, once you start using SDFs the simple approach to blend modes Impeller was using no longer works. For example, BlendMode::clear will clear pixels that aren't "covered" by the SDF unless you're also using discard. But if you use discard then no AA.
In software we used to apply the blend mode before we applied the AA/SDF factor. That's not possible with shader code directly (no access to destination pixels). A 2-pass approach can provide the original destination pixels as an input to the shader, though.
Besides the shapes themselves, once you start using SDFs the simple approach to blend modes Impeller was using no longer works. For example, BlendMode::clear will clear pixels that aren't "covered" by the SDF unless you're also using discard. But if you use discard then no AA.
In software we used to apply the blend mode before we applied the AA/SDF factor. That's not possible with shader code directly (no access to destination pixels). A 2-pass approach can provide the original destination pixels as an input to the shader, though.
Also, DstIn could be used for Clear and be compatible with the AA/SDF factor.
It seems to show self intersecting edges. I'm not sure if this is something worth looking into.
Working through the math on it. It links to a shader toy that describes the line that computes c as dealing with the winding count, but it doesn't explain it. It includes a link on the subject that doesn't resolve for me.
The results for the shadertoy seem to indicate that it is performing even-odd winding calculations.
One thing to note about that library of SDF snippets is that they are only concerned with getting the sign of the return value correct. They don't necessarily produce a value that can be immediately used to determine an AA gradient at the edge or applying a (half) stroke width for stroked versions. More work needs to be done on them to get those values.
Having the library of functions is nice, I'm using a round rect sdf and stroked round rect sdf and that is usually 95% of what is needed. Doesn't solve the general path case though, and I don't want to use subdivision × tessellation for quality reasons
Having the library of functions is nice, I'm using a round rect sdf and stroked round rect sdf and that is usually 95% of what is needed. Doesn't solve the general path case though, and I don't want to use subdivision × tessellation for quality reasons
It's a great library if you rely on MSAA which we do for most devices, but for desktop we are investigating them for computational AA and then you need to worry about not just which side of the border you're on, but how far you are in pixel (or local) distances. The library gives you distances in whatever space you deliver the geometry in, but we have conflicting needs:
stroke widths are computed in local coordinates
the "AA gradient" (i.e. whether you are within half a pixel from the border) is computed in device coordinates
preventing stroke dropouts when the stroke width is smaller than a device pixel also needs to be evaluated in device coordinates.
One thing to note about that library of SDF snippets is that they are only concerned with getting the sign of the return value correct. They don't necessarily produce a value that can be immediately used to determine an AA gradient at the edge or applying a (half) stroke width for stroked versions. More work needs to be done on them to get those values.
At the bottom they describe use of those shaders for stroking. The only missing piece of that puzzle is making sure hairlines don't disappear or "grow beyond hairline-size" on primitives in an odd coordinate transform.
Activity
jonahwilliams commentedon Mar 30, 2026
Interestingly I'm working on a fairly similar problem. my thoughts are roughly:
Besides the shapes themselves, once you start using SDFs the simple approach to blend modes Impeller was using no longer works. For example, BlendMode::clear will clear pixels that aren't "covered" by the SDF unless you're also using discard. But if you use discard then no AA.
flar commentedon Mar 30, 2026
In software we used to apply the blend mode before we applied the AA/SDF factor. That's not possible with shader code directly (no access to destination pixels). A 2-pass approach can provide the original destination pixels as an input to the shader, though.
flar commentedon Mar 30, 2026
Also, DstIn could be used for Clear and be compatible with the AA/SDF factor.
gaaclarke commentedon Mar 30, 2026
Inigo Quilez has the math for sdf polygons in https://iquilezles.org/articles/distfunctions2d/
It seems to show self intersecting edges. I'm not sure if this is something worth looking into.
flar commentedon Mar 30, 2026
Working through the math on it. It links to a shader toy that describes the line that computes
cas dealing with the winding count, but it doesn't explain it. It includes a link on the subject that doesn't resolve for me.The results for the shadertoy seem to indicate that it is performing even-odd winding calculations.
flar commentedon Mar 30, 2026
One thing to note about that library of SDF snippets is that they are only concerned with getting the sign of the return value correct. They don't necessarily produce a value that can be immediately used to determine an AA gradient at the edge or applying a (half) stroke width for stroked versions. More work needs to be done on them to get those values.
jonahwilliams commentedon Mar 31, 2026
Having the library of functions is nice, I'm using a round rect sdf and stroked round rect sdf and that is usually 95% of what is needed. Doesn't solve the general path case though, and I don't want to use subdivision × tessellation for quality reasons
flar commentedon Mar 31, 2026
It's a great library if you rely on MSAA which we do for most devices, but for desktop we are investigating them for computational AA and then you need to worry about not just which side of the border you're on, but how far you are in pixel (or local) distances. The library gives you distances in whatever space you deliver the geometry in, but we have conflicting needs:
flar commentedon Apr 16, 2026
At the bottom they describe use of those shaders for stroking. The only missing piece of that puzzle is making sure hairlines don't disappear or "grow beyond hairline-size" on primitives in an odd coordinate transform.
fix(example): force Skia renderer on Linux desktop