Skip to content

Commit a286d13

Browse files
TMHSDigitalclaude
andauthored
fix(examples): redesign vse-gamma-cross as sequencer filmstrips on a grading monitor (#268)
The old hero was a dark board of six small chips with unreadable labels; the key comparison was two near-identical lavender squares, and the chips were emission colors re-encoded through the view transform, not the sequencer's own pixels. The render now shows every frame of the cross, rendered by the VSE and tiled unaltered into two filmstrips: GAMMA_CROSS on top, the sequencer's linear CROSS directly beneath, mounted with closest-texel emission on a hooded grading monitor beside a three-trackball control surface. The endpoints change to orange (1, 0.36, 0) and azure (0, 0.16, 1), whose per-channel square roots sum to 1, so the gamma midpoint is a neutral 0.25 and the dip below the lerp is the per-channel maximum 0.25 (was 0.115) - a dark valley versus violet that reads at card size. The check logic is unchanged; the render path gains the Layer 1 framing gate (exit 10) and a filmstrip guard (exit 9): every frame uniform (5.2 COLOR strips bake scene size at creation, so strips built before the tile resolution letterbox), and each strip's mid frame on its closed form. Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
1 parent 2326141 commit a286d13

9 files changed

Lines changed: 837 additions & 438 deletions

File tree

‎README.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,7 @@ honors linking too (measured), with Cycles pinned for deterministic samples.
514514
</tr>
515515
<tr>
516516
<td width="46%" valign="middle">
517-
<a href="examples/vse-gamma-cross/"><img src="examples/vse-gamma-cross/preview.webp" alt="VSE gamma cross: a calibration lightbox in a dark studio - four backlit chips fading crimson to teal set into bezels on a bolted steel swatch board, with the true midpoint chip beside the brighter naive-lerp midpoint framed in hazard orange, shot at a three-quarter angle" /></a>
517+
<a href="examples/vse-gamma-cross/"><img src="examples/vse-gamma-cross/preview.webp" alt="VSE gamma cross: a hooded grading monitor on a walnut riser beside a three-trackball control surface, its screen showing every frame of an orange-to-azure cross as two filmstrips - the GAMMA_CROSS strip on top sinking to dark grey at mid-cross, the linear CROSS strip beneath passing through violet" /></a>
518518
</td>
519519
<td valign="middle">
520520

@@ -523,7 +523,7 @@ honors linking too (measured), with Cycles pinned for deterministic samples.
523523
The GAMMA_CROSS fade is not the naive linear mix: it blends in a gamma-0.5
524524
space, `((1-t)·√A + t·√B)²` with `t = (frame − start) / duration` — never 1
525525
inside the effect. Per-frame sample renders assert the closed form (mid dips
526-
0.115 below the sRGB lerp), and the AgX-default sampling trap is documented
526+
0.250 below the sRGB lerp), and the AgX-default sampling trap is documented
527527
(`view_transform = 'Standard'` is mandatory for any pixel witness).
528528

529529
</td>
9.36 KB
Loading
4.56 KB
Loading

‎docs/gallery/index.html‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -673,12 +673,12 @@ <h2><a href="gltf-skin-roundtrip/">gltf-skin-roundtrip</a></h2>
673673
</article>
674674
<article class="card" data-tags="sequencer rendering">
675675
<a class="card-media" href="vse-gamma-cross/" tabindex="-1" aria-hidden="true">
676-
<img src="assets/vse-gamma-cross-hero.webp" alt="A steel swatch board with a row of four fade chips from pink to cyan, and below it two mid-grey chips compared, one framed in orange." loading="lazy" decoding="async" />
676+
<img src="assets/vse-gamma-cross-hero.webp" alt="A hooded grading monitor showing two orange-to-blue filmstrips: the gamma cross on top sinks to dark grey in the middle, while the linear cross beneath it passes through violet." loading="lazy" decoding="async" />
677677
</a>
678678
<div class="card-body">
679679
<h2><a href="vse-gamma-cross/">vse-gamma-cross</a></h2>
680680
<p class="teaches">The GAMMA_CROSS fade is not the naive linear mix: it blends in a gamma-0.5 space, so the mid-cross dips below the sRGB lerp. Tiny per-frame renders are asserted against the closed form per frame.</p>
681-
<p class="witnesses"><span class="tag">witnesses</span> out = ((1-t)*sqrt(A) + t*sqrt(B))^2 with t = (frame - start) / duration, never 1 inside the effect. The mid lerp deviation is 0.115; AgX-default sampling poisons the fit (Standard is mandatory).</p>
681+
<p class="witnesses"><span class="tag">witnesses</span> out = ((1-t)*sqrt(A) + t*sqrt(B))^2 with t = (frame - start) / duration, never 1 inside the effect. The mid lerp deviation is 0.250; AgX-default sampling poisons the fit (Standard is mandatory).</p>
682682
<a class="card-link" href="vse-gamma-cross/">View example<span class="sr-only"> vse-gamma-cross</span> <span aria-hidden="true">&rarr;</span></a>
683683
</div>
684684
</article>

