Files
open-wc/docs/CAMERA_POSE_SWEEP.md
T

6.4 KiB

Renderer Camera Pose Sweep

This offline M00 diagnostic recovers reproducible checkpoint framing when an original-client screenshot has no recorded camera yaw or pitch. It ranks a bounded grid; it does not change renderer or player-camera defaults and does not prove the exact build 12340 camera pose without human approval.

Camera contract

capture_render_checkpoints.gd accepts additive --camera-yaw-offset and --camera-pitch-offset values in degrees. Yaw rotates the no-roll checkpoint basis around Godot world Vector3.UP; pitch then rotates around the camera-local right axis. Zero offsets preserve the manifest target exactly. --single-pass captures only cold_process and is intended for pose calibration, not performance baselines.

Workflow

.\tools\sweep_render_checkpoint_camera_pose.ps1 `
  -ReferenceDirectory 'D:\private-fixtures\wow-3.3.5a-checkpoints' `
  -Checkpoint elwynn_adt_boundary `
  -YawOffsets -15,-10,-5,0,5,10,15 `
  -PitchOffsets -10,-5,0,5,10 `
  -CameraFovValues 38,50,62 `
  -ViewportWidth 1280 -ViewportHeight 960 `
  -WaitSeconds 8

Each candidate receives its own output directory and comparison report. -CameraFovValues adds FOV as another bounded grid dimension; omit it to retain the scalar -CameraFov workflow and legacy candidate paths. The viewport must exactly match the reference image dimensions; the runner fails on size_mismatch instead of inventing a score. The default 8-second wait matches the M00 manifest and is a readiness precondition: lowering it requires evidence that the checkpoint's WMO/M2 content has already appeared. ranking.json sorts candidates by mean perceptual error and then changed-pixel ratio. Use -PlanOnly to validate the Cartesian grid and output paths without rendering. Run a coarse grid first, then a finer grid around the best candidate.

flowchart LR
    Y[Yaw offsets in degrees] --> G[Bounded Cartesian grid]
    P[Pitch offsets in degrees] --> G
    G --> C[Single-pass checkpoint captures]
    R[Original-client reference] --> D[Perceptual comparator]
    C --> D
    D --> J[ranking.json]
    J --> H[Human framing approval]

Interpretation and recovery

The smallest error is a candidate, not automatic fidelity approval. Geometry, materials, lighting and FOV can move the perceptual optimum away from the true original-client pose. Inspect the best images manually and retain the original reference outside Git. A missing matching reference or candidate is a hard error; correct the checkpoint filter or filenames and rerun. Generated PNG and JSON outputs are disposable local evidence.

Verification

The headless capture dry-run must report requested yaw and pitch offsets. Comparator --self-test covers paired metrics. Sweep -PlanOnly covers deterministic grid expansion and output naming without requiring a display. A real ranked sweep requires a display and a private build 12340 reference image.

Goldshire Inn evidence — 2026-07-12

The private 2560x1440 build 12340 goldshire_inn_large_wmo reference was evaluated at FOV 62 degrees. A coarse 5x5 grid over yaw/pitch [-20, -10, 0, 10, 20] reduced mean error from 0.099632 at (0, 0) to 0.077575 at (-10, -20). Extending pitch produced 0.070901 at (0, -40) and 0.063574 at (0, -60) with changed-pixel ratio 0.549556.

These values are invalid camera-pose evidence because the sweep used a 2-second wait. A subsequent readiness audit showed 9 WMO instances and no inn after 2 seconds, 113 instances with the inn visible after 8 seconds, and 328 instances after 15 seconds. The apparent monotonic improvement rewarded grass while the landmark was still absent; it does not demonstrate a spatial/placement defect. The manifest pose remains unchanged pending a ready-scene rerun.

The ready-scene 3x3 rerun at FOV 62 degrees ranked (yaw=10, pitch=-10) first with mean error 0.087952 and changed-pixel ratio 0.665527, compared with 0.101402/0.702489 at zero offsets. Human inspection confirms that the inn is present and the direction is plausible. Pitch remains on the tested boundary and the building scale differs from the reference, so these offsets are coarse evidence only; a joint pitch/FOV refinement is required before changing manifest camera values.

Goldshire joint pitch/FOV refinement — 2026-07-12

A WMO-ready joint grid fixed yaw at 10 degrees and evaluated pitch [-25, -20, -15, -10, -5] across FOV [38, 50, 62]. Full-frame error ranked FOV 62/pitch -25 first at 0.078843 with changed-pixel ratio 0.667721. Human inspection rejects it as a manifest calibration: the view is dominated by grass and crops the inn. FOV 38/pitch -10 is closer to the reference building scale but ranks only 0.084220, and horizontal landmark alignment remains different.

The grid therefore has no approved joint optimum. Full-frame color error continues to trade landmark framing against large terrain regions. The manifest remains unchanged. The next registration method must score an approved inn/road/tree landmark region or explicit landmark coordinates rather than the entire image.

Common landmark region — 2026-07-12

The comparator accepts an optional common screen rectangle through --region x,y,width,height; the sweep runner exposes it as -ComparisonRegion x,y,width,height. Coordinates are integer pixels in the shared reference/candidate image space. Both images must have identical dimensions and the rectangle must be fully inside them. Omitting the option preserves full-frame behavior.

The existing 15 WMO-ready Goldshire candidates were rescored inside [300,100,1400,650], covering the reference facade/chimney and nearby trees. ROI error ranked FOV 38/yaw 10/pitch -15 first at 0.081777 with changed-pixel ratio 0.697185. This is an interior pitch candidate and improves on the full-frame grass preference, but human inspection still rejects manifest calibration: the facade is too large, its upper part is cropped, and the rectangle retains substantial road/terrain pixels. A common rectangle is useful diagnostic weighting, not semantic landmark registration. Explicit approved landmark coordinates or a mask remain necessary.

During this run the sweep orchestration was hardened in two ways: expected comparator exit code 1 is now collected through an explicit child process, and viewport dimensions are explicit. A reference/candidate size_mismatch now fails before ranking instead of producing an empty metric.