Getting started
Introduction
pixi-silk is a Graphics-like object for PixiJS v8. It draws shapes as exact signed distance fields, so edges stay smooth and anti-aliased at any zoom and DPR.
Updated pixi-silk 0.1.0
pixi-silk adds SilkGraphics, a PixiJS v8 display object with an API close to Pixi’s Graphics.
It does not turn shapes into triangles. The GPU evaluates each shape’s exact distance function at
every pixel and derives coverage from it. The anti-aliasing is exact at every scale, without MSAA
or extra render passes.
Live demo
Source src/demos/versus.demo.ts
import { Container, Graphics, Text } from 'pixi.js';
import { SilkGraphics } from 'pixi-silk';
import { defineDemo } from './runtime';
// Left: Pixi v8 Graphics (tessellated, no MSAA). Right: SilkGraphics (distance fields).
export default defineDemo({
size: [480, 240],
controls: {
zoom: { type: 'range', label: 'zoom', min: 1, max: 6, step: 0.01, value: 1 },
spin: { type: 'toggle', label: 'rotate', value: true },
},
setup({ stage, params, tick }) {
const sides = [new Container(), new Container()];
const pixi = new Graphics();
const silk = new SilkGraphics();
sides[0].addChild(pixi);
sides[1].addChild(silk);
sides.forEach((side, i) => {
const mask = new Graphics().rect(i * 240, 0, 240, 240).fill(0xffffff);
const label = new Text({
text: i ? 'SilkGraphics' : 'Graphics',
style: { fill: 0x8e8e93, fontSize: 12, fontFamily: 'system-ui' },
});
label.position.set(i * 240 + 12, 10);
side.mask = mask;
stage.addChild(side, mask, label);
});
let angle = 0;
tick((_t, dt) => {
if (params.spin) angle += dt * 0.15;
for (const [i, side] of sides.entries()) {
side.pivot.set(120, 130);
side.position.set(i * 240 + 120, 130);
side.scale.set(params.zoom);
side.rotation = angle;
}
for (const g of [pixi, silk]) {
g.clear();
g.circle(120, 130, 62).stroke({ width: 3, color: 0x64d2ff });
g.roundRect(70, 90, 100, 80, 24).stroke({ width: 1, color: 0xffffff });
g.circle(120, 130, 18).fill(0xff375f);
for (let k = 0; k < 6; k++)
g.moveTo(40, 60 + k * 3)
.lineTo(200, 64 + k * 5)
.stroke({ width: 0.6, color: 0xffd60a });
}
});
},
});Why v8 graphics stopped looking smooth#
PixiJS v8 builds Graphics geometry once, as triangles, when you draw. That is fast, but it has
limits:
- Curves are tessellated. Scale a circle up and its facets show. A thin line crawls between pixel rows as it moves.
- Anti-aliasing is MSAA or nothing.
antialias: truegives four samples per pixel on the main canvas. Filters and render textures stay aliased unless you opt each one into MSAA. - Filters render at resolution 1, so anything behind a filter is blurry on retina screens.
- Gradients are 8-bit, so wide, dark gradients show bands.
What Silk does instead#
Pixi Graphics | SilkGraphics | |
|---|---|---|
| Edges | tessellated triangles, optional MSAA | exact distance per pixel, 1-device-pixel filter |
| Zoom | facets appear | exact at any scale |
| Thin lines | break up below 1 px | keep 1 px and fade (energy conserving) |
| Inside filters and render textures | aliased unless each target opts into MSAA | same quality everywhere |
| Gradients | sRGB, 8-bit | OKLab, half-float ramps, dithered |
| Draw calls | batched geometry | one instanced draw call per object |
Key facts#
- One
SilkGraphicsis one draw call, whatever it contains. Each primitive is one quad instance. Rebuilding 50,000 primitives every frame costs about 12 ms of CPU. - Shapes: rects and squircles (per-corner radii, continuous curvature), circles, ellipses, arcs, sectors, lines, polylines (smoothed, tapered), paths, areas between two series, hearts, stars, regular polygons and rounded triangles.
- Paint: solid colours, gradients (linear, radial, conic and along-the-path), analytic gaussian blur for glows and soft shadows, and shader-side dashes.
createSilkAppcreates a PixiApplicationwhose canvas maps 1:1 to device pixels, even at fractional ratios like 1.5 or 2.625. It follows DPR changes.- pixi-silk is written in TypeScript, renders with WebGL2 and is MIT licensed.
pixi.js^8 is a peer dependency.
Where to next#
- Install it, then follow the quick start.
- Coming from
Graphics? Read Migrating from Graphics. - Curious how the shader works? See How it works.
- Want to see everything at once? Browse the Lab and the Showcase.
API reference: SilkGraphics, createSilkApp