Pixel Scaling in p5.js – Retro Look with Sharp Edges
When drawing pixel art or retro-style graphics in p5.js, images often appear blurry when scaled up. This is caused by default image interpolation applied by browsers. To preserve crisp, pixel-perfect edges, this behavior must be overridden explicitly.
Objective
- Draw a small image (e.g., 64×64 pixels).
- Display it scaled up on the main canvas.
- Ensure sharp, non-blurry edges — no smoothing.
Solution Overview
The method involves:
- Using the
WEBGL
renderer for full texture control, - Creating an off-screen
createGraphics()
buffer, - Disabling interpolation with
setInterpolation(NEAREST, NEAREST)
, - Manually flipping and translating coordinates to simulate 2D behavior in WEBGL.
Example Code
let pg;
let pixelSize = 10;
function setup() {
createCanvas(800, 800, WEBGL);
noSmooth();
canvas.imageSmoothingEnabled = false;
pg = createGraphics(64, 64, WEBGL);
pg.noSmooth();
pg.imageMode(CORNER);
pg.pixelDensity(1);
pg.ortho();
pg.push();
pg.scale(1, -1);
pg.translate(-32, -32);
pg.background(192);
pg.noFill();
pg.stroke(0);
pg.rect(0, 0, 64, 64);
pg.rect(2, 2, 60, 60);
pg.rect(4, 4, 56, 56);
pg.ellipseMode(CENTER);
pg.fill(90);
pg.ellipse(32, 32, 54, 54);
pg.pop();
imageMode(CENTER);
this._renderer.getTexture(pg).setInterpolation(NEAREST, NEAREST);
}
function draw() {
background(90);
scale(1, -1);
scale(pixelSize);
image(pg, 0, 0);
}
Key Points
- Why WEBGL? — Only in
WEBGL
mode can texture interpolation be changed toNEAREST
. - Why
ortho()
andscale(1, -1)
? — The WEBGL coordinate system flips the Y axis. These adjustments simulate typical 2D top-left-based layouts. imageMode(CORNER)
andCENTER
— Proper positioning depends on matching mode with transform logic.
Result
The output appears crisp and blocky as expected from pixel art, even when upscaled 10× or more. No anti-aliasing or smoothing occurs. This replicates the visual style of old video game systems or emulators.

Conclusion
With careful setup, p5.js supports clean, pixel-perfect rendering without the need for external tools or shaders. createGraphics()
, WEBGL
, and setInterpolation()
together offer full control for retro-style rendering and grid-based visuals.