feat(qa): reference-vs-render iteration loop; screenshots are demo-only

Tools/visual_loop.py:
- --verify gates every capture against its expectation in Tools/visual_targets.json
  (missing, blank, tone-less or wrong-size shots fail), so 'each screenshot shows
  what was expected' is checked rather than assumed.
- --compare measures luminance, RMS contrast, edge density, palette distance and a
  3x3 luma grid against the reference photograph, with a 0-1 similarity score.
- --iteration N writes Art/reference/iterations/N/{metrics.json,feedback.md}; the
  feedback names the skill to consult (blender-modeler, archviz, materials, lookdev,
  camera-cinematography), so the next modelling pass starts from a measurement.
- Iterations are gitignored until the owner confirms a shot; only confirmed shots
  are promoted into Screenshots/.

Screenshots/ holds demo-map captures only now: render_screenshots.sh renders just
DemoMap, collects the shots and runs the verification gate (--verify); the review
staging map is no longer rendered for review and its PNGs are removed. The README
is rewritten around the four demo shots with per-shot expected content and a
verified column, and no longer claims the review staging set.

Tests: 67 pass (13 new) covering metrics on synthetic images, comparison scoring,
the feedback rules and the target spec (including that every target is a demo shot
and that iterations are gitignored).
This commit is contained in:
zwitschi committed 2026-11-08 19:52:25 +01:00
1 parent ad5bb25009
commit bd1f8a9c2e
25 files changed
+688 -121

No files matched your search

+24
View File
@@ -626,3 +626,27 @@ Scope: facts and traps that cost time to establish. Planned work lives in [TODO.
- `ue_import_facade_kit.py` now deletes kit assets that the current build no longer
produces, so a rename cannot leave two generations of the same piece in the
folder (the rename from `Kit_*` to `SM_Kit_*` did exactly that until it did).
## 2026-11-09 — visual comparison loop; screenshots are demo-only
- `Tools/visual_loop.py` closes the reference → render → feedback loop.
`--verify` gates captures against `Tools/visual_targets.json` (blank, tone-less,
wrong-size fail); `--compare` measures luma, RMS contrast, edge density, palette
distance and a 3x3 luma grid against the reference and prints a 0–1 score;
`--iteration N` writes `Art/reference/iterations/N/{metrics.json,feedback.md}`.
The feedback names the skill to consult, so the next modelling pass starts from a
measurement rather than an opinion.
- **Iterations are gitignored** (`/Art/reference/iterations/`); only confirmed shots
are promoted into `Screenshots/`. A test asserts the ignore rule and that every
target is a demo-map shot.
- `Screenshots/` now holds **demo-map captures only** — the review staging map is no
longer rendered for review. `render_screenshots.sh --verify` renders the demo map,
collects the shots and runs the verification gate in one step.
- **PIL gotchas:** `FIND_EDGES` leaves its own border ring at 128 (236/3600 px on a
60x60 frame = 6.5% "detail" on a perfectly flat image), so crop **after**
filtering — cropping before does not help, the new border gets the same
treatment. Palette shares must divide by the full-image area, not the cropped one.
- First comparison (iteration 2): spawn view 0.70, street level 0.35, crossing 0.41,
north buildings 0.34. Edge density is the dominant gap everywhere (0.04–0.11
against 0.20–0.32 in the references) — the render still lacks the relief the
photographs carry, which is exactly what the `0.1.4` façade work is for.