A ramp has no flat region to find
The palette stage works by finding the small set of colours the picture actually uses and assigning each pixel the nearest one. That works well for flat artwork. It breaks down on a smooth gradient, because a gradient has no flat colour to be assigned to — it only ever has the colour it happens to be at that point. The palette's only option is to quantise it: cut the ramp into bands, one per palette entry it crosses, and label each band as if it were its own solid colour.
Left uncorrected, each of those bands becomes its own separate flat shape in the output file. One synthetic test gradient came back described as four flat layers costing fifty-eight numbers in the file, where the honest description is a single gradient costing twelve.
The merging is done carefully rather than greedily: neighbouring bands are only candidates for joining when at least one side is already recognised as part of a ramp, and the actual saving in file size is checked before any two pieces are welded. Two flat regions are never joined just because a gradient happens to sit between them — bands only exist in the first place because a real ramp was quantised, and the check for that runs before any expensive fitting is attempted.
Choosing the cheapest honest description
Once a region's boundary is settled, this stage still has to decide what to fill it with. A flat colour, a straight-line fade and a circular or elliptical fade are all tried, and the cheapest one that actually explains the pixels wins. "Cheapest" is not vague: a flat fill costs the file three numbers, a straight fade costs ten, and a circular fade costs nine (eleven if it needs to be an ellipse rather than a perfect circle) — each extra colour stop along the way costs four more. A gradient is only chosen when the error it removes, compared with the simplest flat guess, is worth more than the extra numbers it costs to write down.
Two further guards keep the search honest. A gradient is not even attempted on a region with too few pixels to tell a real fade from noise. And a candidate fade must clear a visibility floor and actually shade a real portion of the region's pixels — otherwise it is not describing shading at all, it is spending a gradient's worth of numbers explaining a single lost dot or a chamfered corner.
A ramp, or two flat colours wearing a ramp's clothes
There is a harder case than picking a fill for genuine shading: telling a real gradient apart from two flat inks the palette happened to merge into one region. Both cases leave a flat guess with a high error, so comparing a candidate gradient only against the flat fit's own error cannot separate them — an earlier version of this test that tried exactly that ended up declining gradients almost everywhere.
What actually tells the two apart is how well each alternative explains the same pixels. Measured across the regions the tracer was wrongly leaving flat, the best single straight-line ramp removed only thirteen percent of the error there, while the best possible split into two flat colours removed sixty-six percent. That gap is the signature of a step, not a ramp: shading fades continuously and a two-colour split can only approximate it badly, while two genuinely distinct inks are matched almost perfectly by two flat colours and poorly by any smooth fade in between.
A feature stuck to a gradient
The palette only sees colours, not shapes, so a two-pixel white seam through a black shape, a stray dot, or the end of a thin stroke all quantise into the ink that surrounds them, disappearing into an otherwise flat region. The fill fitter then sees a solid region with a small stubborn cluster of pixels it cannot explain as flat, and its only remaining tool is to buy a gradient to cover the difference — real cases on solid black shapes came back fitted with as many as three separate radial gradients purely to explain seams that were never shading at all.
Before fill fitting runs, this stage looks specifically for small clusters of pixels whose colour sits well outside what the region's chosen fill predicts there, excluding anything that looks like ordinary anti-aliasing rather than a genuine feature. Each surviving cluster is carved out as its own small flat region, named by its own measured colour, and the parent region is refitted without those pixels dragging its gradient search around. The threshold for "well outside" scales with the picture's own measured noise, with a floor so that genuine anti-aliasing fringes are never mistaken for a feature, and the number of features carved from a single image is capped, as a guard against a heavily textured region shattering into hundreds of tiny pieces.
Interpolation space is part of the model, not a rendering detail
A gradient can fade in one of two different ways: in the space the file's colours are actually stored in, or in the physical, light-intensity space a screen actually composites in. Both are genuinely used by real design tools, and they look visibly different for the same two end colours. Rather than assuming one, this stage fits a candidate in both spaces and lets the same cost comparison decide which one the picture's own pixels actually support — the winning choice is written into the file alongside the gradient itself, not left to the renderer's default.
This also matters for elliptical fades specifically: in a large corpus of tested icons, most of the radial gradients found were not circles but ellipses, tilted at an angle. Fitting a plain circle to one of those is visibly wrong in a way no colour tolerance can paper over, so an elliptical radial model — with its own angle and aspect ratio — is tried alongside the circular one whenever a region calls for it.
Why this stage costs the most time in the tracer
Searching for the best gradient — trying candidate axes, candidate centres, candidate interpolation spaces, and scoring each against the actual pixels — is the single most expensive part of the whole pipeline. On one particularly demanding image, disabling every other optional stage still left a trace taking 10.9 seconds; capping how many colours feed the search — which is what feeds the per-region gradient search — brought that down to 6.3 seconds. Skipping gradient fitting altogether and filling every region flat is offered as a genuine fast path for exactly this reason — not a cosmetic shortcut, but a real way to trade fidelity on shaded artwork for speed when speed is what matters.