Epic 2.5.2: make the framing actually reach the image

Revisiting the framing layer turned up that it was not reaching four of the
forty-two scenes, and that none of its gates could have told us.

Those gates check the PLAN — cue sizes, the distribution of shot sizes across
a population, headroom, seek determinism — and a plan that never reaches the
image passes every one of them. Rendered at wide, normal and close, Scan
Tear, Pylon Grid, Pitch Shatter and the 3D Particle Field came back
byte-identical at every size.

The cause was a category error in the first implementation. Framing was
applied inside sigCamera, which is gated on the `camera` personality trait —
so a scene that declined the track's drift and sway silently declined the
shot size as well. That gating is right for a TRAIT and wrong for framing,
which is not one: framing is where the camera is standing for this shot, and
no scene should be exempt from it because of an unrelated art-direction
decision.

- Framing now lives in the shader epilogue, applied to the coordinate every
  fragment scene is handed, so honouring it is not optional. uv is left
  unframed on purpose: it is screen space, and prev() and sigGrain belong to
  the output image rather than to the scene being filmed.
- Scan Tear and Pitch Shatter build their image from uv deliberately — a
  signal artefact happens to the signal, not to the world behind it. They now
  slice on raw uv and build the field they displace from a new framedUv(p),
  so the tear stays locked to the frame while the imagery behind it is filmed
  wide or close.
- Particle Field receives framing in update() and honours it as a camera
  dolly, which is what framing literally is when a layer has a real camera.
  Distance divided by scale, matching the fragment path where the coordinate
  is divided by it.

New gate renders instead of inspecting: 42 of 42 scenes now respond to
framing, weakest Ridge Terrain at 0.22 of its own brightness, against a 0.05
floor. Also drops a stale comment on Layer.setFraming that still claimed
sigCamera applied it.

105/105 checks pass including the slow set.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Dejvino
2026-08-06 20:18:08 +02:00
co-authored by Claude Opus 5
parent c92c398d18
commit e6f5a2f0d5
7 changed files with 156 additions and 17 deletions
+26 -3
View File
@@ -190,9 +190,32 @@ actually change size, sizes stay in headroom, and two drivers over one look agre
What this pass does not do, and the reason it is "simple": the framing is constant within a shot.
A zoom that moves during a shot is a separate device and would fight the drift LFO and the slow
axis, both of which already own continuous motion. Scenes built outside the shader contract (the
single 3D layer) are not framed yet. Both are the obvious next steps and neither is required for
a working project.
axis, both of which already own continuous motion.
**Revisited, and it was not reaching four scenes.**
The gates above check the PLAN — cue sizes, distribution, headroom, determinism — and a plan
that never reaches the image passes every one of them. It did. Framing was applied inside
`sigCamera`, which is gated on the `camera` personality trait, so a scene that declined the
track's drift silently declined the shot size too. That is correct for a trait and wrong for
framing, which is not one: it is where the camera is standing, and no scene should be exempt
from it because of an unrelated art-direction decision. Rendered, Scan Tear, Pylon Grid, Pitch
Shatter and the 3D layer were identical at every size, and nothing noticed.
Three fixes:
- Framing moved out of `sigCamera` and into the shader epilogue, applied to the coordinate every
fragment scene is handed. `uv` is deliberately left unframed — it is screen space, and `prev()`
and `sigGrain` belong to the output image rather than to the scene being filmed.
- Screen-space glitch scenes (Scan Tear, Pitch Shatter) build their image from `uv` on purpose:
a signal artefact happens to the signal, not to the world behind it. They now slice on raw
`uv` and build the field they displace from `framedUv(p)`, so the tear stays locked to the
frame while the imagery behind it is filmed wide or close.
- The 3D layer receives `framing` in `update` and honours it as an actual camera dolly, which is
what framing literally is when a scene has a real camera.
And a gate that renders rather than inspecting the plan: **42 of 42 scenes now respond to
framing**, weakest Ridge Terrain at 0.22 of its own brightness.
---