Epic 2.5.1: basis for framing layer
This commit is contained in:
@@ -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 || {};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user