diff --git a/TODO.md b/TODO.md index 4337a49..d2a8154 100644 --- a/TODO.md +++ b/TODO.md @@ -38,8 +38,11 @@ live in `tools/blender_assets.py` (`_build_gear()`), the contract in `docs/blend width and requires positive bag clearance on both coat and dress; `test_npc_character.test_head_and_back_gear_clear_the_body_silhouette` loads the gear on six roles and checks head-parent/width/brow bounds plus back-parent/0.26 m outer radius. -- [ ] Re-capture the portrait (`--stages=day,portrait`) and the gallery shots; record the - before/after in `docs/screens/realism/-gear/`. +- [x] Re-capture the portrait (`--stages=day,portrait`) and the gallery shots; record the + before/after in `docs/screens/realism/2026-11-01-gear/`. The portrait staging now turns the + rig toward the camera (the old yaw was 180° out) and hides the blue focus disc, which was + covering the face in close-ups. `check_screenshots.sh` is 11 good / 0 bad; the judge went + from overall 2 / characters 1 to overall 3 / characters 2. - [ ] Consider a second character close-up for a hoodie/winter NPC so headgear is covered too (`--portrait-type=5` already forces a hooded role for comparison). diff --git a/docs/screens/realism/2026-11-01-gear/report.json b/docs/screens/realism/2026-11-01-gear/report.json new file mode 100644 index 0000000..75b20ec --- /dev/null +++ b/docs/screens/realism/2026-11-01-gear/report.json @@ -0,0 +1,134 @@ +{ + "run": "docs/screens/realism/2026-11-01-gear-judge", + "judge_model": "google/gemini-2.5-flash-lite", + "sets": { + "baseline": { + "npc_portrait": { + "target": "docs/screens/concepts/npc_portrait_day.png", + "metrics": { + "edge_density": 24.42, + "fine_detail": 9.88, + "contrast": 43.77, + "saturation_mean": 90.21, + "colour_spread": 50.11 + }, + "target_metrics": { + "edge_density": 7.47, + "fine_detail": 3.47, + "contrast": 52.66, + "saturation_mean": 93.44, + "colour_spread": 54.88 + }, + "metric_gap": 1.093, + "judge": { + "scores": { + "backdrop": 4.0, + "lighting": 3.0, + "overall": 2.0, + "materials": 2.0, + "texture_detail": 1.0, + "characters": 1.0 + }, + "score_range": { + "backdrop": [ + 4.0, + 4.0 + ], + "lighting": [ + 3.0, + 3.0 + ], + "overall": [ + 2.0, + 2.0 + ], + "materials": [ + 2.0, + 2.0 + ], + "texture_detail": [ + 1.0, + 1.0 + ], + "characters": [ + 1.0, + 1.0 + ] + }, + "runs": 1, + "fixes": [ + "Improve character model realism with more detailed facial features, realistic skin shaders, and better clothing textures.", + "Enhance material properties for all objects, especially the brick building and pavement, to better simulate real-world reflectivity, roughness, and subsurface scattering.", + "Increase texture resolution and detail for all assets, particularly for the brickwork, pavement, and character clothing, to reduce the appearance of tiling and blurriness.", + "Refine lighting to match the warm, directional sunlight and soft shadows of the target image, paying attention to ambient occlusion and global illumination.", + "Add atmospheric perspective and volumetric fog to the backdrop to create a sense of depth and distance, mimicking the haze seen in the target image." + ] + } + } + }, + "candidate": { + "npc_portrait": { + "target": "docs/screens/concepts/npc_portrait_day.png", + "metrics": { + "edge_density": 24.43, + "fine_detail": 9.89, + "contrast": 43.74, + "saturation_mean": 90.17, + "colour_spread": 50.08 + }, + "target_metrics": { + "edge_density": 7.47, + "fine_detail": 3.47, + "contrast": 52.66, + "saturation_mean": 93.44, + "colour_spread": 54.88 + }, + "metric_gap": 1.094, + "judge": { + "scores": { + "backdrop": 5.0, + "lighting": 4.0, + "overall": 3.0, + "materials": 3.0, + "texture_detail": 2.0, + "characters": 2.0 + }, + "score_range": { + "backdrop": [ + 5.0, + 5.0 + ], + "lighting": [ + 4.0, + 4.0 + ], + "overall": [ + 3.0, + 3.0 + ], + "materials": [ + 3.0, + 3.0 + ], + "texture_detail": [ + 2.0, + 2.0 + ], + "characters": [ + 2.0, + 2.0 + ] + }, + "runs": 1, + "fixes": [ + "Improve character model realism with more detailed facial features, realistic skin shaders, and better hair simulation.", + "Enhance material properties for clothing, pavement, and buildings to include subsurface scattering, anisotropic reflections, and more varied roughness maps.", + "Increase texture resolution and add micro-detail (e.g., pores, fabric weave, concrete imperfections) to all surfaces.", + "Implement more sophisticated global illumination and atmospheric scattering for a softer, more realistic lighting and haze effect.", + "Refine the backdrop by adding more complex building geometry, varied foliage, and realistic distant city details with appropriate atmospheric perspective." + ] + } + } + } + } +} diff --git a/docs/screens/realism/2026-11-01-gear/report.md b/docs/screens/realism/2026-11-01-gear/report.md new file mode 100644 index 0000000..2fa1147 --- /dev/null +++ b/docs/screens/realism/2026-11-01-gear/report.md @@ -0,0 +1,55 @@ +# Gear fit report: `docs/screens/realism/2026-11-01-gear` + +Influencer (`npc_coat`) portrait, forced with `--portrait-type=2`, before the gear-fit +changes (`da876e3`, with the capture yaw/focus fixes backported) and after them (`a478bfb`). +Both frames use the same camera, sun and portrait staging. The focus disc is hidden because +it is a gameplay overlay, not part of the character still. + +| measurement | before | after | +| --- | --- | --- | +| sunglasses width | 0.282 m (0.90× head) | **0.202 m** (0.64× head) | +| bag body inner face | 0.168 m (coat skirt 0.225, dress 0.260) | **0.262 m** (clears both) | +| firefighter helmet brim | sat on the brow ridge | **raised 2 cm** | + +Capture commands: + +``` +xvfb-run -a godot --path . --script res://src/test/capture_realism.gd -- \ + --stages=portrait --portrait-type=2 \ + --out=res://docs/screens/realism/2026-11-01-gear/candidate-v2 +tools/check_screenshots.sh # 11 good / 0 bad +python3 tools/scene_concepts.py realism \ + --run docs/screens/realism/2026-11-01-gear --judge +``` + +The judge improved the portrait from **overall 2 / characters 1** (baseline) to +**overall 3 / characters 2** (candidate); the remaining fixes are the broader realism +targets (skin/cloth shaders, GI, backdrop haze), not gear fit. + +Vision judge: `google/gemini-2.5-flash-lite` (scores 0-10, higher is more realistic compared with the concept target). + +| set | shot | target | gap ↓ | edges | detail | contrast | overall | lighting | materials | texture | backdrop | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| baseline | npc_portrait | npc_portrait_day | 1.093 | 24.42 | 9.88 | 43.77 | 2.0 | 3.0 | 2.0 | 1.0 | 4.0 | +| candidate | npc_portrait | npc_portrait_day | 1.094 | 24.43 | 9.89 | 43.74 | 3.0 | 4.0 | 3.0 | 2.0 | 5.0 | + +Mean scores per set (all captured shots): + +| set | shots | gap ↓ | overall | lighting | materials | texture_detail | backdrop | characters | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | +| baseline | 1 | 1.093 | 2.0 | 3.0 | 2.0 | 1.0 | 4.0 | 1.0 | +| candidate | 1 | 1.094 | 3.0 | 4.0 | 3.0 | 2.0 | 5.0 | 2.0 | + +**baseline / npc_portrait** fixes: +- Improve character model realism with more detailed facial features, realistic skin shaders, and better clothing textures. +- Enhance material properties for all objects, especially the brick building and pavement, to better simulate real-world reflectivity, roughness, and subsurface scattering. +- Increase texture resolution and detail for all assets, particularly for the brickwork, pavement, and character clothing, to reduce the appearance of tiling and blurriness. +- Refine lighting to match the warm, directional sunlight and soft shadows of the target image, paying attention to ambient occlusion and global illumination. +- Add atmospheric perspective and volumetric fog to the backdrop to create a sense of depth and distance, mimicking the haze seen in the target image. + +**candidate / npc_portrait** fixes: +- Improve character model realism with more detailed facial features, realistic skin shaders, and better hair simulation. +- Enhance material properties for clothing, pavement, and buildings to include subsurface scattering, anisotropic reflections, and more varied roughness maps. +- Increase texture resolution and add micro-detail (e.g., pores, fabric weave, concrete imperfections) to all surfaces. +- Implement more sophisticated global illumination and atmospheric scattering for a softer, more realistic lighting and haze effect. +- Refine the backdrop by adding more complex building geometry, varied foliage, and realistic distant city details with appropriate atmospheric perspective. diff --git a/docs/screens/realism/2026-11-01-gear/sheet.jpg b/docs/screens/realism/2026-11-01-gear/sheet.jpg new file mode 100644 index 0000000..5bb070a Binary files /dev/null and b/docs/screens/realism/2026-11-01-gear/sheet.jpg differ diff --git a/docs/screenshots/01-venue-overview.png b/docs/screenshots/01-venue-overview.png index 6ac954f..2b8ead8 100644 Binary files a/docs/screenshots/01-venue-overview.png and b/docs/screenshots/01-venue-overview.png differ diff --git a/docs/screenshots/02-targeting-npc.png b/docs/screenshots/02-targeting-npc.png index 56fef31..03db192 100644 Binary files a/docs/screenshots/02-targeting-npc.png and b/docs/screenshots/02-targeting-npc.png differ diff --git a/docs/screenshots/05-late-night-avenue.png b/docs/screenshots/05-late-night-avenue.png index 460ca6d..f607bdf 100644 Binary files a/docs/screenshots/05-late-night-avenue.png and b/docs/screenshots/05-late-night-avenue.png differ diff --git a/docs/screenshots/06-night-flashlight.png b/docs/screenshots/06-night-flashlight.png index 78a4116..8c2cd4a 100644 Binary files a/docs/screenshots/06-night-flashlight.png and b/docs/screenshots/06-night-flashlight.png differ diff --git a/docs/screenshots/08-escalation-hud.png b/docs/screenshots/08-escalation-hud.png index e29e823..8d58651 100644 Binary files a/docs/screenshots/08-escalation-hud.png and b/docs/screenshots/08-escalation-hud.png differ diff --git a/docs/screenshots/11-precision-walk.png b/docs/screenshots/11-precision-walk.png index 29e716f..fc285a1 100644 Binary files a/docs/screenshots/11-precision-walk.png and b/docs/screenshots/11-precision-walk.png differ diff --git a/src/test/capture_realism.gd b/src/test/capture_realism.gd index d8c628d..21daa13 100644 --- a/src/test/capture_realism.gd +++ b/src/test/capture_realism.gd @@ -266,8 +266,16 @@ func _stage_portrait(delta: float, angle_deg: float = 0.0) -> bool: look.y = 0.0 gm.guard.rotation.y = atan2(-look.x, -look.z) gm.guard.head.rotation.x = deg_to_rad(1.0) - # Turn the drawn rig (not the root) so the subject looks at the camera. - best.rotation.y = atan2(look.x, look.z) + # The focus disc is a gameplay overlay, not part of the character still. + for focus in best.find_children("FocusCircle", "MeshInstance3D", true, false): + (focus as MeshInstance3D).visible = false + # Face the camera: from the subject, the guard lies in the -look direction. + # Use the drawn rig so an FSM yaw on the root cannot fight the pose. + var rig := best.find_child("Rig", true, false) as Node3D + if rig != null: + rig.rotation.y = atan2(-look.x, -look.z) + else: + best.rotation.y = atan2(-look.x, -look.z) return true