cover logo: keep the source's anti-aliasing, then trace it lightly

The wordmark segmentation mapped alpha with smoothstep(46, 120) over distance
from the background colour. That ceiling is fixed, but the ink distance is not:
white text on a black band sits at ~438, so every edge pixel brighter than about
27% grey saturated to fully opaque. A hard threshold wearing a smoothstep's
clothing. Measured on Camping in Alaska's "Needlemouth" cover, the extracted
mask's edges transitioned over 0.10px against the source's 0.88px -- nine times
harder than the artwork it came from.

The ramp's top now tracks the measured ink distance (95th percentile of
distance-from-background, so it reads the glyph body rather than the brightest
speck), with the old constant kept as a floor so low-contrast marks are
untouched. Retained anti-aliasing on that cover goes from 10.4% of inked pixels
to 22.2%, and the glyphs thin back toward the source instead of being dilated by
the saturation.

That unlocks the trace side, which is the visible half. The blur there was never
a goal -- it exists to synthesise anti-aliasing a mask lacks, and it melts serif
terminals into blobs. With real gradients in the alpha, the cover-logo branch
drops from ~0.93px of blur to a 0.5px floor and from eps 0.5 to 0.2, at a 2400px
raster instead of 1400. Lowering eps ALONE was tried and rejected: against the
old near-binary mask it just captured the pixel staircase in finer detail.

Camping in Alaska's traced path goes 900 -> ~2500 vertices with no staircasing,
and the serif terminals keep their shape. Cost is 35ms -> 65ms of main-thread
work, once per cover-derived logo at page load, not per frame.
This commit is contained in:
KeelrLeek committed 2026-07-25 18:12:46 -05:00
1 parent e536e96180
commit 21ef73770c
2 files changed
+68 -16

No files matched your search

+32 -14
View File
@@ -776,6 +776,13 @@
const LOGO_TRACE_EDGE = 2400; // supersample target long edge for hard sources
const LOGO_TRACE_MAX_SCALE = 4;
const LOGO_TRACE_BLUR = 1.0; // blur px per unit of supersample scale
// Cover-derived marks trace at a larger raster with far less blur than they
// used to: their alpha now carries the source's real anti-aliasing (see
// cover_logo.rs ALPHA_INK_SPAN), so detail survives instead of needing to be
// smoothed away. Measured on Camping in Alaska: 900 → ~2200 path vertices
// with no staircasing, and serif terminals that keep their shape.
const LOGO_COVER_TRACE_EDGE = 2400;
const LOGO_COVER_TRACE_BLUR = 0.5; // floor; scales up only for tiny sources
const LOGO_MONO_MIN = 0.55; // dominant-colour share to accept for tinting
// A logo can trade this much cleanliness for a wider, more title-like shape.
// It must still pass LOGO_MONO_MIN; this only ranks already-good candidates.
@@ -1562,21 +1569,32 @@
// near the top quality score, then prefer the widest result.
let source, eps, minArea;
if (usingCoverLogo) {
// Cover-derived wordmark (recipe D): the Rust side already
// despeckled the alpha; upscale to a fixed 1400px width and
// blur so the low-res letterforms trace as smooth curves
// rather than a staircase, then simplify at eps 0.5.
// Cover-derived wordmark (recipe D). The blur here is
// COMPENSATION, not a goal: it exists to synthesise the
// anti-aliasing a mask lacks, and it costs serif detail —
// terminals melt into blobs at ~1px of blur.
//
// The blur MUST scale with the enlargement: a fixed 1px did
// almost nothing on a 29px-tall source (a ~7x upscale to
// 1400px), so its pixel-steps survived into the trace as
// aliasing. ~0.6px of blur per unit of scale synthesises the
// anti-aliasing the tracer needs — hi-res marks (scale≈1) stay
// crisp, tiny marks get proportionally more smoothing.
const scale = 1400 / candidate.img.naturalWidth;
source = rgba(candidate.img, 1400, Math.max(1, scale * 0.6));
eps = 0.5;
minArea = 24;
// The Rust segmentation now scales its alpha ramp to the
// measured ink distance (see cover_logo.rs ALPHA_INK_SPAN),
// so the mask arrives with the source's REAL anti-aliasing
// instead of a near-binary edge. That is what makes a lighter
// touch safe: less blur and a tighter simplify tolerance now
// resolve genuine sub-pixel curvature, where before they only
// captured the pixel staircase in finer detail.
//
// A tiny mark still needs proportionally more smoothing, so
// the blur keeps scaling with the enlargement — just from a
// much lower base.
const scale = LOGO_COVER_TRACE_EDGE / candidate.img.naturalWidth;
source = rgba(
candidate.img,
LOGO_COVER_TRACE_EDGE,
Math.max(LOGO_COVER_TRACE_BLUR, scale * 0.3),
);
eps = 0.2;
// Speck floor scales with the raster, or a 2400px trace keeps
// dust the 1400px one dropped.
minArea = 24 * (LOGO_COVER_TRACE_EDGE / 1400) ** 2;
} else if (aaFraction(rgba(candidate.img)) < LOGO_AA_MIN) {
// Hard-edged 1-bit source: supersample and blur to synthesise
// anti-aliasing, so the tracer resolves smooth sub-pixel