‎docs/gallery/vse-gamma-cross/index.html‎

Lines changed: 405 additions & 212 deletions
Large diffs are not rendered by default.

‎examples/gallery.json‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -406,8 +406,8 @@
406406
"name": "vse-gamma-cross",
407407
"dir": "examples/vse-gamma-cross",
408408
"teaches": "The GAMMA_CROSS fade is not the naive linear mix: it blends in a gamma-0.5 space, so the mid-cross dips below the sRGB lerp. Tiny per-frame renders are asserted against the closed form per frame.",
409-
"alt": "A steel swatch board with a row of four fade chips from pink to cyan, and below it two mid-grey chips compared, one framed in orange.",
410-
"witnessesFix": "out = ((1-t)*sqrt(A) + t*sqrt(B))^2 with t = (frame - start) / duration, never 1 inside the effect. The mid lerp deviation is 0.115; AgX-default sampling poisons the fit (Standard is mandatory).",
409+
"alt": "A hooded grading monitor showing two orange-to-blue filmstrips: the gamma cross on top sinks to dark grey in the middle, while the linear cross beneath it passes through violet.",
410+
"witnessesFix": "out = ((1-t)*sqrt(A) + t*sqrt(B))^2 with t = (frame - start) / duration, never 1 inside the effect. The mid lerp deviation is 0.250; AgX-default sampling poisons the fit (Standard is mandatory).",
411411
"hero": "docs/gallery/assets/vse-gamma-cross-hero.webp",
412412
"preview": "examples/vse-gamma-cross/preview.webp",
413413
"tags": [

‎examples/vse-gamma-cross/README.md‎

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
11
# VSE GAMMA_CROSS Blend Curve
22

33
A runnable follow-up to [`vse-cut-list`](../vse-cut-list/): the check renders
4-
tiny frames across a GAMMA_CROSS between crimson and teal strips and asserts
5-
every sample against the fade's actual math — because AI-generated sequencer
6-
code assumes the cross is the naive linear mix, and it is not.
4+
tiny frames across a GAMMA_CROSS between signal-orange and azure strips and
5+
asserts every sample against the fade's actual math — because AI-generated
6+
sequencer code assumes the cross is the naive linear mix, and it is not.
77

88
**What it witnesses:** the fade math and the frame convention behind it.
99

1010
- **The cross blends in a gamma-0.5 space.** Not `(1-t)·A + t·B` but
11-
`((1-t)·√A + t·√B)²` — the mid-cross dips below the sRGB lerp. From crimson
12-
`(0.85, 0.10, 0.22)` and teal `(0.06, 0.75, 0.80)` the midpoint is
13-
`(0.341, 0.349, 0.463)`: **0.115 darker** on red than the lerp
14-
`(0.455, 0.425, 0.510)`. The check renders and asserts nine samples
11+
`((1-t)·√A + t·√B)²` — the mid-cross dips below the sRGB lerp. The
12+
endpoints are chosen to make that dip as large as a cross can: orange
13+
`(1.0, 0.36, 0.0)` and azure `(0.0, 0.16, 1.0)` have per-channel square
14+
roots summing to 1, so the gamma midpoint is the neutral
15+
`(0.25, 0.25, 0.25)` while the lerp midpoint is the violet
16+
`(0.5, 0.26, 0.5)`: **0.25 darker** on red and blue, the per-channel
17+
maximum. The check renders and asserts nine samples
1518
(t = 0, 1/8, …, 7/8, 31/32) within 5e-3
16-
(2× the 8-bit quantization step + fit residual; measured 2.93e-3) and that
17-
the mid lerp deviation is material (≥0.05).
19+
(2× the 8-bit quantization step + fit residual; measured 2.71e-3) and that
20+
the mid lerp deviation is material (≥0.05; measured 0.250).
1821
- **`t = (frame − start) / duration`, and it never reaches 1 inside the
1922
effect.** The last frame of the span blends at `(duration−1)/duration`;
2023
B arrives only when the effect ends. That final frame (frame 32,
@@ -29,22 +32,31 @@ code assumes the cross is the naive linear mix, and it is not.
2932
scene`) — remove effects before their inputs.
3033

3134
**What each check catches on failure:** asserting the naive lerp as the
32-
expectation (exit 6, deviation 0.1138 at mid), the endpoint-inclusive t
35+
expectation (exit 6, deviation 0.2490 at mid), the endpoint-inclusive t
3336
convention (exit 5), and swapped cross inputs (exit 4, `input1=T2`).
3437

35-
**Version witness:** the blend math is identical on Blender 4.5 LTS and 5.1 —
36-
every sample matches to the quantization step. The creation contract from
38+
**Version witness:** the blend math is identical on Blender 4.5 LTS, 5.1 and
39+
5.2 LTS — every sample matches to the quantization step. The creation contract from
3740
`vse-cut-list` still gates the timeline: `strips` (never `.sequences`), and
3841
`new_effect` ending in `length=` on 5.x vs `frame_end=` on 4.5.
3942

40-
The render is a calibration lightbox: the authentic fade as four backlit
41-
chips (t = 0, 1/4, 1/2, 3/4) set into bezels on a bolted steel swatch board
42-
— cap rails, panel seam, corner bolts, rear struts down to a plinth — shot
43-
at a 3/4 angle so it reads as a staged object. Below the fade row sits the
44-
contrast pair: the true mid chip directly beside the naive lerp mid, the
45-
impostor framed in hazard orange. The gamma dip reads as an adjacency
46-
contrast even at card scale: a naive-lerp cross would make the pair
47-
identical, so the still visibly breaks with the contract.
43+
The render is the evidence itself, mounted. All 32 frames of the cross are
44+
rendered by the sequencer and laid side by side as a filmstrip: the
45+
GAMMA_CROSS strip on top, and directly beneath it the same two strips
46+
crossed by the sequencer's linear `CROSS` effect, frame for frame. Both
47+
filmstrips are authentic sequencer pixels shown unaltered (closest-texel
48+
sampling, emission only, Standard view) on a hooded grading monitor beside a
49+
three-ball control surface. The gamma strip sinks into a dark neutral valley
50+
at mid-cross where the linear strip passes through violet; three small warm
51+
ticks mark the t = 1/2 column. A GAMMA_CROSS that was really a lerp would
52+
make the two strips identical, so the still visibly breaks with the contract.
53+
54+
Before shooting, the render path guards its own comparison (exit 9): every
55+
frame must fill its tile edge to edge — a 5.2 COLOR strip bakes the scene
56+
size into its width/height at creation, so strips built before the tile
57+
resolution is set letterbox into black bars (probe: in-frame spread 1.0) —
58+
and each strip's mid frame must match its closed form, so the lower strip
59+
really is the lerp (probe: wiring GAMMA_CROSS in its place fails at 0.249).
4860

4961
## Run
5062

@@ -55,7 +67,7 @@ blender --background --python vse_gamma_cross.py --
5567
# Falsifier: GC T2 -> T1. Must exit non-zero (inputs).
5668
blender --background --python vse_gamma_cross.py -- --swap-inputs
5769

58-
# Also render the calibration lightbox still (EEVEE on a GPU host; cycles on GPU-less):
70+
# Also render the grading-monitor still (EEVEE on a GPU host; cycles on GPU-less):
5971
blender --background --python vse_gamma_cross.py -- --output bench.png
6072
blender --background --python vse_gamma_cross.py -- --output bench.png --engine cycles
6173
```
@@ -76,6 +88,8 @@ against it.
7688
| 6 | Cross sample off the gamma-0.5 closed form |
7789
| 7 | Mid-cross lerp deviation missing (naive mix) |
7890
| 8 | `--output` produced no file |
91+
| 9 | `--output` filmstrip guard: a frame not uniform, or a strip's mid frame off its closed form |
92+
| 10 | `--output` framing violation (`gallery_framing`) |
7993

8094
The `blender-smoke` workflow runs the check on Blender 5.2 LTS and 4.5 LTS
8195
(5.1 on the weekly cron, the `needs-5.1` PR label, or manual dispatch).
9.29 KB
Loading

0 commit comments

Comments
 (0)