Narrower paint, same placement

How many compositions does a corpus use? A label-free count, for AI-default and premodern portraits. The narrowing is in the paint, not in the placing.

Russell Parrish · Parallax Metrology · 14 October 2026 · Companion piece: The Mixing Painter

Finding. At a resolution of one interquartile range, covering 440 Midjourney default portraits takes 254 distinct compositions; 440 premodern oil portraits take 365. At two IQRs the counts are 49 and 101: about half. The narrowing is not evenly spread. On placement — where the mass of the picture goes — the two corpora are level, 1.1×, under two different definitions of what counts as material. On surface it is 2.4×, and about half of that is paint handling that disappears when hatch and grain stop counting. On colour, measured on a separate eight-axis spine, it is 1.5× and rises to 2.0× at coarser resolutions. The count holds at every resolution from 0.4 IQR upward, with any axis removed, at matched pixel resolution, in a second measurement engine on a second human corpus, and in a second generator.

Why count, rather than classify

Earlier work on compositional monoculture asked whether AI images sit in a different place from paintings. That question depends on what they are compared with: genre, subject and artist all move the reference. Trying to build a single membership test on these same portraits failed for exactly that reason; the two classes overlap heavily in structural space, and a portrait is itself a genre that centres one mass.

A covering number asks something that needs no reference class. N(δ) is the number of points needed so that every member of a corpus lies within δ of one of them: the size of the corpus’s compositional vocabulary at that resolution. Each corpus is measured only against itself, with no labels, no fitted threshold and no notion of a correct composition.

Method

Each image is reduced to the eight-coordinate VTL spine: centroid offsets Δx and Δy, void ratio rv, packing density ρr, cohesion μ, peripheral pull xp, orientation stability θ and structural thickness ds. Each axis is scaled by its median and interquartile range over the whole corpus, pooled across the classes being compared, which is what makes δ a shared unit; a consequence is that N(δ) counts both how many distinct arrangements a class uses and how far they reach, separated below. Each axis is then clipped to ±3. N(δ) is the size of a greedy δ-net built in seeded random order, which keeps a point when it is farther than δ from every point already kept; that construction is a δ-packing, and it brackets the covering number between N(δ) and N(δ/2). Covering numbers grow with sample size, so every group is subsampled to the same n, 200 times, and the median and 5–95% band are reported. Every comparison stays inside one measurement engine. The counts in sections 1 to 3, 5 and 7 were pre-registered before they were run; section 4 was not, and the scope note says so. Section 6 reads the same corpus on the gradient-field axes instead of the spine: the 85th and 97th percentile gradient magnitudes, their difference as the tail gap, and the midtone fraction. Section 8 recounts the spine under a second mask, and section 9 counts a separate eight-axis colour spine: the chromatic centroid pair, chromatic dispersion and focality, hue and chroma entropy, effective palette count, and colour independence from structure.

Corpus: 446 premodern European and American single-sitter oil portraits (open-access museum collections, culled for membership, not taste), 447 Midjourney portraits from 112 neutral prompts in the same registers (all four variants kept), and 448 Midjourney portraits from steered prompts.

1. The count

Covering-number curves: AI default lowest, steered next, premodern highest; Van Gogh periods narrowing over time
Left: N(δ) for 440 images per class, log–log. Right: Van Gogh by period, measured only against himself (browser engine, four metrics, 82 works per period). Bands are 5–95% over subsamples.
δ (IQR)AI defaultAI steeredPremodern oil
0.79337352418
1.00254 [249–261]270 [265–275]365 [361–368]
1.5992108181
2.0049 [45–53]60 [55–64]102 [97–108]
3.17131522

Removing any one of the eight axes keeps the order: at δ = 1 the AI-default count ranges from 162 to 216 across the eight removals and the premodern count from 273 to 317. No single axis carries the result.

Van Gogh against himself. His vocabulary narrows in date order: N(1) = 28 in the early work, 24 in Paris, 19 in Arles, 15 at Saint-Rémy and 17 at Auvers. The early set mixes media.

2. Is the breadth only photography?

The premodern images are photographs of paintings: frames, varnish, uneven light and lens variation all reach the measurement. To bound that, each AI-default image was given the same kinds of capture at two strengths (crop imprecision, a picture-frame edge on half the images, slight rotation, varnish cast, gamma, uneven lighting, blur, noise and JPEG), then re-measured with the same engine and the same scaling.

Four Midjourney portraits: original, moderate capture, strong capture
Injected capture on four AI-default portraits (Midjourney outputs generated for this study): original, moderate, strong.
Set (n = 440)N(1.0)N(2.0)Share of the gap from capture
AI default25449
+ moderate capture295680.37 / 0.37
+ strong capture271650.15 / 0.31
Premodern oil364101

