⚡ Zig Guide LiveUnofficialbut fully verified
✓ Zig 0.17.0-dev.1503+1f1bee62eOn an older Zig?

Graphics

A renderer built out of an array of bytes, with no graphics library underneath. Start with a framebuffer, draw lines and circles, rasterize triangles with barycentric coordinates, composite with alpha, and kill the staircase with supersampling. Then read the buffer back: brightness and contrast as lookup tables, blur and Sobel edges as convolution kernels, grayscale and sepia as colour matrices, auto-levels from a histogram, median filters for noise, and the half-pixel bug that shifts a resized image. Everything before the last chapter runs in your browser.

  1. A framebuffer is an array of bytes. Every chapter here is arithmetic on that array, with no library underneath.
  2. Rasterizing decides which pixels a shape covers. Antialiasing decides how much of each, which is why it costs more.
  3. Blur, sharpen and edge detection are one operation with different numbers in the kernel.
  4. Resampling shifts the image half a pixel unless you sample pixel centres. It looks like a rounding bug and it is not.

14 chapters.

  • A Framebuffer Is an ArrayRow-major layout, top-left origin, packed pixels, and a clipping putPixel.
  • Writing an Image FilePPM, the image format you can write without a library, and the one rule that will bite you.
  • LinesBresenham's algorithm: one add and one compare per pixel, integers only.
  • CirclesCompare squared distances, loop over the bounding box, and let putPixel clip.
  • Alpha BlendingSource-over compositing in integers, why the /255 matters, and why order still does.
  • Rasterizing TrianglesEdge functions decide inside from outside, and the same three numbers interpolate across the face.
  • AntialiasingCoverage is alpha. Sample the inside test sixteen times per pixel and the staircase goes away.
  • Per-Pixel TransformsBrightness, contrast, threshold and invert are all one table lookup, and the add that does brightness is where Zig has an opinion.
  • ConvolutionBlur, sharpen and Sobel are one loop with different numbers in it. The two bugs are always the border and the buffer.
  • Colour MatricesGrayscale, sepia and saturation are one 3x3 matrix, and a chain of them multiplies into a single matrix before the image is touched.
  • Histograms and LevelsCount what the image contains, and the lookup table that fixes it falls out of the counts. Auto-levels, equalization, and why you apply them to luma.
  • Median and Rank FiltersA convolution cannot ignore a value. Sorting the neighbourhood gives one function that is a denoiser, an eroder and a dilator depending on the index.
  • Scaling and ResamplingNearest, bilinear and box filtering, the half-pixel bug that shifts your whole image, and why downscaling without a filter turns detail into a solid bar.
  • Onto the ScreenThe same buffer, handed to X11 through translate-c, and what changes on Wayland.