WindFoil – algorithm for computing winding and anti-aliasing of 2D vector shapes Developer Matt DesLauriers released WindFoil, an algorithm for filling 2D vector shapes with per-pixel winding and analytic anti-aliasing in a fragment shader, designed to improve on the Slug Algorithm for high-resolution print artwork. The core was designed by Code Claude on Fable in a ~1.5-hour session, with further tuning, and the repo includes benchmarks showing comparable performance to Slug while reducing the bands buffer from ~1.54 MB to ~0.84 MB in the tiger test SVG. Code and demos for windfoil , a method for filling 2D vector shapes built from quadratic-Bézier contours, by computing winding and analytic anti-aliasing per-pixel in a fragment shader. The algorithm was designed to improve upon the public Slug Algorithm https://terathon.com/blog/decade-slug.html for certain uses cases. 🚩 This builds on prior work Slug, Vello, Pathfinder, font-rs and others , and may or may not be a novel algorithm. The core of the algorithm was designed by Code Claude on Fable after a ~1.5 hour uninterrupted session within a larger codebase I am working on, although it required several more hours and design/code iterations to tune performance and bugs see How This Came About . It's entirely possible this algorithm collides with an existing technique in its memory, or perhaps even a patent. After searching, I haven't been able to find any other algorithms or code that approaches vector rendering in the same way, but more research would be needed to be sure, so use this at your own risk. You can see a demo of this here: https://texel-org.github.io/windfoil/ https://texel-org.github.io/windfoil/ Requires Deno https://deno.com/ 2.x on a machine with a WebGPU-capable GPU. renders a PNG in output/ deno task render compare against point-sampled box filter, Skia, and Slug synthetic shapes + glyphs a–z deno task validate serve the demo, then open http://localhost:8080/ or http://localhost:8080/tools/validate/ to run the validation suite against the browser's own canvas2d rasterizer deno task serve Note: this repo refers to "Skia" but is actually using @napi-rs/canvas https://www.npmjs.com/package/@napi-rs/canvas as a reference, which uses Skia under the hood. This README was written by me, but most of the code and other documentation in the repo was produced by agents at my direction. — the algorithm docs/ALGORITHM.md — some additional properties of the algorithm I've found interesting for my own uses docs/NOTES.md — the shader: the winding-integral box filter + the row-band gather src/windfoil.wgsl — the row-band acceleration structure src/bands.js — glyph outlines + metrics from the bundled font using opentype.js src/font.js — a windfoil-vs-Slug WebGPU benchmarks and acceleration notes bench/ To provide a little context, I have been working for some weeks now on a 2D vector engine that uses the Slug Algorithm https://terathon.com/blog/decade-slug.html which is great, but primarily developed for text and icons . My goal has been "perfectly" anti-aliased vector graphics at all resolutions for high quality print artwork e.g. 30k x 30k 16-bit PNG files , while supporting a range of complex paths, strokes, and per-pixel effects for generative art. You can see two demos of the engine here https://x.com/mattdesl/status/2070470499772080512 and here https://x.com/mattdesl/status/2071199412785684630 , alongside some other posts I've made on X/Twitter about it. I tasked Fable with solving some problems I was encountering, and it was able to work within the large codebase I had been developing I had a number of profilers, fuzzers and harnesses already in place across Rust/WASM, JS, Figma's renderer, and Skia via @napi-rs/canvas . Some notes & findings: - Slug uses a dual-ray approach, splitting shapes into horizontal and vertical bands each pixel walks two bands , and in some complex scenes I was finding performance bottlenecks in shader reads and storage. The single-ray winding integral approach brought the bands buffer from ~1.54 MB to ~0.84 MB in the tiger test SVG https://commons.wikimedia.org/wiki/File:Ghostscript Tiger.svg . The new algorithm performed similarly or faster in many views and scenes I tested.- This repo now includes benchmarks against Eric's reference implementation of Slug https://github.com/EricLengyel/Slug , see. Windfoil performs comparably, sometimes slower, sometimes faster, depending on the scene and view. ./bench/README.md - This repo now includes benchmarks against Eric's - Broadly, Slug's AA assumes ~one edge per pixel, so self overlapping strokes would sometimes render with degraded AA. To correct this, I had a CPU prepass sweep-union to ensure each fragment received a single edge. Since windfoil's integral handles overlap for free, I was able to remove most of the CPU processing and just operate on the curves directly. This was a huge performance win for some generative art scenes with hundreds of thousands of complex and overlapping strokes, and also meant that more of my shapes became naturally scale invariant as the CPU preprocessing was flattening curves at a device scale . - Both Slug and Skia's anti-aliasing could be described as approximations of the box filter, but windfoil computes it nearly exactly in all cases I tested and care about. The algorithm beats Slug and Skia by this metric. And, tested across a ~1000 shape corpus, it matched Skia more closely than Slug: Δ 0.164/255 for windfoil vs 0.189 for Slug, and every outlier improved. It tied Slug only on the pathological pixels containing three-plus overlapping winding levels, which as far as I understand no single-sample approach can handle. - I was struggling to compute a per-cell "backdrop" across shapes with Slug's dual-ray approach, to further optimise complex scenes. This algorithm makes the implementation much simpler: everything outside a cell reduces to a single winding integer I can precompute the "backdrop" . - This algorithm also opens some other interesting new avenues for my renderer that were not easy with Slug, such as plugging in new AA kernels e.g. tent, Mitchell–Netravali and computing curve normals, see docs/NOTES.md I've left much of the LLM-generated documents and code alone in this repo, although it has gone through many rounds of iterations the first draft of the algorithm had various bugs and issues . If this is truly a novel approach, which I am still not entirely sure of, it does present to me an interesting example of AI interpolating and recombining existing ideas to form something new, and as such it seems fitting to let the AI mostly speak for itself in some of the code & documents em dashes and all . The original name that Fable gave the algorithm was "Area Algorithm," which felt a little dull. I've gone with windfoil , a sport I've never done but would like to try one day. I also like the tie-in with the winding computation, and the light and airy properties the term evokes in my mind. See the ./bench /texel-org/windfoil/blob/main/bench folder for full results, but at a glance: Slug is often faster when rendering minified shapes i.e. zooming out, drawing small things , and windfoil tends to be marginally faster when shapes take up more of the viewport i.e. zoomed in . font-rs https://github.com/raphlinus/font-rs — Raph Levien's signed-area scanline rasterizer writeup https://medium.com/@raphlinus/inside-the-fastest-font-renderer-in-the-world-75ae5270c445 Pathfinder https://github.com/servo/pathfinder — Patrick Walton's GPU vector/font rasterizer Vello https://github.com/linebender/vello — GPU compute-centric 2D renderer Linebender Slug https://sluglibrary.com/ — Eric Lengyel's dual-ray analytic per-pixel coverage JCGT 2017 Analytic Rasterization of Curves with Polynomial Filters https://josiahmanson.com/research/scanline rasterization/ — Manson & Schaefer Eurographics 2013 , exact prefiltered curve coverage under polynomial filters Easy Scalable Text Rendering on the GPU https://medium.com/@evanwallace/easy-scalable-text-rendering-on-the-gpu-c3f4d782c5ac — Evan Wallace's atlas-free outline gather GPU text rendering with vector textures https://wdobbie.com/post/gpu-text-rendering-with-vector-textures/ — Will Dobbie 2016 Random-Access Vector Graphics https://hhoppe.com/proj/ravg/ — Nehab & Hoppe, per-cell curve lattice 2008 Valve SDF https://steamcdn-a.akamaihd.net/apps/valve/2007/SIGGRAPH2007 AlphaTestedMagnification.pdf — Chris Green, distance-field text 2007 msdfgen https://github.com/Chlumsky/msdfgen — Viktor Chlumský, multi-channel SDF atlases If you reference this work, you can cite it as: Matt DesLauriers. Windfoil: per-pixel winding and analytic anti-aliasing for 2D vector shapes.2026. https://github.com/texel-org/windfoil @misc{deslauriers2026windfoil, author = {DesLauriers, Matt}, title = {Windfoil: per-pixel winding and analytic anti-aliasing for 2D vector shapes}, year = {2026}, howpublished = {\url{https://github.com/texel-org/windfoil}} } Apache-2.0 — see LICENSE /texel-org/windfoil/blob/main/LICENSE . This repository bundles the Lato font SIL OFL 1.1 , see . /texel-org/windfoil/blob/main/assets/OFL.txt assets/OFL.txt