Capture widens the texture and density axes (ρr spread ×3.7 to ×6.2, ds ×2.3) and leaves the placement axes (Δx, Δy, xp, rv) at 0.83 to 0.96 of their original spread. What survives capture is placement: where the mass of the picture goes. Section 4 returns to that split, and finds the vocabulary gap is not in placement.

3. A second engine and a second corpus

The same Midjourney images, measured independently with The Crit’s browser kernel, against 116 museum photographs of mixed genre, raw and with tone matched to the AI reference (n = 110 per group).

Bar charts: capture injection and the second-engine replication
Left: capture injection. Right: the second engine.
GroupN(1.0)N(2.0)
rawAI default5419
rawAI steered4517
rawMuseum10156
tone-matchedAI5917
tone-matchedMuseum7726

A second generator, as distinct from a second measurement engine, is in section 7. The museum set is widest raw and tone-matched. Tone matching reduces the museum-to-AI ratio from 1.87 to 1.31 at δ = 1 and from 2.9 to 1.5 at δ = 2. Steered prompts did not widen the vocabulary here (45 against 54, overlapping bands), consistent with the earlier finding that steering narrowed rather than widened. The museum set mixes genres, so its breadth includes genre.

4. Where the gap lives

The sections above establish a gap and bound how much of it is capture. They do not say which part of the composition it is in. Two readings answer that, on the same feature table with the same scaling, grid, seed and 200 subsamples: one separates how far a corpus reaches from how varied it is within that reach, the other splits the spine by the capture sensitivities measured in section 2. Both are diagnostics rather than registered tests, as the scope note records.

Two ratio curves: the gap shrinks under per-class self-scaling, and sits in the texture axes rather than the placement axes
Left: premodern-to-AI vocabulary ratio under the pooled scaling and under per-class self-scaling. Right: the same ratio on the placement axes and on the texture and density axes.

Extent or variety. Pooled scaling lets a class count as wider simply by reaching further on an axis. Scaling each class by its own median and IQR normalises that away, leaving only how unevenly a class fills its own range.

δ (IQR)AI defaultPremodern oilPooled ratioSelf-scaled ratioShare of gap from reach
1.00305 [301–311]333 [329–337]1.441.090.79
1.59124 [119–130]151 [146–157]1.971.220.77
2.0067 [62–72]83 [79–88]2.081.240.78

The order survives at every resolution, and at δ = 1 the bands do not overlap, so the paintings use more distinct arrangements even with their extra reach removed. But 73 to 83% of the gap is reach rather than variety. Under self-scaling the steered set stops sitting between the two (298 against AI default’s 305 at δ = 1): steering widens reach without adding variety, which matches section 3.

Which axes. Section 2 measured that capture widens ρr and ds and leaves placement alone. Counting each half of the spine separately asks where the gap itself sits. A four-axis count is a different quantity from an eight-axis count, not a cleaner one.

SubspaceδAI defaultAI steeredPremodern oilRatio
placement (Δx, Δy, xp, rv)1.0048 [44–53]55 [51–59]54 [50–58]1.12
placement2.009 [7–10]11 [9–13]10 [8–12]1.11
texture / density (ρr, ds, θ, μ)1.0050 [46–53]56 [53–60]119 [114–124]2.38
texture / density2.0011 [9–13]14 [12–16]28 [25–31]2.55

On texture and density the ratio runs 1.8 to 2.7 across the grid with the bands far apart. On placement it runs 1.0 to 1.3, the AI-default and premodern bands overlap at δ = 1, and the steered set matches or exceeds the paintings at every resolution from 0.5 to 2. Where the mass is placed, the two corpora are close; where they differ is in the reading of surface. The spine measures surface under an energy-defined mask, so section 6 reads it again under the gradient-field axes, which answer the same question without depending on where that mask was cut.

The eight-axis leave-one-out check in section 1 does not reach this. Removing one axis of eight leaves seven, so a result carried by four axes survives the removal of any one of them. The capture bound of section 2 is unchanged by this: moderate injection pushed ρr spread to about 3.3 IQR, past the paintings’ own 1.51, and still moved N(1.0) only from 254 to 295.

5. Is it a resolution artifact?

The two sets are not measured at the same number of pixels. Every Midjourney image here has a long edge of 1200; every painting has 1536, because the loader resizes only downward. The axes carrying the gap in section 4 are all computed from a Sobel gradient field, whose statistics can depend on sampling resolution. That is a confound aimed straight at the result, so it was registered as a prediction and tested.

All 446 paintings were re-measured at a 1200 px long edge, the treatment the AI images receive, with the same engine and the same absolute-pixel settings. The AI images were not touched. A control first: this measurement path reproduces a stored painting’s metrics at 1536 to 1 part in 1016, so it is the same instrument that built the corpus.

