diff --git a/docs/gallery/asset-sheets/terrain-scatter.webp b/docs/gallery/asset-sheets/terrain-scatter.webp
new file mode 100644
index 00000000..4764d74e
Binary files /dev/null and b/docs/gallery/asset-sheets/terrain-scatter.webp differ
diff --git a/docs/gallery/assets/car-mirror-symmetry-hero.webp b/docs/gallery/assets/car-mirror-symmetry-hero.webp
index ac3430e8..209f94d0 100644
Binary files a/docs/gallery/assets/car-mirror-symmetry-hero.webp and b/docs/gallery/assets/car-mirror-symmetry-hero.webp differ
diff --git a/docs/gallery/assets/terrain-scatter-hero.webp b/docs/gallery/assets/terrain-scatter-hero.webp
index bc375bcd..42e16560 100644
Binary files a/docs/gallery/assets/terrain-scatter-hero.webp and b/docs/gallery/assets/terrain-scatter-hero.webp differ
diff --git a/docs/gallery/car-mirror-symmetry/index.html b/docs/gallery/car-mirror-symmetry/index.html
index e9155d65..2ec75a13 100644
--- a/docs/gallery/car-mirror-symmetry/index.html
+++ b/docs/gallery/car-mirror-symmetry/index.html
@@ -283,7 +283,7 @@
car-mirror-symmetry
Original holds the half. Body datablock is exactly 126 verts / 231 edges / 106 faces (14 × 9, loft closed forms), with exactly 28 centerline verts (probe: modifier applied into data → exit 3, datablock reads (224, 434, 212)).
Evaluated is the welded whole. Exactly 2n − c = 224 verts (probe: use_mirror_merge = False → exit 5, 252 verts — the doubled seam; probe: one centerline vert pulled off the plane → exit 4, 27 ≠ 28 welded; probe: mirror axis off → exit 5, 126 — the half-car). The evaluated shell is watertight (every edge borders 2 faces) with Euler characteristic 2 — the two halves weld into a topological sphere.
Exact ±X partners. Every evaluated vertex has a partner at negated X: measured deviation 0.000e+00 (mirror copies exactly; tol 2e-5 guards float32), evaluated bbox symmetric (min.x == −max.x).
Mirrored parts. Wheels (96/81 half → 192/162 evaluated) and lamps (8/6 → 16/12) each double across the plane with partner deviation 0.0 — and each object origin reads x == 0.
Why the checks target the modifier, not the base: mutating a non-plane base vertex cannot break the ±X pairing — the evaluated set is always half ∪ mirror(half), symmetric by construction. Realistic failures live in the modifier (merge off, axis off, modifier applied into data, origin off the plane), which is what the probes break.
Version witness: check output is byte-identical on Blender 4.5.11 LTS and 5.1.2. Mirror, evaluated_get / to_mesh / to_mesh_clear (no argument — passing the mesh raises TypeError on both), and TRACK_TO constraint behavior are stable across the pair; only the EEVEE engine id is version-gated.
-
The render is the proof: hide the mirror and the still is literally half a car — halved windshield and hood at the centerline, one headlamp. Render notes: the loft is faceted by design (flat shading, no bevel modifier — the modifier stack is Mirror only, so counts stay closed-form); the window band is glass by construction class (steepest roof-rise slope is the windshield, steepest drop the rear window, ring segment 5 the side windows), and the glass is dielectric — metallic glass mirrors the key light and renders the windshield as a hot salmon slab.
+
The render is the proof: hide the mirror and the still is literally half a car — halved windshield and hood at the centerline, one headlamp. Render notes: the loft is faceted by design (flat shading, no bevel modifier — the modifier stack is Mirror only, so counts stay closed-form); the window band is glass by construction class (steepest roof-rise slope is the windshield, steepest drop the rear window, ring segment 5 the side windows), and the glass is dielectric — metallic glass mirrors the key light and renders the windshield as a hot salmon slab. The camera stands on the key light's side of the car: from the other side it saw only the flank the key cannot reach, and the whole visible side rendered near-black. The car is mirror-symmetric, so the composition is the same either way. The bright streak along the cowl below the windshield is the key's highlight in a crease that faces it.
Run
# Cheap correctness check (no render) — the CI check:
blender --background --python car_mirror_symmetry.py --
@@ -788,7 +788,10 @@
Source
cam_data = bpy.data.cameras.new("Cam")
cam_data.lens = 52.0
cam = bpy.data.objects.new("Cam", cam_data)
- cam.location = (4.4, -5.3, 2.1)
+ # On the key's side (-X): the car is mirror-symmetric, so this is the
+ # same composition, but at +X the camera saw the flank the key cannot
+ # reach and the whole visible side rendered near-black.
+ cam.location = (-4.4, -5.3, 2.1)
scene.collection.objects.link(cam)
track = cam.constraints.new('TRACK_TO') # data API, not bpy.ops (damped-track-aim)
track.target = aim
diff --git a/docs/gallery/contact-sheets/car-mirror-symmetry-contact-sheet.webp b/docs/gallery/contact-sheets/car-mirror-symmetry-contact-sheet.webp
index c398c592..76844901 100644
Binary files a/docs/gallery/contact-sheets/car-mirror-symmetry-contact-sheet.webp and b/docs/gallery/contact-sheets/car-mirror-symmetry-contact-sheet.webp differ
diff --git a/docs/gallery/contact-sheets/terrain-scatter-contact-sheet.webp b/docs/gallery/contact-sheets/terrain-scatter-contact-sheet.webp
index f45055fb..49294325 100644
Binary files a/docs/gallery/contact-sheets/terrain-scatter-contact-sheet.webp and b/docs/gallery/contact-sheets/terrain-scatter-contact-sheet.webp differ
diff --git a/docs/gallery/index.html b/docs/gallery/index.html
index e1890c42..2e8a9dac 100644
--- a/docs/gallery/index.html
+++ b/docs/gallery/index.html
@@ -981,12 +981,12 @@
A Geometry Nodes hill tile with seated icosphere scatter through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than an API contract.
-
witnesses Recomputed: 1758 tris, two materials with 720 stone faces, UVs in 0..1 with zero AABB overlap, outer AABB 1.800×1.800×0.552 m, grounded zmin, 9 stones of ≥80 faces seated on sampled dirt Z (offset −35 mm, floor zmin 0.113 m), LOD ratios in band, convex collider 81 tris, hygiene zero, non-empty glTF. --skip-decimate exits 9; --stray-vert 15; --lift-z 16; --poke-rock 17; --float-rocks 18; --box-rocks 19.
+
A Geometry Nodes hill tile with embedded, varied stone scatter through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than an API contract.
+
witnesses Recomputed: 2398 tris, two materials with 720 stone faces, UVs in 0..1 with zero AABB overlap, outer AABB 1.800x1.800x0.570 m, grounded zmin, 9 stones of >=80 faces each sealed into the ground in 8/8 sectors, footprint ratio 9.8, rim tilt step 33.5 deg, no stone pairs overlapping, LOD ratios in band, convex collider 36 tris, hygiene zero, non-empty glTF. --skip-decimate exits 9; --stray-vert 15; --lift-z 16; --poke-rock 17; --float-rocks 18; --box-rocks 19; --pile-rocks 20; --perch-rocks 21; --uniform-rocks 22; --sharp-rim 23.