artgate: render 3D route with Standard view transform, not AgX
Some checks are pending
Pre-commit checks / pre-commit (push) Waiting to run
Python tests / test (push) Waiting to run
Shell tests / shell-tests (push) Waiting to run
Shell tests / arch-tests (push) Waiting to run

Blender defaults to the AgX view transform, a photoreal film emulation
that rolls off highlights and desaturates. On the flat-lit item renders
the 3D route produces, it turned gold into beige and washed out every
material -- which is why row C read as unusable in the bake-off.

Measured on an identical coin scene where only view_transform differed:
mean saturation 0.282 (AgX) vs 0.787 (Standard), a 2.8x increase.

This makes row C a fair test, not a good one: the geometry is still
low-poly primitives and ring/bone remain nearly invisible at 32px.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T9rQ12yZ7sJxiPQTCS5dUF
This commit is contained in:
Krzysztof Rudnicki 2026-08-15 23:09:06 +02:00
parent e6e0ba5ab3
commit a0db432933
2 changed files with 49 additions and 0 deletions

View File

@ -0,0 +1,42 @@
{
"intent": "Stop the artgate 3D route (row C) rendering washed-out, desaturated items. Rendered gold/cyan/red materials came out beige and grey, which made the whole 3D row unfairly fail the human accept gate.",
"scope": [
"python_pkg/artgate/routes/blender_scene.py (SCENE_TEMPLATE only)",
"Non-goal: no geometry, lighting, material or camera changes",
"Non-goal: the route still runs Blender as a fire-and-forget subprocess; it was not rewired to the blender MCP host"
],
"changes": [
"Set scene.view_settings.view_transform = 'Standard' in SCENE_TEMPLATE. Blender defaults to the AgX view transform, a photoreal film emulation that rolls off highlights and desaturates; on flat-lit item renders it destroyed the material colours.",
"Documented the reason inline with the measured numbers so the line is not 'cleaned up' later."
],
"verification": [
{
"command": "controlled A/B render of an identical gold coin scene, AgX vs Standard, via the blender-mcp socket",
"result": "pass",
"evidence": "Identical geometry/materials/lights; only view_transform differed. AgX: mean RGB (193.6,178.6,145.4), saturation 0.282. Standard: mean RGB (241.1,214.7,138.1), saturation 0.787 -- a 2.8x increase. Visually beige vs gold."
},
{
"command": "python3 -c 'from python_pkg.artgate.routes.blender import render; render(\"coin\", out)'",
"result": "pass",
"evidence": "Ran the real route (not a standalone test scene) after the edit; 33193-byte PNG, visually saturated gold."
},
{
"command": "re-rendered all 5 modelled row-C subjects through the real route",
"result": "pass",
"evidence": "coin/gem/ring/bone/bomb all rendered. Saturation coin 0.24->0.68, ring 0.15->0.29, gem 0.09->0.20. bone/bomb unchanged at ~0.03 (genuinely near-greyscale by design). Contact sheet: ~/artgate-output/contact-sheets/ROWC_AGX_FIX.png"
},
{
"command": "pre-commit run --files python_pkg/artgate/routes/blender_scene.py docs/superpowers/evidence/artgate-blender-agx-view-transform-2026-08-15.json",
"result": "pass",
"evidence": "All hooks Passed or Skipped (no files to check); none Failed. Includes ruff, ruff format, mypy, pylint, bandit, pytest with coverage enforcement, and the AI evidence contract."
}
],
"risks": [
"Standard applies no tone mapping, so genuinely over-bright scenes can now clip to white instead of rolling off. Acceptable here: these are flat-lit 256px item renders that get downscaled to 32px, and clipping is preferable to desaturation for game icons.",
"This makes row C a fair test; it does not make row C good. The geometry is still low-poly primitives (the gem is two stacked cones, the bone is spheres on a cylinder) and ring/bone still read as nearly invisible at 32px. Colour management was one bug, not the only one."
],
"rollback": [
"Delete the scene.view_settings.view_transform line from SCENE_TEMPLATE; Blender falls back to the AgX default.",
"After rollback, re-render coin and confirm saturation drops back to ~0.28 to prove the line was the cause."
]
}

View File

@ -39,6 +39,13 @@ scene.render.image_settings.file_format = "PNG"
scene.render.image_settings.color_mode = "RGBA"
scene.render.filepath = OUT
# Blender defaults to the AgX view transform, which is built for photoreal film:
# it rolls off highlights and desaturates hard. On flat-lit item renders that
# turned gold into beige (measured mean saturation 0.28 vs 0.79 for the same
# scene), which is why this route's first pass read as washed out. Game icons
# want the raw shaded colour, so bypass tone mapping entirely.
scene.view_settings.view_transform = "Standard"
def material(name, rgba):
mat = bpy.data.materials.new(name)