Measure crop-over-grass z-fighting with --flicker, now atlas can extract BRP cells #307

Closed
opened 2026-09-27 04:02:26 +00:00 by jeroen · 1 comment
Owner

Problem

The crop-parcel layer has been drawn by the client since 2026-08-30, but its depth ordering has never been checked. docs/notes/crop-parcels.md:95-101 places Crop half a step above Grass with '32 ULP of margin' and then says: "Unverified on real hardware — the --flicker instrument is what would confirm it, and it needs a host serving /brp/coverage.json before there is anything to photograph."

That depth ordering is the only thing keeping the two layers apart. The OSM ground fills are cut against each other so no ground is drawn twice (crates/geo/src/vector_tiles.rs ~2025-2060, the doc comment on tessellate_surfaces). Crop parcels are not part of that cut: crates/geo/src/crops.rs:193-201 (build_crop_meshes) builds them separately with build_flat_fills, and they lie directly on top of the OSM grass that farmland is drawn as. If the margin is too small, every field in the country z-fights with the grass under it whenever the camera moves.

The blocker is gone. e3ea134 (2026-09-26) added atlas's pipeline/brp.rs, which writes brp/14/x/y.json and brp/coverage.json. Its commit body records 1145 parcels across 9 cells over a 3 km box north of Groningen, extracted in 1 s.

Evidence

  • docs/notes/crop-parcels.md:99-101: the unverified claim and the instrument that would settle it.
  • crates/geo/src/crops.rs:193-201: crop meshes are built outside the cut that keeps the ground fills from overlapping.
  • crates/geo/src/ground_stack.rs:138,274: GroundLayer::Crop has a clearance of 1, the smallest in the window, shared with Forest and Sand.
  • crates/cartopolis/src/systems/dev/shot_harness.rs:812-817,3686: crop_parcels is already a --dump-state field.
  • crates/cartopolis/src/systems/map/osm_buildings.rs:147-150 and resources.rs:1635: CARTO_3DBAG_URL points the client at a loopback host, so this needs no production deploy.

Approach

  1. Run atlas run brp --bbox <RD box> locally over the 3 km box from e3ea134's commit body (farmland north of Groningen) into a temporary directory, and serve it on loopback with CARTO_3DBAG_URL. Run it twice: once with the brp/ tree present and once without it. Without it the coverage manifest is missing and no crops are drawn, which gives the "off" side of the comparison.
  2. Capture three viewpoints over that box with --flicker, at 300 m, 1 km and 3 km altitude, pitched about -35°. Use the pinned environment the instrument calls for: --time 12 --clouds 0 --rain 0 --hide-ui. The margin is fixed in depth-buffer ULPs, so a problem at range would show at the higher viewpoints. Shoot on the Deck slot if it is free, otherwise on a VPS slot. Flicker is a geometry question, so lavapipe's output counts here.
  3. If crops add flicker beyond the bound below, fix it in cartopolis_geo. Either cut the parcels' footprint out of the tile's grass group (the same remove-the-overlap approach tessellate_surfaces takes), or widen the Crop clearance in ground_stack. Keep whatever ground_stack tests exist passing. Choose one and give the reason in the commit body.
  4. Replace the 'Unverified' sentence in docs/notes/crop-parcels.md with the measured numbers, the date and the method.

Acceptance criteria

  • With crops on, every viewpoint reports crop_parcels > 0, asserted with --expect 'crop_parcels>0'.
  • At each viewpoint, flicker_px with crops on is at most flicker_px with crops off plus 0.1 % of the frame's pixels. The CSV rows for both runs are recorded in the note.
  • If a fix was needed: the same comparison passes after it, and cargo test -p cartopolis_geo passes, including a new test that a crop parcel over a grass polygon leaves no grass drawn twice (if the cut approach is taken).
  • docs/notes/crop-parcels.md no longer says 'Unverified' about the depth ordering. It states the measured result.

