Skip to content

fix(examples): bmesh-gear turned-brass finish replaces moire banding - #258

Merged
TMHSDigital merged 1 commit into
mainfrom
fix/hero-bmesh-gear
Sep 25, 2026
Merged

TMHSDigital merged 1 commit into
mainfrom
fix/hero-bmesh-gear

Conversation

@TMHSDigital

Copy link
Copy Markdown
Owner

What changed and why

Gallery review: the bmesh-gear face was covered in coarse concentric banding that read as a moire/render artifact, not as machining. Two causes. First, a scale-16 RINGS wave drove roughness across a wide 0.14–0.36 range. Second, the wave was fed Generated coordinates, so the rings were centred on the bounding-box corner and crossed the face as off-axis arcs. The old still also clipped about 40k pixels, and the tooth flanks were close to black.

This is a material and lighting fix only. The mesh the check counts is unchanged:

  • Lathe-faced caps. Rings run about the object Z axis (the gear axis) at scale 150, which is below a pixel. Roughness sits in a narrow 0.17–0.21 band with a 0.05 bump. The sub-pixel marks add up to the soft radial fan that a real turned face shows, with no stripes.
  • Hobbed flanks. Flank roughness is 0.55. The object-space face normal separates flanks from caps, so the finish follows the geometry in any pose.
  • Key highlight. A softbox sits on the camera ray's reflection about the front cap, offset to the upper left. Its soft reflection is the face's one clear highlight.
  • Bounce card. A low card in front gives the downward tooth flanks something to reflect. The old hot Glint light was removed.
  • Brass color. Base color is a little more saturated: (0.80, 0.47, 0.12).
  • Framing gate added. The render path now runs the Layer 1 framing gate through gallery_framing.check_framing (exit 10), which it did not do before. The wedge is passed as staging.

Hub/bore: not added. A bore changes the closed-form counts (verts = 2 × 4 × teeth, faces = sides + 2 caps, edges = 3 × profile) that the check asserts, and faking a hole in the shader would be dishonest. The gear stays a solid blank, and the README now says so.

Calibration image changed

bmesh-gear belongs to the pinned contact-sheet calibration set (armature-bend, damped-track-aim, bmesh-gear). This PR changes that calibration image. Contact sheets that other examples committed earlier still show the old gear tile. They are historical evidence and were not regenerated. From now on, scripts/contact_sheet.py will composite the new hero.

Before / after

Gate numbers (Blender 5.2.1 LTS)

Framing (silhouette): fill x=0.488 y=0.856 (band 0.70–0.90, ok). Margins: left=0.272 right=0.241 bottom=0.111 top=0.033 (min 0.020, ok).

Contact sheet (python scripts/contact_sheet.py bmesh-gear):

tile luma stage warmth sat
bmesh-gear (new) 0.2358 0.1772 +0.3027 0.2495
bmesh-gear (old hero) 0.302 0.236 +0.374 0.195
armature-bend 0.2787 0.2132 -0.4279 0.1436
damped-track-aim 0.1511 0.1448 +0.2772 0.2305

Verdicts:

  • Stage darkness: pass. Stage is 0.177, within the calibration range (0.145–0.213). The old hero, at 0.236, was the brightest stage in the set.
  • Wedge warmth: pass. +0.30, close to damped-track-aim (+0.28). The warm pool on the back wall is kept.
  • Subject fill: pass. 0.856 in y.
  • Saturation: pass. 0.250, the highest in the set, from the richer brass.
  • Thumbnail legibility: pass. At 320×180 the image reads at once as a brass gear, with separate teeth, lit flanks and a clean face. It no longer looks like a striped defect.
  • Mean luminance: 0.236 against 0.279 and 0.151 for the other two members, which is mid-set.
  • Clipped pixels: 0 (any channel ≥ 254). The old hero had 40,050.

Hero drift (python scripts/measure_hero_drift.py --only bmesh-gear): mean_abs 0.00297, verdict matches.

