Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

One-shot (trace)

✅ verified · segment -> trace, with the criteria in the same step · needs only ComfyUI’s SAM, in the segment step · the one and only step of the one-shot route · code: appendix B

in one line

Solve the vector edges and the value bands out of the source, use strokes only for the difference, and paint it in one go. No draft, no gate, no completion, no lines; vectors own the edges and strokes own the interiors. It answers the question “can a diffusion image become a 4K painting where every pixel has a provenance” – it can, and it looks right; it does not answer “can an artist take it over”.

The two steps and what each produces

input/origin.png ─► segment   (ch. 1)  ASSIGN cuts out the sub-parts; the SAM majority vote is unused
              ─► trace     reading the picture (plain python, independent of the scale):
                             KMeans cuts each sub-part into 2-5 bands by colour (below), one
                               sub-pixel alpha ring per band (ch. 1)
                             stacked bottom to top into a 1x "bands only" picture (preview_cel.png);
                               the joint label (sub-part, band) is a cell
                             strokes are planned from that picture, covering only its difference
                               from the source: the background - two airbrush passes per cell to
                               soften the steps - Hertzmann's greedy detail strokes, capped at
                               max_aspect - optionally hatching on HATCH_GROUPS' sub-parts and
                               strands on STRAND_GROUPS, both off by default
                             -> plan.json + strokes.jsonl (1x coordinates) + preview.png (1x sim)
                           painting (headless Krita): build the tree -> paintPath / paintLine stroke
                             by stroke -> final.kra / final.png / layers.json / review/
                           the criteria (ch. 7) -> gauge.json + the README's table
              (the criteria run at the end of trace's main.py; a separate gauge step whose PAINT
               points at it works too) the node rule fails by design

Value bands

This route has no “local colour plus painting”: each sub-part is cut by colour into 2 to 5 bands with k-means (read/tiers.levels, with k chosen by pick_k; the band with the largest area is the Flat, not the brightest – a white part’s own colour is the brightest, so “the brightest is the Light” is wrong on a white part), one vector shape per band and one group per band. The edges are analytic and the interiors hard, which is why the one-shot route’s interior sharpness is high (ch. 7); the cost is that the bands are named by luminance and the layers are not what a person wants.

What the layer tree looks like

01_BG/   BG_Base (filled black, three numbers)   BG_Glow (the background's strokes)
04_Color/
  Subject_Silhouette                     the vector silhouette, at the bottom of the group
  <sub-part>/                            inheritAlpha -> the silhouette; in ORDER, bottom to top
    <sub-part>_<band>/                   one group per band, clipped to the alpha accumulated below
      Shape                              vector: this band's outline, filled with this band's
                                         colour -- this is what owns the edge
      Soft                               paint layer, clip -> Shape: airbrush softening the steps
      Marks                              paint layer, clip -> Shape: hatching / detail / strands
06_Line/  Line (empty: this route draws no lines)
09_Post/  Post_Grade

A stroke has to be clipped to the band’s shape rather than the sub-part’s outline: clipped only to the part, one stroke can run across an eye and the skin and wipe out the band structure the vector layers had just built (the gradient p99 falls to a fraction of what the vector stage had, and the eye becomes a round blob). The cost is several hundred nodes: sub-parts x bands x 4, plus one per sub-part, plus 10 of skeleton. The bands are named by luminance as Flat / Shadow1… / Light1…, and no layer is called “eye” – the two darkest bands are usually the two eyes, while the mouth, the shadow behind an ear and the cheeks are mixed into the middle one. The difference from ch. 5’s tree: here it is one group per sub-part with one subgroup per value band; there it is one group per semantic group, holding named layers.

Knobs

parameterdefaultmeaning
scalethe project’s multiplier (4)8 is more than twice as slow and more than twice the memory
expand smooth eps0.6 / 0.8 / 0.30each band shape’s expansion, sigma and RDP tolerance
detail_t34the detail brush’s threshold; larger means fewer strokes
max_aspect3the longest a detail stroke may be, in multiples of its own width; None lets it grow to 14 radii
strands hatchfalsehair strands on the parts table’s strand groups, hatching on its hatch groups (appendix G)
jobtruefalse reads the picture only, producing the plan and the 1x simulation

No long thin marks by default. Three passes drew them: the hair strands, the skin hatching, and the tail of the detail brush, whose strokes grow along the flow field for up to fourteen radii – a streak a dozen times its own width. On a source with no visible brushwork they comb the picture, and they are the first thing a person notices. All three are off by default; a picture that wants them turns them back on. What it costs is sharpness inside a part, and the hair pays most: the strands were the only high-frequency content it had, so without them it reads well under its own source. The gradient, the colour count and the stair fingerprint stay where they were. The measured account is in the version history, appendix E.

What a person decides in the parts table for this route: which regions make up each sub-part and in what occlusion order (ch. 1), which sub-parts are hatched, which grow strands, and where the close-ups are centred (appendix G). expand 0.6, smooth 0.8 and eps 0.30 are each band shape’s expansion, sigma and RDP tolerance (ch. 5’s Shape expansion is 1.2, because too small a value shows a sliver of black ground between the outline and the fill; this route has no lines, so it can be smaller).

limitations

When to use it, what it costs and the route it belongs to, step by step, are in ch. 9; the other route is ch. 10. Its own inherent limits: the layers are not what a person wants (the bands are cut by luminance and have no names, and the node rule fails by design); there is no completion (hide the dress and the legs are cut in two); the strokes are dots rather than lines (the detail brush scatters short dots, and there is no lineart); the hand-written table cannot separate two things inside one region (the majority-vote version can, but this route does not use it); and the hand-written table of regions has to be redone for every new picture.

On origin

Ch. 18, “The one-shot route”: the numbers, the tree, the close-ups and the evidence images.