Verification

cargo run -p atlas -- run brp --bbox <xmin ymin xmax ymax> --out /tmp/brp-host
# serve /tmp/brp-host on 127.0.0.1:<port>, then for each of on/off:
CARTO_3DBAG_URL=http://127.0.0.1:<port> WGPU_BACKEND=vulkan cargo run -p cartopolis -- \
  --shot /tmp/crop.png --at <lat>,<lng>,300 --at <lat>,<lng>,1000 --at <lat>,<lng>,3000 \
  --look=-35,0 --look=-35,0 --look=-35,0 --flicker --time 12 --clouds 0 --rain 0 --hide-ui \
  --csv /tmp/crop_on.csv --expect 'crop_parcels>0'
cargo test --locked -p cartopolis_geo

Out of scope

  • Running the BRP pipeline on the production host, or publishing /brp/ there.
  • Crop colours, seasons and tones. Those are judged by eye and colour output from lavapipe is not evidence.
  • Adding a permanent CI gate: scene-smoke has no BRP fixture, and adding one is a separate decision.

Direction

Value 6: the result is flicker_px and crop_parcels, both counts. Value 1: it confirms a claim the note itself marks as unmeasured. If a fix turns out to be needed, the preferred one is to delete the overlap rather than widen the tolerance (the ground stack's own rule). Value 4: grass is only removed where a parcel is drawn in its place. It touches no wire protocol, no database schema, nothing judged by eye, no AR, no Android publishing and no host change: the data is served on loopback inside the container.


Filed unattended by the steward from e3ea134695. To reject, close it with a sentence saying why — the next run reads that.

## Problem The crop-parcel layer has been drawn by the client since 2026-08-30, but its depth ordering has never been checked. `docs/notes/crop-parcels.md:95-101` places `Crop` half a step above `Grass` with '32 ULP of margin' and then says: **"Unverified on real hardware — the `--flicker` instrument is what would confirm it, and it needs a host serving `/brp/coverage.json` before there is anything to photograph."** That depth ordering is the only thing keeping the two layers apart. The OSM ground fills are cut against each other so no ground is drawn twice (`crates/geo/src/vector_tiles.rs` ~2025-2060, the doc comment on `tessellate_surfaces`). Crop parcels are not part of that cut: `crates/geo/src/crops.rs:193-201` (`build_crop_meshes`) builds them separately with `build_flat_fills`, and they lie directly on top of the OSM grass that farmland is drawn as. If the margin is too small, every field in the country z-fights with the grass under it whenever the camera moves. The blocker is gone. e3ea134 (2026-09-26) added atlas's `pipeline/brp.rs`, which writes `brp/14/x/y.json` and `brp/coverage.json`. Its commit body records 1145 parcels across 9 cells over a 3 km box north of Groningen, extracted in 1 s. ## Evidence - `docs/notes/crop-parcels.md:99-101`: the unverified claim and the instrument that would settle it. - `crates/geo/src/crops.rs:193-201`: crop meshes are built outside the cut that keeps the ground fills from overlapping. - `crates/geo/src/ground_stack.rs:138,274`: `GroundLayer::Crop` has a clearance of 1, the smallest in the window, shared with Forest and Sand. - `crates/cartopolis/src/systems/dev/shot_harness.rs:812-817,3686`: `crop_parcels` is already a `--dump-state` field. - `crates/cartopolis/src/systems/map/osm_buildings.rs:147-150` and `resources.rs:1635`: `CARTO_3DBAG_URL` points the client at a loopback host, so this needs no production deploy. ## Approach 1. Run `atlas run brp --bbox <RD box>` locally over the 3 km box from e3ea134's commit body (farmland north of Groningen) into a temporary directory, and serve it on loopback with `CARTO_3DBAG_URL`. Run it twice: once with the `brp/` tree present and once without it. Without it the coverage manifest is missing and no crops are drawn, which gives the "off" side of the comparison. 2. Capture three viewpoints over that box with `--flicker`, at 300 m, 1 km and 3 km altitude, pitched about -35°. Use the pinned environment the instrument calls for: `--time 12 --clouds 0 --rain 0 --hide-ui`. The margin is fixed in depth-buffer ULPs, so a problem at range would show at the higher viewpoints. Shoot on the Deck slot if it is free, otherwise on a VPS slot. Flicker is a geometry question, so lavapipe's output counts here. 3. If crops add flicker beyond the bound below, fix it in `cartopolis_geo`. Either cut the parcels' footprint out of the tile's grass group (the same remove-the-overlap approach `tessellate_surfaces` takes), or widen the Crop clearance in `ground_stack`. Keep whatever `ground_stack` tests exist passing. Choose one and give the reason in the commit body. 4. Replace the 'Unverified' sentence in `docs/notes/crop-parcels.md` with the measured numbers, the date and the method. ## Acceptance criteria - [ ] With crops on, every viewpoint reports `crop_parcels > 0`, asserted with `--expect 'crop_parcels>0'`. - [ ] At each viewpoint, `flicker_px` with crops on is at most `flicker_px` with crops off plus 0.1 % of the frame's pixels. The CSV rows for both runs are recorded in the note. - [ ] If a fix was needed: the same comparison passes after it, and `cargo test -p cartopolis_geo` passes, including a new test that a crop parcel over a grass polygon leaves no grass drawn twice (if the cut approach is taken). - [ ] `docs/notes/crop-parcels.md` no longer says 'Unverified' about the depth ordering. It states the measured result. ## Verification ```bash cargo run -p atlas -- run brp --bbox <xmin ymin xmax ymax> --out /tmp/brp-host # serve /tmp/brp-host on 127.0.0.1:<port>, then for each of on/off: CARTO_3DBAG_URL=http://127.0.0.1:<port> WGPU_BACKEND=vulkan cargo run -p cartopolis -- \ --shot /tmp/crop.png --at <lat>,<lng>,300 --at <lat>,<lng>,1000 --at <lat>,<lng>,3000 \ --look=-35,0 --look=-35,0 --look=-35,0 --flicker --time 12 --clouds 0 --rain 0 --hide-ui \ --csv /tmp/crop_on.csv --expect 'crop_parcels>0' cargo test --locked -p cartopolis_geo ``` ## Out of scope - Running the BRP pipeline on the production host, or publishing `/brp/` there. - Crop colours, seasons and tones. Those are judged by eye and colour output from lavapipe is not evidence. - Adding a permanent CI gate: `scene-smoke` has no BRP fixture, and adding one is a separate decision. ## Direction Value 6: the result is `flicker_px` and `crop_parcels`, both counts. Value 1: it confirms a claim the note itself marks as unmeasured. If a fix turns out to be needed, the preferred one is to delete the overlap rather than widen the tolerance (the ground stack's own rule). Value 4: grass is only removed where a parcel is drawn in its place. It touches no wire protocol, no database schema, nothing judged by eye, no AR, no Android publishing and no host change: the data is served on loopback inside the container. --- _Filed unattended by the steward from `e3ea134695`. To reject, close it with a sentence saying why — the next run reads that._
Author
Owner

Closing on review: superseded by dbb1a41 (2026-09-27), which found the crop/grass blotching on the Deck, removed the overlap with crops::cut_into_ground, and replaced the note's "Unverified" sentence (docs/notes/crop-parcels.md, "Depth, and why the ladder was not enough").

Closing on review: superseded by dbb1a41 (2026-09-27), which found the crop/grass blotching on the Deck, removed the overlap with `crops::cut_into_ground`, and replaced the note's "Unverified" sentence (docs/notes/crop-parcels.md, "Depth, and why the ladder was not enough").
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
jeroen/cartopolis#307
No description provided.