Asset-sheet gate: not run. bmesh-gear is a mesh-API example, not a game prop or kit. Geometry is unchanged, so edge90 0.667 in VISUAL-STYLE's table still holds.

Check runs per binary

binary (reported version) check-only --no-extrude falsifier --output render
E:\Blender-Developer-Tools\.scratch\blender-5.2.1-windows-x64\blender.exe (Blender 5.2.1 LTS) exit 0, verts=112 edges=168 faces=58 watertight=True exit 3, topology (56, 56, 1) != expected (112, 168, 58) exit 0, framing_ok
E:\Blender-Developer-Tools\.scratch\blender-5.1.2-windows-x64\blender.exe (Blender 5.1.2) exit 0 exit 3, same exit 0, framing_ok, same numbers
E:\Blender-Developer-Tools\.scratch\blender-4.5.11-windows-x64\blender.exe (Blender 4.5.11 LTS) exit 0 exit 3, same exit 0, framing_ok, same numbers

Falsifiers

  • Topology check (unchanged): --no-extrude gives exit 3 on all three binaries (see above).
  • New framing call site: a temporary copy with cam_data.lens = 75.0 gave exit 10 on 5.2.1: framing_fill x=0.666 y=1.000 FAIL, margins bottom=0.000 top=0.000 FAIL. No PNG was written. The copy was then deleted.

Proven by live run vs established by inspection only

Proven by live run (headless):

  • Check, falsifier and render exit codes on 5.2.1, 5.1.2 and 4.5.11.
  • Framing numbers and the framing falsifier.
  • Contact-sheet metrics and the clipped-pixel counts.
  • Hero drift "matches".
  • build_gallery.py regeneration. I read the generated <img alt> in docs/gallery/index.html and docs/gallery/bmesh-gear/index.html, and it is the new alt sentence in full.

Established by inspection only:

  • The aesthetic verdicts: a turned-brass read, no moire at 1:1 or at thumbnail size, and flank legibility. I judged these by looking at the full-size render, a 3× nearest-neighbour crop of the face centre, and a 320×180 thumbnail.
  • A very faint residual interference texture is visible only in the 3× crop and not at 1:1.
  • The Live MCP was not used.

🤖 Generated with Claude Code

The hero's face was covered in coarse ring stripes: a scale-16 RINGS wave
on Generated coordinates drove roughness over 0.14-0.36, so the rings were
centred on the bounding-box corner and read at thumbnail scale as a striped
render defect rather than machining. The old still also clipped about 40k
pixels and left the tooth flanks nearly black.

The finish now follows how a gear blank is cut. Caps are lathe-faced:
rings about the object Z axis at scale 150 (sub-pixel), a narrow 0.17-0.21
roughness band and a 0.05 bump, which aggregate into the soft radial fan a
turned face actually shows. Flanks are hobbed at roughness 0.55, split from
the caps by the object-space normal. A softbox placed on the camera ray's
reflection about the front cap gives one legible key highlight, and a low
bounce card lights the downward flanks. Clipped pixels: 0.

Geometry is untouched. A bore would change the closed-form counts the
check asserts, so the gear stays a solid blank; no hole is faked in the
shader. The render path now also runs the Layer 1 framing gate (exit 10),
which it previously lacked.