Subspace, δ = 1AI defaultAI steeredPremodern oilRatioRatio at 1536
placement47 [43–51]54 [50–57]51 [47–55]1.091.12
texture / density44 [41–47]53 [49–57]116 [110–121]2.642.38
full spine243 [238–249]269 [263–275]356 [352–360]1.471.44

The registered prediction was that the texture ratio would fall from 2.38 while staying above 1.5. It did not fall. At matched resolution it is 2.64, and placement stays where it was at 1.09 with the bands overlapping. This holds even though the paintings’ ρr spread drops by 30% when they are measured smaller, so the gap is not carried by that axis having more room at the higher resolution.

Resolution is not the explanation. What this does not test is capture, lens, varnish or framing, which section 2 bounds separately. Upscaling the AI images to 1536 was not run, because it would invent detail the generator never produced.

6. Reading surface without a fixed cut

Density and void are mask-conditional. ρr is the convex-hull packing of a mask defined as the top 15% of gradient, so it answers how densely visual energy packs under an energy-defined material field. That is the right regime for texture-sensitive work, and it has a known consequence: because the mask is defined by rank, the quantities derived from it are near-constant across images by construction. ρr sits at 0.1504 with an interquartile spread of half a percent of its own value; ds, mass fraction and the void index behave the same way.

The kernel prescribes the pairing for exactly this reason: read rv alongside the gradient field, with the tail gap as the peak-seeking diagnostic — “big gap = quiet frame and a few punches, small gap = edge energy everywhere”. Those readings carry the same question with no fixed cut in them, so the count can be taken a second way.

AxisIQRmedianIQR / median% clipped
ρr0.000800.150410.00510.2near-constant
ds0.000210.002750.0772.2near-constant
gradient floor850.044360.083620.530.1alive
tail gap97–850.050100.107950.460.1alive
midtone fraction0.226460.269940.840.1alive

Taken three ways, the count holds, and it is largest on the readings with no fixed cut in them:

AxesRatio at δ = 1
the eight-axis spine1.44
the spine without its mask-conditional axes1.34
gradient field (floor, tail gap, midtone)1.53
gradient field + rv1.70

At δ = 1 on the last of these the AI-default set needs 20 [18–22] compositions and the paintings 34 [31–38], bands apart.

The spine’s halves are grouped differently in the two places they appear. The kernel’s own taxonomy puts ds and θ with placement, which is stable across mask regimes, and ρr with rv as the density pair, which moves with the regime. Section 4 groups by the capture sensitivities measured in section 2 instead. The gap is present under both groupings and under the gradient field, which is the point of taking it three ways.

7. A second generator

Everything above measures one generator. If the narrow vocabulary is a Midjourney property rather than a property of default generation, it should not appear in a different model given the same prompts. This round was pre-registered before any image was made, and it sharpened the question using sections 4 and 5: not “is the count lower” but does a second generator show the same profile, narrow on texture and at parity on placement?

FLUX.2 [klein] 4B, run locally at 4-bit, 4 steps, on the same 112 prompts with the --ar flag stripped, two seeds each, 224 images at 640×800. Because section 5 established that these axes move with sampling resolution, every set here is measured at a common 800 px long edge, so these numbers are comparable to each other and not to the figures above.

Twenty-four FLUX portraits, all dark-ground centred half-length figures in warm brown and olive
Twenty-four of the 224, drawn at random. Competent and coherent, and visibly the same picture each time.
At 800 px, n = 224FLUX kleinAI defaultPremodernpremod / FLUXpremod / AI
full spine N(1.0)59 [55–63]139 [132–148]195 [188–202]3.311.40
placement N(1.0)10 [8–12]40 [36–44]44 [39–48]4.401.10
texture / density N(1.0)21 [19–23]30 [26–34]69 [63–74]3.292.30
Covering-number curves for all four sets measured at 800 px
N(δ) for all four sets at a common 800 px, texture and placement subspaces.

The texture deficit replicates. The registered prediction was that FLUX would also show one, at a ratio of at least 1.5; it shows 3.29, against Midjourney’s 2.30 in the same run, within the registered factor of 1.5 of each other. A narrow vocabulary of surface is therefore not a Midjourney property.

Placement parity does not replicate. The registered prediction was 0.8 to 1.4 and the result is 4.40. Midjourney sits level with the paintings on placement; FLUX does not come close. Placement parity is specific to Midjourney.

The limit on that second sentence was written into the pre-registration and it matters: FLUX.2 klein 4B at 4 bits and 4 steps is small, heavily quantized and few-step, and it is narrower than Midjourney on every axis, with under half the full-spine vocabulary. Its placement narrowness is confounded with model capacity. The honest reading is that placement parity is not universal, not that default generation narrows placement.

