SplatRs: The Capacity Wall Was a Pacing Problem

Last post ended with an honest 5.33 dB gap to splatfacto and a refrain we’d measured four separate times: give the model more gaussians, and it gets worse. Cap raised to 400k? Worse. Again on a better champion? Worse. Every capacity arm we ran — 16.29, 16.71, 17.49, 17.01 — lost to a ~117k baseline.

Two days later the champion is 18.68 dB at 250k gaussians, the best structural similarity we’ve ever scored (SSIM 0.635), and the gap to splatfacto is 3.53 dB — down from 6.45 three weeks ago and 4.43 at the start of day one. The capacity experiments weren’t wrong. Our reading of them was.

Day 1 — the flag arm runs dry, so read the other side’s source

Two long-pinned hypotheses died fast. The reference alpha-discard threshold (1/255 vs our 1e-4) ported cleanly across all three rasterizers — and did nothing for quality. The full-resolution revisit delivered worse news: split-PDF sampling, our single biggest half-res win at +0.90 dB, inverts at full-res (12.50 dB, worse than plain L2). That front went back on the shelf.

With the obvious flags exhausted, the campaign changed mode: stop guessing what splatfacto does and diff our densification stack line-by-line against gsplat’s DefaultStrategy and splatfacto’s resolved configuration, fetched from source. Four concrete discrepancies came back, ranked by suspected impact.

The first win was a constant we wrote ourselves

Day-0 baseline render at 17.78 dB: the locomotive is sharp but the sky is muddy and the background hazy

Our world-space oversize prune had been hardcoded 5× stricter than splatfacto’s since the day it landed. Concretely: we were repeatedly churning the big, soft “anchor” gaussians that hold together sky and background — the exact regions our renders have always struggled with — while the reference implementation keeps them.

One flag to parity: +0.59 dB (17.78 → 18.37), and the sky visibly repaired, exactly where the forensics predicted. Second-biggest single lever of the entire campaign. Default flipped.

The same view after oversize-prune parity, 18.37 dB: the sky cleans up and the background solidifies

Day 2 — the pattern in the refutations pointed at our own gap

The remaining ports went to verdicts: refinement-pause-after-reset refuted, gsplat’s visibility denominator a metric tie (but the largest SSIM gain of any arm), screen-size split/prune machinery refuted. Individually unimpressive — but every mechanism that reshuffled which gaussians get densified moved the metrics. That pattern pointed somewhere gsplat can’t have a bug: they run uncapped, so their gradient threshold simply is their selection. We run a binding 150k cap — and our budget was handed out first-come-by-index. Not by need. By array position.

Ranking densification candidates by gradient instead: +0.34 dB (18.71), a new PSNR peak.

Budget-priority render at 18.71 dB: strongest structure yet on the locomotive

Night 2 — the wall breaks

Here’s where the four “more gaussians hurt” verdicts got re-read. All four arms had slammed into their cap by iteration 3,000 and spent the rest of the run saturated — while splatfacto grows to ~300k organically across its whole densification window. The experiments had never tested “a big population.” They’d tested “a population forced to grow up instantly.” Those are different claims.

A per-event growth throttle — each densify event adds only ~3–4% of the current population — replicated the organic curve. Result: 18.68 dB at 249.9k gaussians, SSIM 0.635 (best ever), texture recovered. A 250k population now matches the best 115k population, where every unpaced attempt at that scale had lost a full decibel. Population scaling was never about capacity or allocation. It was about pacing.

Champion render: pacing at 250k gaussians, 18.68 dB with the best SSIM ever recorded in the campaign

The efficiency footnote is almost as good: pacing at 3% starved itself down to 84k gaussians and still scored 18.03 — beating the day-0 champion with 28% fewer gaussians.

Ground-truth photo of locomotive 713, the held-out test view none of these models ever saw

Scoreboard — every arm, both days

arm (single delta unless noted)PSNRgaussiansverdict
day-0 champion: split-PDF sampling17.78117.0kbaseline
alpha-discard 1/25517.54116.4krefuted
full-res revisit (L2 + split-PDF)12.50387krefuted — split-PDF inverts at full-res
oversize-prune 0.5 (parity)18.37115.4kWIN +0.59 — default flipped
pause-refine-after-reset17.82~114krefuted
visibility denominator (gsplat semantics)18.37118.2ktie — largest SSIM gain of any arm
max_radii2D screen-size machinery18.15119.2krefuted
cap 400k revisit #317.49298.6krefuted — but first cap arm whose settle rose
budget priority (top-K by gradient)18.71115.6kWIN +0.34 (LPIPS caveat)
priority + cap 400k17.01292krefuted — allocation thesis closed
growth pacing 3%18.0384kstarved, not wrong — record efficiency
growth pacing 4%18.68249.9kCHAMPION — capacity wall broken

Ten 30k-iteration runs in two days on an M2 Max (~2h each, Metal, our wgpu tiled rasterizer), every arm a fresh single-delta run against a same-binary control on the identical seed and protocol. Verdicts required PSNR + SSIM + LPIPS + an actual look at the render, and every refutation is ledgered so nothing gets re-run.

Why this worked

  1. Read the reference, don’t guess it. Both breakthroughs trace to diffing our code against gsplat/splatfacto source, not paper descriptions — one was a 5×-too-strict constant, the other a mechanism they never needed to write.
  2. Refutations are data. The pacing discovery came directly from the shape of four failed capacity arms; the priority discovery from the pattern across four adjudicated ports. A dead end that dies cleanly tells you where the wall isn’t.
  3. Single-delta discipline. One flag per arm, seeded controls, full metric panels, a written ledger. It’s the same boring recipe as every other week — it’s just that this week it paid out twice.

Where that leaves us

3.53 dB to splatfacto, and the next moves write themselves: the capacity ladder continues (paced 300k+), pacing combines with the denominator’s SSIM gain, and full-res gets its best reopening thesis yet — it died by saturating its cap at iteration 3,000 with 4× thinner per-pixel gradients, which is exactly the pathology pacing removes.