How do you stop pixel-art sprites from shimmering when the camera eases?

What’s up everyone? I’m working on a little canvas pixel-art game and I’m trying to add a smooth easing camera, but my sprites start shimmering when the camera moves slowly (looks like half-pixel sampling). If I round the camera position I lose the smooth feel, and if I don’t, nearest-neighbor still looks weird.

const scale = 4;
const cam = { x: 0, y: 0 };

function draw(ctx) {
  ctx.imageSmoothingEnabled = false;
  ctx.setTransform(scale, 0, 0, scale, 0, 0);

  const cx = cam.x; // tried Math.round(cam.x)
  const cy = cam.y;

  ctx.translate(-cx, -cy);
  drawTilemap(ctx);
  drawSprites(ctx);
}

What’s the cleanest way to keep smooth camera easing while guaranteeing pixel-perfect alignment so the scene doesn’t shimmer?

Quelly

shimmering is basically your camera doing a slow-mo “subpixel slide” so the sampler keeps flipping which source pixel wins each frame.

keep the eased camera as floats, but snap only the render transform to the screen pixel grid (1/scale in world units):

const scale = 4;
const snap = v => Math.round(v * scale) / scale;

function draw(ctx) {
  ctx.imageSmoothingEnabled = false;
  ctx.setTransform(scale, 0, 0, scale, 0, 0);
  ctx.translate(-snap(cam.x), -snap(cam.y));

  drawTilemap(ctx);
  drawSprites(ctx);
}

you still get smooth easing in the camera math, but the actual draw lands on exact pixel boundaries so nearest-neighbor stops doing that “sparkle” thing.