8. When paint stops counting as material

Every count above is taken under a mask that is the top 15% of gradient. That is an energy-defined material field, and under it painterly hatch, craquelure, varnish and photographic grain all count as material. The paintings here are museum photographs of varnished, hatched oil; the AI sets are renderings. So a gap measured that way can be a gap of arrangement or a gap of surface handling, and nothing above separates them.

A second mask answers it, built by closing small gaps and then dropping islands below a fraction of frame area, so that speckle becomes coherent mass. The kernel mask is untouched; this one is derived from it and the seven mask-dependent axes are recomputed through the same engine primitives. Median connected components fall from 3,260 to 15 and the largest component grows from 36% of the mass to 70%.

Ratio curves under both masks: texture falls, placement unchanged
Dashed: the energy-defined mask. Solid: the region-biased mask. Texture drops; placement sits at parity under both.
At δ = 1energy maskregion mask
full spine1.401.21
texture / density2.301.58
placement1.101.07

About half the gap is paint handling: 48% of the full-spine gap and 55% of the texture gap disappear when hatch and grain stop counting. What remains is real, 1.58 on texture with the bands apart. And placement is level under both definitions, 1.10 and 1.07, which is the firmest negative result in this study: measured two ways, these corpora do not differ in where they put the mass.

The same mask also settles the question of section 6 in passing. ρr’s spread relative to its own median goes from 0.005 to 0.288, and ds’s from 0.114 to 0.265, while no placement axis moves more than 1.11× and rv does not move at all. A mask chosen to answer a question about paint also gives those two axes something to say.

9. Colour

Everything to this point is the luminance gradient field. For a comparison between paintings and renderings that is a conspicuous omission, and section 8 sharpens it: if half the surface gap is paint handling, colour is the rest of what paint means. The corpus build already computed it, so this is the same count on a different eight axes: the chromatic centroid pair, chromatic dispersion and focality, hue and chroma entropy, how many colours are actually in play, and how far colour decisions run free of structure.

Colour covering numbers and the colour ratio against the structural one
Left: colour-spine counts, bands apart from δ = 0.63 upward. Right: the colour ratio against the structural one.
δ (IQR)AI defaultAI steeredPremodern oilRatio
0.79321 [315–327]355 [350–360]405 [402–407]1.26
1.00219 [212–225]249 [244–255]337 [332–342]1.54
1.5959 [55–63]75 [71–81]119 [113–126]2.02
2.0029 [25–32]36 [33–41]58 [54–62]2.00

Colour is not the exception. It separates the corpora slightly more than structure does at δ = 1 (1.54 against 1.44) and about twice over at coarse resolution, with bands apart from δ = 0.63 upward and a leave-one-axis-out range of 1.56 to 1.76, so no single axis carries it.

The direction is the opposite of what the per-image readings suggest, and that is the point of counting. Taken one picture at a time, the AI portraits are the more colourful: higher chroma entropy (0.80 against 0.74), higher hue entropy, more colours in play (4.3 against 3.8). Each AI portrait is individually richer in colour than each painting. The set of them explores fewer distinct colour configurations. A mean and a count answer different questions, and only the count sees this.

Steering widens colour vocabulary, 249 against 219, where section 4 found it widened structural reach without adding variety.

What did not hold

The same day tested a mechanism. In pure attention mixing, every token moves toward a weighted average of the others, and their disagreement provably shrinks with depth; The Mixing Painter lets you watch a composition collapse that way. Does a real vision transformer collapse its internal disagreement faster on AI-default portraits?

Token disagreement by depth in DINOv2, rising then dropping at the last block
DINOv2 ViT-S/14, all 1,341 portraits: relative token spread by block (median, IQR), and the collapse ratio by class.

No. Token disagreement grows through blocks 1 to 6, plateaus, and drops only at the final block. AI-default portraits first appear to collapse more (AUC 0.73), but they enter the network with more disagreement between patches; premodern portraits carry large uniform dark grounds. With input spread matched, the difference falls to 0.62, 0.51 and 0.43 across terciles. The narrow vocabulary is a property of the outputs, not of a network averaging its tokens.

Scope

Method notes. Spine from the Parallax Portrait engine (compute_structural, verified to reproduce the stored corpus metrics exactly); greedy δ-nets over a log-spaced grid from 0.25 to 4 IQR; 200 seeded subsamples (seed 20261013); second engine The Crit kernel via the steering-authority study tables. Covering numbers and δ-nets are standard (metric entropy); their use here follows Russell Foltz-Smith’s notes on bounded latent dynamics. The measurement pipeline, analysis and this page were built and run with an AI assistant under the author’s direction; every number is reproducible from the scripts in the study folder.