bmesh-gear is a pinned contact-sheet calibration member, so this changes
the calibration image other examples are judged against.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com>
@github-actions github-actions Bot added examples Runnable smoke-gated examples under examples/ documentation Improvements or additions to documentation labels Sep 25, 2026
@TMHSDigital
TMHSDigital merged commit d89ed5a into main Sep 25, 2026
11 checks passed
TMHSDigital added a commit that referenced this pull request Sep 26, 2026
…h measured axis gizmos (#262)

* fix(examples): redesign export-preset-axis as a banded radio mast with measured axis gizmos

The review judged the hero weak: dim olive-on-grey, a thin undesigned pole
with a box, and the Godot copy lying sideways read as "fell over" rather
than as an axis convention.

- The source is now a modelled radio mast: stepped chamfered concrete
  footing, bolted flange, tapered mast in red/white aviation bands with
  steel collars, three sector panels, a shrouded microwave dish on a raked
  arm, an equipment cabinet, and a red obstruction lamp under a lightning
  rod whose point is the witnessed tip vertex. Eight materials.
- Each re-import gets a modelled X/Y/Z gizmo. The frame is measured, not
  placed: the render path picks the axis-aligned rotation mapping source
  vertices onto the re-import (fit_err printed; exit 12 above 1 mm). Unity
  shows blue Z up; Godot shows green Y up and blue Z along the lying mast.
- The camera looks along +X so the lying mast shows its full length.
- The render path now runs gallery_asset_quality (exit 11).

The check contract is unchanged; the same checks pass on 4.5.11, 5.1.2
and 5.2.1, and --same-axis still exits 9.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com>

* chore(gates): export-preset-axis asset sheet against the raised reference set

Adds the RadioMast.Unity selector to scripts/asset_sheet.py and regenerates
the asset sheet and contact sheet after rebasing onto the new reference set
(#257) and the new bmesh-gear calibration hero (#258).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com>

---------

Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
TMHSDigital added a commit that referenced this pull request Sep 26, 2026
…ff (#265)

* fix(examples): redesign gltf-skin-roundtrip as a mech scorpion standoff

The review singled this hero out: two near-identical scorpions built from
untextured orange boxes, with legs clipping into each other and the floor.
The image gave the eye nothing to compare, because a pass meant "they look
the same".

The model is rebuilt from scratch. It has a lofted gunmetal chassis under a
crowned carapace and five shingled tergite plates. Eight jointed legs have
painted femur armour, hydraulic rams and knee drums, and they plant on
rubber pads. Each claw has three bones (arm, swollen chela, movable finger).
The tail has five armoured collars on rubber bellows, and a telson with a
venom band and a chrome needle. There are 5 materials, and emission is used
only on the eyes and the venom band. The rig grows from 7 bones to 21, with
bones pointing +Y, -Y and +/-X, so the rest-matrix round-trip is exercised
off the old single axis.

The composition now witnesses the skin. The authored rig holds the guard
pose the check compares. The actual re-imported mesh is driven through its
IMPORTED armature into a different strike pose. A file that lost the skin,
the joints or the weights could not follow that pose. The render path now
runs gallery_framing (exit 10) and gallery_asset_quality (exit 11).

Two check-protocol bugs were found and fixed; both make the check stricter:
- The "straddle-safe" neighbour lookup added +/-1e-4 without re-rounding,
  so only the exact key could ever match. It reported a phantom weight
  loss (exit 18, 1.0) once the redesign put a vertex on a rounding
  boundary.
- got_w kept only the last re-imported vertex per position. A corrupted
  split copy hid behind its twin, and the weight falsifier fell through to
  exit 19 instead of 18.

Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(examples): regate gltf-skin-roundtrip against the rebased calibration sets

After the rebase onto main, two things changed. #258 re-rendered
bmesh-gear, which darkened the contact-sheet calibration, and #257 raised
the asset-sheet reference set. The scorpion stage measured 0.236, brighter
than every calibration tile, so the key, fill, rim and wedge come down
until the stage sits inside the set (0.204). Luma is now 0.231.

The committed asset-sheet tool gains a row for this example, and it now
bakes an Armature-deformed asset's staged pose before it removes the rig.
Without that bake a skinned asset falls back to its rest pose, and the
scorpion rendered with its tail stretched flat. None of the five
references is skinned, so their panels are unchanged.

Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@TMHSDigital
TMHSDigital deleted the fix/hero-bmesh-gear branch September 26, 2026 23:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation examples Runnable smoke-gated examples under examples/

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant