Skip to content

Commit 15dc4f7

Browse files
committed
docs: update visual style guidelines for gallery renders
Expanded the visual style document to clarify mandatory house identity and default stage requirements for gallery renders. Introduced two layers of guidelines: Layer 1 emphasizes the necessity of house identity for all renders, while Layer 2 outlines the default stage as the standard unless specific contracts dictate otherwise. Added detailed instructions on materials, framing, camera setup, and output specifications to ensure consistency and quality across examples. Included a section on legitimate deviations from the default stage with clear criteria for documentation and compliance.
1 parent 2b3e847 commit 15dc4f7

1 file changed

Lines changed: 115 additions & 29 deletions

File tree

docs/VISUAL-STYLE.md

Lines changed: 115 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,30 @@
11
# Gallery Visual Style
22

3-
The spec for every example render that ships in the gallery. New examples must
4-
conform; deviations are defects. Calibration references: `armature-bend`,
5-
`color-attribute-wheel`, `grease-pencil-rosette`, `compositor-glare`,
6-
`damped-track-aim`, `parent-inverse-orrery`.
3+
The spec for every example render that ships in the gallery.
4+
5+
This document has two layers. **House identity** is mandatory for every render
6+
without exception — a render that violates it is a defect. The **default stage**
7+
is the presumption: use it unless the example's own API contract requires
8+
otherwise, and when it does, state the reason in one line in the example README.
9+
A stage deviation without a stated reason is a defect; a stage deviation with one
10+
is normal.
11+
12+
The canonical contact-sheet calibration set lives in `CLAUDE.md` § Quality
13+
Gates for Example Runs. Do not restate its membership here.
714

815
## The look in one sentence
916

1017
A dark staged studio — near-black floor and back wall, one shaped warm key, a
1118
warm light pool raking the backdrop — with a saturated hero subject filling
1219
the frame.
1320

21+
---
22+
23+
# Layer 1 — House identity (mandatory)
24+
25+
These hold for every render in the gallery, including examples that deviate from
26+
the default stage.
27+
1428
## Color management
1529

1630
- `scene.view_settings.view_transform = 'Standard'`, always, with a comment.
@@ -19,6 +33,59 @@ the frame.
1933
traces to renders that never set a transform.
2034
- Standard does not compress highlights: tune light energies so nothing
2135
clips. If a region reads pure white at full size, the key is too hot.
36+
(Exception: a subject whose contract *is* a blown or clamped value —
37+
see Deviations — must still confine the clipping to the witnessed region.)
38+
39+
## Materials
40+
41+
- Hero materials are designed, never Principled defaults: saturated base
42+
colors, roughness chosen (0.3–0.6 glossy, 0.7+ matte), optional faint
43+
emission (~0.1) when the subject carries color data that must read exactly.
44+
- Surfaces that display flat color data (attribute fills, pixel buffers) go
45+
fully matte: `Specular IOR Level = 0`, otherwise the wall/floor horizon
46+
reflects as a line across the face.
47+
- Nothing in frame may read as programmer art. Subjects are modeled with
48+
intent, not primitives with modifiers.
49+
50+
## Framing and camera
51+
52+
- The subject fills roughly 70–90 % of the frame in at least one axis.
53+
Nothing that matters may touch or cross the frame edge.
54+
- Camera: a chosen angle, not the default — typically a 45–55 mm lens,
55+
slightly above subject height, aimed with a `TRACK_TO` constraint at an
56+
empty on the subject. Flat subjects present toward the camera (lean or
57+
tilt them); progressions read left to right.
58+
- No visible helper objects, light shapes, tracking empties, or backdrop
59+
seams crossing the subject.
60+
61+
## The render is the proof
62+
63+
- The image must read in under a second at thumbnail scale.
64+
- The image must witness the API: if the contract failed, the render should
65+
visibly break. If the render would look the same whether the code worked or
66+
not, the scene design is wrong, not merely unpolished.
67+
- Presentation may be staged; evidence may not. When the witnessed artifact
68+
is itself an image (a sequencer frame, a pixel buffer, a baked texture),
69+
the authentic pixels must appear unaltered — mount them in the scene
70+
(`vse-cut-list` on a monitor, `image-pixels-testcard` on a TV) rather than
71+
recreating them.
72+
73+
## Output
74+
75+
- Render 1280×720 PNG (`taa_render_samples`/`cycles.samples` 32–64).
76+
- Gallery assets: hero webp 1280×720 and preview webp 1200×675, quality 85
77+
(load the PNG in Blender, `save(filepath=..., quality=85)`, `scale()` for
78+
the preview — this preserves pixels without re-applying color management).
79+
- After touching any example: `python scripts/build_gallery.py`, and update
80+
the README gallery-row alt text if the composition changed.
81+
82+
---
83+
84+
# Layer 2 — Default stage (the presumption)
85+
86+
Use this unless the contract requires otherwise. It is what makes the gallery
87+
read as one body of work, and the great majority of examples should use it
88+
unmodified.
2289

