Fill Rasterization and Anti-Aliasing
I'm not sure why I do these sorts of things to myself, but I decided to go ahead with building my own software-based alpha mask rasterization library in C++. 😅
What I'm building has no external dependencies, and is fairly minimalist, but still covers a large number of use-cases that solo indie game developers would typically need for their project:
- Fill rasterization for polygons, including those with holes or self-intersections.
- Stroke rasterization for polylines.
- Anti-aliasing using coverage-based analysis or supersampling.
- Pixel erosion (deflation and inflation).
- Shadows.
The general idea behind the library I'm building is that you decide on as many polygon and polyline shapes that you're going to need as possible up-front, and bake them into textures. Then your game loop can just blit them as needed.
There are several libraries out there that indie game developers will probably want to check out, before thinking about rolling their own:
- Blend2D - a high-performance 2D vector graphics engine, released under the zlib license. As of January 2026, they're looking for funding in order to continue maintaining the project.
- Skia - an open-source 2D graphics library, used by Google Chrome, and released under a BSD license. This is actively maintained and backed by Google, robust and industrial-grade, but also larger and more complex to integrate into smaller projects.
- Anti-Grain Geometry - an open-source graphics library, no longer actively maintained, and released under a specialized permissive license.
Latest C++ Milestone - Fill Rasterization of Alpha Masks and Anti-Aliasing

What you're seeing above is a comparison of the four different anti-aliasing approaches that my fill rasterization algorithm supports. No anti-aliasing is on the left, then coverage-based, then supersampling at a 2x2 scale, and finally supersampling at a 4x4 scale.
You can see the slight jagged edges on the alpha mask on the left, and how well each anti-aliasing approach does at fixing the jagged edges. A coverage-based approach is more complex, but is faster and requires significantly less memory. Supersampling is brute-force, and will potentially cause brief spikes in memory-usage, but for small textures it can be worth it.
Why Alpha Masks?
If you're wondering why my screenshot is showing jigsaw pieces as a filled white blob, that's an alpha mask. The idea is to process the polygon shape into an alpha-only texture first, and then blend it with the photo afterwards. You can think of the alpha mask as a reusable texture asset:
- It uses less memory than a full-color texture.
- It's easier and more performant to build in software.
- It can be blended with textures or colors in a variety of ways.
Every major multimedia library that an indie game developer might use - including SDL, SFML, and Raylib - provides functions to render textures using alpha blending. They each allow an alpha mask texture to be composited with color textures at draw time.
Fill Rasterization of Polygons into Alpha Masks
The overall algorithm I've built for fill rasterization performs the following steps:
- Build a co-ordinate system for a given polygon: width, height, and an affine matrix tranformation.
- Build a raster scanline span table for the polygon, using either a non-zero winding or even-odd fill rule. You can think of a raster span table as an intermediate representation of a 2D boolean alpha mask. It's basically just a run-length encoded bitmap image. To generate it, you run along each horizontal Y position in the bitmap (each scanline), and jump forward to each edge that intersects the polygon along that Y position.
- Apply raster scanline span tables to an alpha mask.
- If the alpha mask was supersampled, downsample it using a box filter.
Lots More To Do!
I still have to tackle pixel erosion and shadow effects for the fill rasterizer. Then I'll be moving along to stroke rasterization.
I don't know if it was the right choice to roll my own software rasterization library. 😅 But I do know that it's going to feel really good when I can confidently draw my puzzle pieces, with a variety of effects like shadows and edge highlighting. And I'll have built myself a library that should be useful for other projects in the future to boot... 🤩
If things go well, I'm considering whether I might want to organize what I'm building into an open-source 2D indie game library, with adapters for SDL, SFML, and Raylib. That's peeking quite a ways into the future, but it's the eventual dream... 🤞