Resolution & DPR
createSilkApp maps the canvas 1:1 to device pixels, even at fractional DPRs, follows DPR changes and renders filters at screen resolution.
Updated pixi-silk 1.0.1View as Markdown
createSilkApp gives you a canvas whose pixels are the screen’s pixels. Exact edges need that as
much as they need the shader: if the browser rescales the canvas, every edge goes soft.
Create a sharp canvas#
import { createSilkApp } from 'pixi-silk';
const silk = await createSilkApp({
parent: document.getElementById('stage')!,
background: 0x000000,
maxResolution: 3,
});
silk.app; // the Pixi Application
silk.width; // CSS pixels
silk.resolution; // device pixels per CSS pixel
silk.setResolution(1); // compare at 1x, null returns to devicePixelRatio
silk.destroy();
The canvas fills parent, so the parent needs a size. Every other option is a Pixi
ApplicationOptions field and passes through.
| Option | Default | What it does |
|---|---|---|
parent | required | Element the canvas fills |
maxResolution | 3 | Upper bound for the resolution, to cap memory and fill rate |
fixedResolution | none | Forces a resolution instead of following devicePixelRatio |
onResize | none | Called after every size or resolution change, with the size in CSS pixels |
inheritFilterResolution | true | New Pixi filters render at the renderer resolution |
touchAction | 'pan-y pinch-zoom' | CSS touch-action of the canvas |
preference | 'webgl' | Renderer Pixi tries first. See renderers |
What it sets up#
The backing store is sized from devicePixelContentBoxSize, so one canvas pixel is one device
pixel, even at a DPR of 1.5 or 2.625. Rounding cssWidth * dpr yourself can be off by one pixel.
The browser then resamples the whole canvas and blurs it. Safari has no device pixel box, so there
the size is rounded.
The canvas follows DPR changes, such as browser zoom or a move to another display.
MSAA is off (antialias: false), because the shader already computes coverage. Pixel rounding is
off too (roundPixels: false), so slow motion moves by fractions of a pixel instead of snapping.
Pixi filters render at resolution 1 by default, which blurs everything behind a filter on a retina
screen. createSilkApp sets Filter.defaultOptions.resolution to 'inherit'. Turn that off with
inheritFilterResolution: false.
Pixi sets touch-action: none on its canvas, which stops the page from scrolling on phones. The
default here lets the page scroll. Use touchAction: 'none' for a canvas that handles drags
itself.
Your own Application#
If you create the application yourself, use the same settings:
await app.init({
preference: 'webgl',
antialias: false,
autoDensity: true,
resolution: window.devicePixelRatio,
roundPixels: false,
});
Filter.defaultOptions.resolution = 'inherit';
This does not size the backing store to exact device pixels or follow DPR changes. For that, use
createSilkApp or copy its ResizeObserver code.
Render textures and filters#
A SilkGraphics in a render texture or behind a filter is anti-aliased at that target’s
resolution. Give render textures the renderer’s resolution to keep them sharp on retina screens.
The render texture experiment shows the difference.
API reference: createSilkApp, SilkAppOptions, SilkApp
Experiments on this page
Full-screen scenes. Each one also opens in Studio with its source.