2390
## Stage
2491

@@ -45,33 +112,52 @@ the frame.
45112
a hard terminator line across any flat surface it skims — if a stray
46113
bright band crosses the subject, a light is grazing it.
47114

48-
## Materials
115+
---
49116

50-
- Hero materials are designed, never Principled defaults: saturated base
51-
colors, roughness chosen (0.3–0.6 glossy, 0.7+ matte), optional faint
52-
emission (~0.1) when the subject carries color data that must read exactly.
53-
- Surfaces that display flat color data (attribute fills, pixel buffers) go
54-
fully matte: `Specular IOR Level = 0`, otherwise the wall/floor horizon
55-
reflects as a line across the face.
117+
# Deviations
56118

57-
## Framing
119+
Some contracts cannot be witnessed on the default stage. The stage is a
120+
presumption, not a cage: when the subject of the example *is* the lighting, the
121+
world, the atmosphere, or the camera itself, the default stage would hide the
122+
very thing being proven.
58123

59-
- The subject fills roughly 70–90 % of the frame in at least one axis.
60-
Nothing that matters may touch or cross the frame edge; no featureless
61-
quadrant of empty wall or floor.
62-
- Camera: 45–55 mm lens, slightly above subject height, aimed with a
63-
`TRACK_TO` constraint at an empty on the subject — a chosen angle, not the
64-
default. Flat subjects present toward the camera (lean or tilt them);
65-
progressions read left to right.
66-
- The image must still read in under a second at thumbnail scale, and it
67-
must witness the API: if the contract failed, the render should visibly
68-
break.
124+
**When a deviation is legitimate.** The contract requires it. Examples:
69125

70-
## Output
126+
- **Lighting contracts** (light linking, shadow-catcher, light groups) — the
127+
arrangement of lights is the evidence; the fixed four-light rig pre-empts it.
128+
- **World / sky contracts** (sky texture, sun elevation, HDRI mapping, world
129+
node trees) — the near-black world value is the thing under test.
130+
- **Volumetric contracts** (scatter density, god rays, absorption) — a
131+
near-black stage swallows the phenomenon.
132+
- **Camera contracts** (depth of field, focus distance, motion blur, sensor
133+
fit) — these need depth and background content the default framing avoids.
134+
- **Non-photoreal contracts** (Freestyle, line art, flat NPR shading) — a
135+
raking key fights the flat readable field the technique produces.
136+
- **Clamping / exposure contracts** — where a blown or clamped value is
137+
precisely what the check asserts.
71138

72-
- Render 1280×720 PNG (`taa_render_samples`/`cycles.samples` 32–64).
73-
- Gallery assets: hero webp 1280×720 and preview webp 1200×675, quality 85
74-
(load the PNG in Blender, `save(filepath=..., quality=85)`, `scale()` for
75-
the preview — this preserves pixels without re-applying color management).
76-
- After touching any example: `python scripts/build_gallery.py`, and update
77-
the README gallery-row alt text if the composition changed.
139+
**What a deviation must still satisfy.** Everything in Layer 1, without
140+
exception: Standard view transform, designed materials, chosen camera,
141+
70–90 % subject fill, no visible helpers, thumbnail legibility, render-as-proof,
142+
authentic evidence, and the output pipeline. Deviate from the stage, never from
143+
the identity.
144+
145+
**What a deviation must not be.** A deviation is not permission to skip staging
146+
effort. "The default stage did not suit this" is not a reason; "this example
147+
witnesses sun elevation, so the world background carries a sky texture" is.
148+
Lighting a deviating scene is *more* work than using the rig, not less — the
149+
scene still needs a designed key, deliberate falloff, and a background that was
150+
chosen rather than defaulted.
151+
152+
**Documenting it.** One line in the example README under a `Stage deviation`
153+
heading: what changed, and which contract required it. One line in the PR body.
154+
That is the whole ceremony.
155+
156+
**The contact-sheet gate under deviation.** The gate still applies and the
157+
composite is still committed. The pass condition is unchanged in substance —
158+
the candidate must not be sortable as belonging to a *different gallery* — but
159+
judge it on materials, framing, finish, view transform, and thumbnail legibility
160+
rather than backdrop match. Report mean luminance against the calibration set as
161+
*information*, not as a pass/fail criterion, and say in the verdict that the
162+
example deviates and why. A bright sky-texture render can hold the lineup; a
163+
carelessly lit one cannot, and the sheet is how you tell them apart.

0 commit comments

Comments
 (0)