Epic 2.5.1: basis for framing layer

This commit is contained in:
Dejvino
2026-08-06 10:29:32 +02:00
parent 189328587d
commit 19bfff8651
9 changed files with 346 additions and 3 deletions
+18
View File
@@ -99,6 +99,14 @@ export function setFrameUniforms(layer, renderer, target, ctx) {
else u[name].value = v;
}
// Framing is per shot and wins over the personality's neutral defaults —
// it is the operator's hand on a shot that is already set up, not a trait
// of the track. See look/framing.js.
if (layer.framing) {
u.u_sigFrameScale.value = layer.framing.scale;
u.u_sigFrameShift.value.set(layer.framing.shift[0], layer.framing.shift[1]);
}
u.u_prev.value = prevTexture || null;
u.u_hasPrev.value = prevTexture ? 1 : 0;
}
@@ -136,6 +144,16 @@ export class Layer {
return this;
}
/**
* This shot's FRAMING — a per-shot scale/recentre pushed by the arc driver,
* applied inside sigCamera. A layer that is never framed renders at the
* neutral (full-frame) scale, so nothing predating framing changes.
*/
setFraming(framing) {
this.framing = framing || null;
return this;
}
/** Resolve base params + reactive modulation into the values used this frame. */
resolveParams(features) {
const defs = this.module.params || {};
+2 -2
View File
@@ -163,7 +163,7 @@ void main() {
) * 0.08;
float breath = 1.0 + u_sigBreathe * sin(u_barPhase * 6.28318530718);
vec2 corner = vec2(-u_aspect + 0.2, -1.0 + 0.1) + cam;
vec2 corner = vec2(-u_aspect + 0.3, -1.0 + 0.1) + cam;
float blockH = 0.09 * breath;
float blockW = blockH * u_titleAspect;
vec2 blockBL = corner;
@@ -181,7 +181,7 @@ void main() {
// --- shape: the signature form stamped as a monogram left of the title ---
float emD = blockH * 0.95;
vec2 emC = vec2(blockBL.x - blockH * 0.35, blockC.y);
vec2 emC = vec2(blockBL.x - blockH * 1.15, blockC.y);
float d = sigShape((p - emC) / max(emD * 0.5, 1e-3)) * (emD * 0.5);
float emFill = smoothstep(u_sigSoft * emD * 0.15, -u_sigSoft * emD * 0.15, d);
float emEdge = sigEdge(d);
+18
View File
@@ -73,6 +73,20 @@ export const SIGNATURE_UNIFORMS = {
u_sigSoft: 'float', // edge softness
u_sigTexture: 'float', // surface grain
u_sigFold: 'float', // kaleidoscopic folds, 1 = none
// FRAMING. Not a personality trait — this one is per SHOT, pushed by the
// arc driver rather than derived from the track. See look/framing.js.
//
// Every scene in the library is a locked-off, full-frame wide, and always
// has been. That is one shot type, held for the length of a song, and it is
// the reason cutting between two scenes changes the subject but never the
// FRAMING — which is at least half of how a real edit holds attention.
//
// Applied inside sigCamera, in scene coordinates, so a close-up is rendered
// close rather than being a magnified 720p image. That distinction is the
// whole reason this is a coordinate transform and not a post pass.
u_sigFrameScale: 'float', // >1 pushes in, <1 pulls back
u_sigFrameShift: 'vec2', // recentre, in scene units
};
export const FRAME_UNIFORMS = [
@@ -210,6 +224,10 @@ float sigForm(vec2 p, vec2 centre, float size) {
*/
vec2 sigCamera(vec2 p) {
float t = u_time;
// Framing first: everything below is the operator's hand on a shot that has
// already been set up, so it composes on top of the framing rather than
// fighting it.
p = p / max(u_sigFrameScale, 0.05) + u_sigFrameShift;
p = rot(u_sigSpin * t) * p;
p *= 1.0 - u_sigBreathe * sin(u_barPhase * 6.28318530718);
p += vec2(sin(t * u_sigSwayRate), cos(t * u_sigSwayRate * 0.83)) * u_sigSway;