hyperframes 0.6.5 → 0.6.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,605 @@
1
+ import { createRequire as __hf_createRequire } from "node:module";
2
+ import { fileURLToPath as __hf_fileURLToPath } from "node:url";
3
+ import { dirname as __hf_dirname } from "node:path";
4
+ var require = __hf_createRequire(import.meta.url);
5
+ var __filename = __hf_fileURLToPath(import.meta.url);
6
+ var __dirname = __hf_dirname(__filename);
7
+
8
+ // ../producer/src/services/shaderTransitionWorker.ts
9
+ import { parentPort } from "worker_threads";
10
+
11
+ // ../engine/src/utils/shaderTransitions.ts
12
+ var HLG_OOTF_LW = 1e3;
13
+ var HLG_OOTF_GAMMA = 1.2 * Math.pow(1.111, Math.log2(HLG_OOTF_LW / 1e3));
14
+ function sampleRgb48le(buf, u, v, w, h) {
15
+ const uc = Math.max(0, Math.min(1, u));
16
+ const vc = Math.max(0, Math.min(1, v));
17
+ const sx = uc * (w - 1);
18
+ const sy = vc * (h - 1);
19
+ const x0 = Math.floor(sx);
20
+ const y0 = Math.floor(sy);
21
+ const x1 = Math.min(x0 + 1, w - 1);
22
+ const y1 = Math.min(y0 + 1, h - 1);
23
+ const fx = sx - x0;
24
+ const fy = sy - y0;
25
+ const w00 = (1 - fx) * (1 - fy);
26
+ const w10 = fx * (1 - fy);
27
+ const w01 = (1 - fx) * fy;
28
+ const w11 = fx * fy;
29
+ const off00 = (y0 * w + x0) * 6;
30
+ const off10 = (y0 * w + x1) * 6;
31
+ const off01 = (y1 * w + x0) * 6;
32
+ const off11 = (y1 * w + x1) * 6;
33
+ const r = Math.round(
34
+ buf.readUInt16LE(off00) * w00 + buf.readUInt16LE(off10) * w10 + buf.readUInt16LE(off01) * w01 + buf.readUInt16LE(off11) * w11
35
+ );
36
+ const g = Math.round(
37
+ buf.readUInt16LE(off00 + 2) * w00 + buf.readUInt16LE(off10 + 2) * w10 + buf.readUInt16LE(off01 + 2) * w01 + buf.readUInt16LE(off11 + 2) * w11
38
+ );
39
+ const b = Math.round(
40
+ buf.readUInt16LE(off00 + 4) * w00 + buf.readUInt16LE(off10 + 4) * w10 + buf.readUInt16LE(off01 + 4) * w01 + buf.readUInt16LE(off11 + 4) * w11
41
+ );
42
+ return [r, g, b];
43
+ }
44
+ function mix16(a, b, t) {
45
+ return Math.round(a * (1 - t) + b * t);
46
+ }
47
+ function clamp16(v) {
48
+ return Math.max(0, Math.min(65535, v));
49
+ }
50
+ function smoothstep(edge0, edge1, x) {
51
+ const t = Math.max(0, Math.min(1, (x - edge0) / (edge1 - edge0)));
52
+ return t * t * (3 - 2 * t);
53
+ }
54
+ function hash(x, y) {
55
+ return (Math.sin(x * 127.1 + y * 311.7) * 43758.5453 % 1 + 1) % 1;
56
+ }
57
+ function vnoise(px, py) {
58
+ const ix = Math.floor(px);
59
+ const iy = Math.floor(py);
60
+ let fx = px - ix;
61
+ let fy = py - iy;
62
+ fx = fx * fx * fx * (fx * (fx * 6 - 15) + 10);
63
+ fy = fy * fy * fy * (fy * (fy * 6 - 15) + 10);
64
+ const h00 = hash(ix, iy);
65
+ const h10 = hash(ix + 1, iy);
66
+ const h01 = hash(ix, iy + 1);
67
+ const h11 = hash(ix + 1, iy + 1);
68
+ return h00 * (1 - fx) * (1 - fy) + h10 * fx * (1 - fy) + h01 * (1 - fx) * fy + h11 * fx * fy;
69
+ }
70
+ var ROT_A = 0.8;
71
+ var ROT_B = 0.6;
72
+ function fbm(px, py) {
73
+ let value = 0;
74
+ let amplitude = 0.5;
75
+ let x = px;
76
+ let y = py;
77
+ for (let i = 0; i < 5; i++) {
78
+ value += amplitude * vnoise(x, y);
79
+ const nx = ROT_A * x - ROT_B * y;
80
+ const ny = ROT_B * x + ROT_A * y;
81
+ x = nx * 2.02;
82
+ y = ny * 2.02;
83
+ amplitude *= 0.5;
84
+ }
85
+ return value;
86
+ }
87
+ var TRANSITIONS = {};
88
+ var crossfade = (from, to, out, w, h, p) => {
89
+ const inv = 1 - p;
90
+ for (let i = 0; i < w * h; i++) {
91
+ const o = i * 6;
92
+ out.writeUInt16LE(Math.round(from.readUInt16LE(o) * inv + to.readUInt16LE(o) * p), o);
93
+ out.writeUInt16LE(
94
+ Math.round(from.readUInt16LE(o + 2) * inv + to.readUInt16LE(o + 2) * p),
95
+ o + 2
96
+ );
97
+ out.writeUInt16LE(
98
+ Math.round(from.readUInt16LE(o + 4) * inv + to.readUInt16LE(o + 4) * p),
99
+ o + 4
100
+ );
101
+ }
102
+ };
103
+ TRANSITIONS["crossfade"] = crossfade;
104
+ var flashThroughWhite = (from, to, out, w, h, p) => {
105
+ const toWhite = smoothstep(0, 0.45, p);
106
+ const fromWhite = 1 - smoothstep(0.5, 1, p);
107
+ const blend = smoothstep(0.35, 0.65, p);
108
+ for (let i = 0; i < w * h; i++) {
109
+ const o = i * 6;
110
+ const fromR = mix16(from.readUInt16LE(o), 65535, toWhite);
111
+ const fromG = mix16(from.readUInt16LE(o + 2), 65535, toWhite);
112
+ const fromB = mix16(from.readUInt16LE(o + 4), 65535, toWhite);
113
+ const toR = mix16(to.readUInt16LE(o), 65535, fromWhite);
114
+ const toG = mix16(to.readUInt16LE(o + 2), 65535, fromWhite);
115
+ const toB = mix16(to.readUInt16LE(o + 4), 65535, fromWhite);
116
+ out.writeUInt16LE(mix16(fromR, toR, blend), o);
117
+ out.writeUInt16LE(mix16(fromG, toG, blend), o + 2);
118
+ out.writeUInt16LE(mix16(fromB, toB, blend), o + 4);
119
+ }
120
+ };
121
+ TRANSITIONS["flash-through-white"] = flashThroughWhite;
122
+ var chromaticSplit = (from, to, out, w, h, p) => {
123
+ for (let i = 0; i < w * h; i++) {
124
+ const ux = i % w / w;
125
+ const uy = Math.floor(i / w) / h;
126
+ const o = i * 6;
127
+ const cx = ux - 0.5;
128
+ const cy = uy - 0.5;
129
+ const fromShift = p * 0.06;
130
+ const fr = sampleRgb48le(from, ux + cx * fromShift, uy + cy * fromShift, w, h)[0];
131
+ const fg = sampleRgb48le(from, ux, uy, w, h)[1];
132
+ const fb = sampleRgb48le(from, ux - cx * fromShift, uy - cy * fromShift, w, h)[2];
133
+ const toShift = (1 - p) * 0.06;
134
+ const tr = sampleRgb48le(to, ux - cx * toShift, uy - cy * toShift, w, h)[0];
135
+ const tg = sampleRgb48le(to, ux, uy, w, h)[1];
136
+ const tb = sampleRgb48le(to, ux + cx * toShift, uy + cy * toShift, w, h)[2];
137
+ out.writeUInt16LE(clamp16(mix16(fr, tr, p)), o);
138
+ out.writeUInt16LE(clamp16(mix16(fg, tg, p)), o + 2);
139
+ out.writeUInt16LE(clamp16(mix16(fb, tb, p)), o + 4);
140
+ }
141
+ };
142
+ TRANSITIONS["chromatic-split"] = chromaticSplit;
143
+ var sdfIris = (from, to, out, w, h, p) => {
144
+ const accentBright = [65535, 55e3, 35e3];
145
+ for (let i = 0; i < w * h; i++) {
146
+ const ux = i % w / w;
147
+ const uy = Math.floor(i / w) / h;
148
+ const o = i * 6;
149
+ const ax = (ux - 0.5) * (w / h);
150
+ const ay = uy - 0.5;
151
+ const d = Math.sqrt(ax * ax + ay * ay);
152
+ const radius = p * 1.2;
153
+ const fw = 3e-3;
154
+ const edge = smoothstep(radius + fw, radius - fw, d);
155
+ const ring1 = Math.exp(-Math.abs(d - radius) * 25);
156
+ const ring2 = Math.exp(-Math.abs(d - radius + 0.04) * 20) * 0.5;
157
+ const ring3 = Math.exp(-Math.abs(d - radius + 0.08) * 15) * 0.25;
158
+ const glow = (ring1 + ring2 + ring3) * p * (1 - p) * 4;
159
+ const [fromR, fromG, fromB] = sampleRgb48le(from, ux, uy, w, h);
160
+ const [toR, toG, toB] = sampleRgb48le(to, ux, uy, w, h);
161
+ out.writeUInt16LE(clamp16(mix16(fromR, toR, edge) + accentBright[0] * glow * 0.6), o);
162
+ out.writeUInt16LE(clamp16(mix16(fromG, toG, edge) + accentBright[1] * glow * 0.6), o + 2);
163
+ out.writeUInt16LE(clamp16(mix16(fromB, toB, edge) + accentBright[2] * glow * 0.6), o + 4);
164
+ }
165
+ };
166
+ TRANSITIONS["sdf-iris"] = sdfIris;
167
+ function glitchRand(x, y) {
168
+ return (Math.sin(x * 12.9898 + y * 78.233) * 43758.5453 % 1 + 1) % 1;
169
+ }
170
+ var glitch = (from, to, out, w, h, p) => {
171
+ const intensity = p * (1 - p) * 4;
172
+ for (let i = 0; i < w * h; i++) {
173
+ const ux = i % w / w;
174
+ const uy = Math.floor(i / w) / h;
175
+ const o = i * 6;
176
+ const lineY = Math.floor(uy * 60) / 60;
177
+ const lineDisp = (glitchRand(lineY, Math.floor(p * 17)) - 0.5) * 0.18 * intensity;
178
+ const blockX = Math.floor(ux * 12);
179
+ const blockY = Math.floor(uy * 8);
180
+ const progressStep = Math.floor(p * 11);
181
+ const br = glitchRand(blockX + progressStep, blockY + progressStep);
182
+ const ba = (br >= 0.83 ? 1 : 0) * intensity;
183
+ const bdx = (glitchRand(blockX * 2.1, blockY * 2.1) - 0.5) * 0.35 * ba;
184
+ const bdy = (glitchRand(blockX * 3.7, blockY * 3.7) - 0.5) * 0.35 * ba;
185
+ const uvx = Math.max(0, Math.min(1, ux + lineDisp + bdx));
186
+ const uvy = Math.max(0, Math.min(1, uy + bdy));
187
+ const shift = intensity * 0.035;
188
+ const r = sampleRgb48le(from, uvx + shift, uvy, w, h)[0];
189
+ const g = sampleRgb48le(from, uvx, uvy, w, h)[1];
190
+ const b = sampleRgb48le(from, uvx - shift, uvy, w, h)[2];
191
+ let cr = r / 65535;
192
+ let cg = g / 65535;
193
+ let cb = b / 65535;
194
+ const scanline = (uy * h * 0.5 % 1 + 1) % 1 >= 0.5 ? 0.05 * intensity : 0;
195
+ cr -= scanline;
196
+ cg -= scanline;
197
+ cb -= scanline;
198
+ const flicker = 1 + (glitchRand(Math.floor(p * 23), 0) - 0.5) * 0.3 * intensity;
199
+ cr *= flicker;
200
+ cg *= flicker;
201
+ cb *= flicker;
202
+ const levels = 256 - (256 - 8) * (intensity * 0.5);
203
+ cr = Math.floor(cr * levels) / levels;
204
+ cg = Math.floor(cg * levels) / levels;
205
+ cb = Math.floor(cb * levels) / levels;
206
+ const [toR, toG, toB] = sampleRgb48le(to, ux, uy, w, h);
207
+ out.writeUInt16LE(clamp16(mix16(Math.round(cr * 65535), toR, p)), o);
208
+ out.writeUInt16LE(clamp16(mix16(Math.round(cg * 65535), toG, p)), o + 2);
209
+ out.writeUInt16LE(clamp16(mix16(Math.round(cb * 65535), toB, p)), o + 4);
210
+ }
211
+ };
212
+ TRANSITIONS["glitch"] = glitch;
213
+ function aces(x) {
214
+ return Math.max(0, Math.min(1, x * (2.51 * x + 0.03) / (x * (2.43 * x + 0.59) + 0.14)));
215
+ }
216
+ var lightLeak = (from, to, out, w, h, p) => {
217
+ const accent = [5e4 / 65535, 25e3 / 65535, 5e3 / 65535];
218
+ const accentBright = [65535 / 65535, 55e3 / 65535, 35e3 / 65535];
219
+ const lpx = 1.3;
220
+ const lpy = -0.2;
221
+ for (let i = 0; i < w * h; i++) {
222
+ const ux = i % w / w;
223
+ const uy = Math.floor(i / w) / h;
224
+ const o = i * 6;
225
+ const dx = ux - lpx;
226
+ const dy = uy - lpy;
227
+ const dist = Math.sqrt(dx * dx + dy * dy);
228
+ const leak = Math.max(0, Math.min(1, Math.exp(-dist * 1.8) * p * 4));
229
+ const warmR = accent[0] + (accentBright[0] - accent[0]) * dist * 0.7;
230
+ const warmG = accent[1] + (accentBright[1] - accent[1]) * dist * 0.7;
231
+ const warmB = accent[2] + (accentBright[2] - accent[2]) * dist * 0.7;
232
+ const flare = Math.exp(-Math.abs(uy - (-0.2 + ux * 0.3)) * 15) * leak * 0.3;
233
+ const [fr, fg, fb] = sampleRgb48le(from, ux, uy, w, h);
234
+ const fromR = fr / 65535;
235
+ const fromG = fg / 65535;
236
+ const fromB = fb / 65535;
237
+ const overR = aces(fromR + warmR * leak * 3 + accentBright[0] * flare);
238
+ const overG = aces(fromG + warmG * leak * 3 + accentBright[1] * flare);
239
+ const overB = aces(fromB + warmB * leak * 3 + accentBright[2] * flare);
240
+ const [toR, toG, toB] = sampleRgb48le(to, ux, uy, w, h);
241
+ const blend = smoothstep(0.15, 0.85, p);
242
+ out.writeUInt16LE(clamp16(mix16(Math.round(overR * 65535), toR, blend)), o);
243
+ out.writeUInt16LE(clamp16(mix16(Math.round(overG * 65535), toG, blend)), o + 2);
244
+ out.writeUInt16LE(clamp16(mix16(Math.round(overB * 65535), toB, blend)), o + 4);
245
+ }
246
+ };
247
+ TRANSITIONS["light-leak"] = lightLeak;
248
+ var crossWarpMorph = (from, to, out, w, h, p) => {
249
+ for (let i = 0; i < w * h; i++) {
250
+ const ux = i % w / w;
251
+ const uy = Math.floor(i / w) / h;
252
+ const o = i * 6;
253
+ const dispX = fbm(ux * 3, uy * 3) - 0.5;
254
+ const dispY = fbm(ux * 3 + 7.3, uy * 3 + 3.7) - 0.5;
255
+ const fromUx = Math.max(0, Math.min(1, ux + dispX * p * 0.5));
256
+ const fromUy = Math.max(0, Math.min(1, uy + dispY * p * 0.5));
257
+ const toUx = Math.max(0, Math.min(1, ux - dispX * (1 - p) * 0.5));
258
+ const toUy = Math.max(0, Math.min(1, uy - dispY * (1 - p) * 0.5));
259
+ const [fromR, fromG, fromB] = sampleRgb48le(from, fromUx, fromUy, w, h);
260
+ const [toR, toG, toB] = sampleRgb48le(to, toUx, toUy, w, h);
261
+ const n = fbm(ux * 4 + 3.1, uy * 4 + 1.7);
262
+ const blend = smoothstep(0.4, 0.6, n + p * 1.2 - 0.6);
263
+ out.writeUInt16LE(clamp16(mix16(fromR, toR, blend)), o);
264
+ out.writeUInt16LE(clamp16(mix16(fromG, toG, blend)), o + 2);
265
+ out.writeUInt16LE(clamp16(mix16(fromB, toB, blend)), o + 4);
266
+ }
267
+ };
268
+ TRANSITIONS["cross-warp-morph"] = crossWarpMorph;
269
+ var whipPan = (from, to, out, w, h, p) => {
270
+ const fromOff = p * 1.5;
271
+ const toOff = (1 - p) * 1.5;
272
+ for (let i = 0; i < w * h; i++) {
273
+ const ux = i % w / w;
274
+ const uy = Math.floor(i / w) / h;
275
+ const o = i * 6;
276
+ let fromR = 0, fromG = 0, fromB = 0;
277
+ for (let s = 0; s < 10; s++) {
278
+ const f = s / 10;
279
+ const fuv = Math.max(0, Math.min(1, ux + fromOff + p * 0.08 * f));
280
+ const [r, g, b] = sampleRgb48le(from, fuv, uy, w, h);
281
+ fromR += r;
282
+ fromG += g;
283
+ fromB += b;
284
+ }
285
+ fromR /= 10;
286
+ fromG /= 10;
287
+ fromB /= 10;
288
+ let toR = 0, toG = 0, toB = 0;
289
+ for (let s = 0; s < 10; s++) {
290
+ const f = s / 10;
291
+ const tuv = Math.max(0, Math.min(1, ux - toOff - (1 - p) * 0.08 * f));
292
+ const [r, g, b] = sampleRgb48le(to, tuv, uy, w, h);
293
+ toR += r;
294
+ toG += g;
295
+ toB += b;
296
+ }
297
+ toR /= 10;
298
+ toG /= 10;
299
+ toB /= 10;
300
+ out.writeUInt16LE(clamp16(mix16(Math.round(fromR), Math.round(toR), p)), o);
301
+ out.writeUInt16LE(clamp16(mix16(Math.round(fromG), Math.round(toG), p)), o + 2);
302
+ out.writeUInt16LE(clamp16(mix16(Math.round(fromB), Math.round(toB), p)), o + 4);
303
+ }
304
+ };
305
+ TRANSITIONS["whip-pan"] = whipPan;
306
+ var cinematicZoom = (from, to, out, w, h, p) => {
307
+ const fromS = p * 0.08;
308
+ const toS = (1 - p) * 0.06;
309
+ for (let i = 0; i < w * h; i++) {
310
+ const ux = i % w / w;
311
+ const uy = Math.floor(i / w) / h;
312
+ const o = i * 6;
313
+ const dx = ux - 0.5;
314
+ const dy = uy - 0.5;
315
+ let fr = 0, fg = 0, fb = 0;
316
+ for (let s = 0; s < 12; s++) {
317
+ const f = s / 12;
318
+ const rr = sampleRgb48le(
319
+ from,
320
+ ux - dx * fromS * 1.06 * f,
321
+ uy - dy * fromS * 1.06 * f,
322
+ w,
323
+ h
324
+ )[0];
325
+ const gg = sampleRgb48le(from, ux - dx * fromS * f, uy - dy * fromS * f, w, h)[1];
326
+ const bb = sampleRgb48le(
327
+ from,
328
+ ux - dx * fromS * 0.94 * f,
329
+ uy - dy * fromS * 0.94 * f,
330
+ w,
331
+ h
332
+ )[2];
333
+ fr += rr;
334
+ fg += gg;
335
+ fb += bb;
336
+ }
337
+ fr /= 12;
338
+ fg /= 12;
339
+ fb /= 12;
340
+ let tr = 0, tg = 0, tb = 0;
341
+ for (let s = 0; s < 12; s++) {
342
+ const f = s / 12;
343
+ const rr = sampleRgb48le(to, ux + dx * toS * 1.06 * f, uy + dy * toS * 1.06 * f, w, h)[0];
344
+ const gg = sampleRgb48le(to, ux + dx * toS * f, uy + dy * toS * f, w, h)[1];
345
+ const bb = sampleRgb48le(to, ux + dx * toS * 0.94 * f, uy + dy * toS * 0.94 * f, w, h)[2];
346
+ tr += rr;
347
+ tg += gg;
348
+ tb += bb;
349
+ }
350
+ tr /= 12;
351
+ tg /= 12;
352
+ tb /= 12;
353
+ out.writeUInt16LE(clamp16(mix16(Math.round(fr), Math.round(tr), p)), o);
354
+ out.writeUInt16LE(clamp16(mix16(Math.round(fg), Math.round(tg), p)), o + 2);
355
+ out.writeUInt16LE(clamp16(mix16(Math.round(fb), Math.round(tb), p)), o + 4);
356
+ }
357
+ };
358
+ TRANSITIONS["cinematic-zoom"] = cinematicZoom;
359
+ var gravitationalLens = (from, to, out, w, h, p) => {
360
+ for (let i = 0; i < w * h; i++) {
361
+ const ux = i % w / w;
362
+ const uy = Math.floor(i / w) / h;
363
+ const o = i * 6;
364
+ const uvx = ux - 0.5;
365
+ const uvy = uy - 0.5;
366
+ const dist = Math.sqrt(uvx * uvx + uvy * uvy);
367
+ const pull = p * 2;
368
+ const warpStr = pull * 0.3 / (dist + 0.1);
369
+ const warpedX = Math.max(0, Math.min(1, ux - uvx * warpStr));
370
+ const warpedY = Math.max(0, Math.min(1, uy - uvy * warpStr));
371
+ const [, ag] = sampleRgb48le(from, warpedX, warpedY, w, h);
372
+ const horizon = smoothstep(0, 0.3, dist / (1 - p * 0.85 + 1e-3));
373
+ const shift = pull * 0.02 / (dist + 0.2);
374
+ const rSampX = Math.max(0, Math.min(1, ux - uvx * (warpStr + shift)));
375
+ const rSampY = Math.max(0, Math.min(1, uy - uvy * (warpStr + shift)));
376
+ const bSampX = Math.max(0, Math.min(1, ux - uvx * (warpStr - shift)));
377
+ const bSampY = Math.max(0, Math.min(1, uy - uvy * (warpStr - shift)));
378
+ const ar = sampleRgb48le(from, rSampX, rSampY, w, h)[0];
379
+ const ab = sampleRgb48le(from, bSampX, bSampY, w, h)[2];
380
+ const lensedR = Math.round(ar * horizon);
381
+ const lensedG = Math.round(ag * horizon);
382
+ const lensedB = Math.round(ab * horizon);
383
+ const [toR, toG, toB] = sampleRgb48le(to, ux, uy, w, h);
384
+ const blend = smoothstep(0.3, 0.9, p);
385
+ out.writeUInt16LE(clamp16(mix16(lensedR, toR, blend)), o);
386
+ out.writeUInt16LE(clamp16(mix16(lensedG, toG, blend)), o + 2);
387
+ out.writeUInt16LE(clamp16(mix16(lensedB, toB, blend)), o + 4);
388
+ }
389
+ };
390
+ TRANSITIONS["gravitational-lens"] = gravitationalLens;
391
+ var rippleWaves = (from, to, out, w, h, p) => {
392
+ const accentBright = [65535, 55e3, 35e3];
393
+ for (let i = 0; i < w * h; i++) {
394
+ const ux = i % w / w;
395
+ const uy = Math.floor(i / w) / h;
396
+ const o = i * 6;
397
+ const uvx = ux - 0.5;
398
+ const uvy = uy - 0.5;
399
+ const dist = Math.sqrt(uvx * uvx + uvy * uvy);
400
+ const nux = uvx + 1e-3;
401
+ const nuy = uvy + 1e-3;
402
+ const nlen = Math.sqrt(nux * nux + nuy * nuy);
403
+ const dirx = nux / nlen;
404
+ const diry = nuy / nlen;
405
+ const fromAmp = p * 0.04;
406
+ const fw1 = Math.exp(Math.sin(dist * 25 - p * 12) - 1);
407
+ const fw2 = Math.exp(Math.sin(dist * 50 - p * 18) - 1) * 0.5;
408
+ const fromUx = Math.max(0, Math.min(1, ux + dirx * (fw1 + fw2) * fromAmp));
409
+ const fromUy = Math.max(0, Math.min(1, uy + diry * (fw1 + fw2) * fromAmp));
410
+ const toAmp = (1 - p) * 0.04;
411
+ const tw1 = Math.exp(Math.sin(dist * 25 + p * 12) - 1);
412
+ const tw2 = Math.exp(Math.sin(dist * 50 + p * 18) - 1) * 0.5;
413
+ const toUx = Math.max(0, Math.min(1, ux - dirx * (tw1 + tw2) * toAmp));
414
+ const toUy = Math.max(0, Math.min(1, uy - diry * (tw1 + tw2) * toAmp));
415
+ const [fromR, fromG, fromB] = sampleRgb48le(from, fromUx, fromUy, w, h);
416
+ const [toR, toG, toB] = sampleRgb48le(to, toUx, toUy, w, h);
417
+ const peak = fw1 * p;
418
+ const tintR = accentBright[0] * peak * 0.1;
419
+ const tintG = accentBright[1] * peak * 0.1;
420
+ const tintB = accentBright[2] * peak * 0.1;
421
+ out.writeUInt16LE(clamp16(mix16(Math.round(fromR + tintR), toR, p)), o);
422
+ out.writeUInt16LE(clamp16(mix16(Math.round(fromG + tintG), toG, p)), o + 2);
423
+ out.writeUInt16LE(clamp16(mix16(Math.round(fromB + tintB), toB, p)), o + 4);
424
+ }
425
+ };
426
+ TRANSITIONS["ripple-waves"] = rippleWaves;
427
+ var swirlVortex = (from, to, out, w, h, p) => {
428
+ for (let i = 0; i < w * h; i++) {
429
+ const ux = i % w / w;
430
+ const uy = Math.floor(i / w) / h;
431
+ const o = i * 6;
432
+ const uvx = ux - 0.5;
433
+ const uvy = uy - 0.5;
434
+ const dist = Math.sqrt(uvx * uvx + uvy * uvy);
435
+ const warp = fbm(ux * 4, uy * 4) * 0.5;
436
+ const fromAng = p * (1 - dist) * 10 + warp * p * 3;
437
+ const fs = Math.sin(fromAng);
438
+ const fc = Math.cos(fromAng);
439
+ const fromUx = Math.max(0, Math.min(1, uvx * fc - uvy * fs + 0.5));
440
+ const fromUy = Math.max(0, Math.min(1, uvx * fs + uvy * fc + 0.5));
441
+ const toAng = -(1 - p) * (1 - dist) * 10 - warp * (1 - p) * 3;
442
+ const ts = Math.sin(toAng);
443
+ const tc = Math.cos(toAng);
444
+ const toUx = Math.max(0, Math.min(1, uvx * tc - uvy * ts + 0.5));
445
+ const toUy = Math.max(0, Math.min(1, uvx * ts + uvy * tc + 0.5));
446
+ const [fromR, fromG, fromB] = sampleRgb48le(from, fromUx, fromUy, w, h);
447
+ const [toR, toG, toB] = sampleRgb48le(to, toUx, toUy, w, h);
448
+ out.writeUInt16LE(clamp16(mix16(fromR, toR, p)), o);
449
+ out.writeUInt16LE(clamp16(mix16(fromG, toG, p)), o + 2);
450
+ out.writeUInt16LE(clamp16(mix16(fromB, toB, p)), o + 4);
451
+ }
452
+ };
453
+ TRANSITIONS["swirl-vortex"] = swirlVortex;
454
+ var thermalDistortion = (from, to, out, w, h, p) => {
455
+ const accentBright = [65535, 55e3, 35e3];
456
+ for (let i = 0; i < w * h; i++) {
457
+ const ux = i % w / w;
458
+ const uy = Math.floor(i / w) / h;
459
+ const o = i * 6;
460
+ const heat = p * 1.5;
461
+ const yFade = smoothstep(1, 0, uy);
462
+ const shimmer = Math.sin(uy * 40 + fbm(ux * 6, uy * 6) * 8) * fbm(ux * 3 + 0, uy * 3 + p * 2);
463
+ const dispX = shimmer * heat * 0.03 * yFade;
464
+ const fromUx = Math.max(0, Math.min(1, ux + dispX));
465
+ const [fromR, fromG, fromB] = sampleRgb48le(from, fromUx, uy, w, h);
466
+ const invShimmer = Math.sin(uy * 40 + fbm(ux * 6 + 3, uy * 6 + 3) * 8) * fbm(ux * 3 + 3, uy * 3 + p * 2);
467
+ const dispX2 = invShimmer * (1 - p) * 0.03 * yFade;
468
+ const toUx = Math.max(0, Math.min(1, ux + dispX2));
469
+ const [toR, toG, toB] = sampleRgb48le(to, toUx, uy, w, h);
470
+ const haze = heat * yFade * 0.15 * (1 - p);
471
+ out.writeUInt16LE(clamp16(mix16(fromR, toR, p) + Math.round(accentBright[0] * haze)), o);
472
+ out.writeUInt16LE(clamp16(mix16(fromG, toG, p) + Math.round(accentBright[1] * haze)), o + 2);
473
+ out.writeUInt16LE(clamp16(mix16(fromB, toB, p) + Math.round(accentBright[2] * haze)), o + 4);
474
+ }
475
+ };
476
+ TRANSITIONS["thermal-distortion"] = thermalDistortion;
477
+ var domainWarp = (from, to, out, w, h, p) => {
478
+ const accentDark = [25e3, 8e3, 2e3];
479
+ const accentBright = [65535, 55e3, 35e3];
480
+ for (let i = 0; i < w * h; i++) {
481
+ const ux = i % w / w;
482
+ const uy = Math.floor(i / w) / h;
483
+ const o = i * 6;
484
+ const qx = fbm(ux * 3, uy * 3);
485
+ const qy = fbm(ux * 3 + 5.2, uy * 3 + 1.3);
486
+ const rx = fbm(ux * 3 + qx * 4 + 1.7, uy * 3 + qy * 4 + 9.2);
487
+ const ry = fbm(ux * 3 + qx * 4 + 8.3, uy * 3 + qy * 4 + 2.8);
488
+ const n = fbm(ux * 3 + rx * 2, uy * 3 + ry * 2);
489
+ const warpDirX = (qx - 0.5) * 0.4;
490
+ const warpDirY = (qy - 0.5) * 0.4;
491
+ const aUx = Math.max(0, Math.min(1, ux + warpDirX * p));
492
+ const aUy = Math.max(0, Math.min(1, uy + warpDirY * p));
493
+ const bUx = Math.max(0, Math.min(1, ux - warpDirX * (1 - p)));
494
+ const bUy = Math.max(0, Math.min(1, uy - warpDirY * (1 - p)));
495
+ const [aR, aG, aB] = sampleRgb48le(from, aUx, aUy, w, h);
496
+ const [bR, bG, bB] = sampleRgb48le(to, bUx, bUy, w, h);
497
+ const e = smoothstep(p - 0.08, p + 0.08, n);
498
+ const ed = Math.abs(n - p);
499
+ const pStep = p >= 1 ? 1 : 0;
500
+ const em = smoothstep(0.1, 0, ed) * (1 - pStep);
501
+ const ecBlend = smoothstep(0, 0.1, ed);
502
+ const ecR = accentDark[0] + (accentBright[0] - accentDark[0]) * (1 - ecBlend);
503
+ const ecG = accentDark[1] + (accentBright[1] - accentDark[1]) * (1 - ecBlend);
504
+ const ecB = accentDark[2] + (accentBright[2] - accentDark[2]) * (1 - ecBlend);
505
+ out.writeUInt16LE(clamp16(mix16(bR, aR, e) + Math.round(ecR * em * 2)), o);
506
+ out.writeUInt16LE(clamp16(mix16(bG, aG, e) + Math.round(ecG * em * 2)), o + 2);
507
+ out.writeUInt16LE(clamp16(mix16(bB, aB, e) + Math.round(ecB * em * 2)), o + 4);
508
+ }
509
+ };
510
+ TRANSITIONS["domain-warp"] = domainWarp;
511
+ function ridged(px, py) {
512
+ let value = 0;
513
+ let amplitude = 0.5;
514
+ let x = px;
515
+ let y = py;
516
+ for (let i = 0; i < 5; i++) {
517
+ value += amplitude * Math.abs(vnoise(x, y) * 2 - 1);
518
+ const nx = ROT_A * x - ROT_B * y;
519
+ const ny = ROT_B * x + ROT_A * y;
520
+ x = nx * 2.02;
521
+ y = ny * 2.02;
522
+ amplitude *= 0.5;
523
+ }
524
+ return value;
525
+ }
526
+ var ridgedBurn = (from, to, out, w, h, p) => {
527
+ const accent = [5e4, 25e3, 5e3];
528
+ const accentDark = [25e3, 8e3, 2e3];
529
+ const accentBright = [65535, 55e3, 35e3];
530
+ for (let i = 0; i < w * h; i++) {
531
+ const ux = i % w / w;
532
+ const uy = Math.floor(i / w) / h;
533
+ const o = i * 6;
534
+ const [aR, aG, aB] = sampleRgb48le(from, ux, uy, w, h);
535
+ const [bR, bG, bB] = sampleRgb48le(to, ux, uy, w, h);
536
+ const n = ridged(ux * 4, uy * 4);
537
+ const e = smoothstep(p - 0.04, p + 0.04, n);
538
+ const heat = smoothstep(0.12, 0, Math.abs(n - p));
539
+ const pStep = p >= 1 ? 1 : 0;
540
+ const heatMasked = heat * (1 - pStep);
541
+ let burnR = accentDark[0] + (accent[0] - accentDark[0]) * smoothstep(0, 0.25, heatMasked);
542
+ let burnG = accentDark[1] + (accent[1] - accentDark[1]) * smoothstep(0, 0.25, heatMasked);
543
+ let burnB = accentDark[2] + (accent[2] - accentDark[2]) * smoothstep(0, 0.25, heatMasked);
544
+ const blend2 = smoothstep(0.25, 0.5, heatMasked);
545
+ burnR = burnR + (accentBright[0] - burnR) * blend2;
546
+ burnG = burnG + (accentBright[1] - burnG) * blend2;
547
+ burnB = burnB + (accentBright[2] - burnB) * blend2;
548
+ const blend3 = smoothstep(0.5, 1, heatMasked);
549
+ burnR = burnR + (65535 - burnR) * blend3;
550
+ burnG = burnG + (65535 - burnG) * blend3;
551
+ burnB = burnB + (65535 - burnB) * blend3;
552
+ const sparks = (vnoise(ux * 80, uy * 80) >= 0.92 ? 1 : 0) * heatMasked * 3;
553
+ out.writeUInt16LE(
554
+ clamp16(
555
+ mix16(bR, aR, e) + Math.round(burnR * heatMasked * 3.5) + Math.round(accentBright[0] * sparks)
556
+ ),
557
+ o
558
+ );
559
+ out.writeUInt16LE(
560
+ clamp16(
561
+ mix16(bG, aG, e) + Math.round(burnG * heatMasked * 3.5) + Math.round(accentBright[1] * sparks)
562
+ ),
563
+ o + 2
564
+ );
565
+ out.writeUInt16LE(
566
+ clamp16(
567
+ mix16(bB, aB, e) + Math.round(burnB * heatMasked * 3.5) + Math.round(accentBright[2] * sparks)
568
+ ),
569
+ o + 4
570
+ );
571
+ }
572
+ };
573
+ TRANSITIONS["ridged-burn"] = ridgedBurn;
574
+
575
+ // ../producer/src/services/shaderTransitionWorker.ts
576
+ if (!parentPort) {
577
+ console.warn("[shaderTransitionWorker] no parentPort; module loaded on main thread");
578
+ } else {
579
+ parentPort.on("message", (msg) => {
580
+ const { shader, bufferA, bufferB, output, width, height, progress } = msg;
581
+ const bufA = Buffer.from(bufferA);
582
+ const bufB = Buffer.from(bufferB);
583
+ const out = Buffer.from(output);
584
+ try {
585
+ const fn = TRANSITIONS[shader] ?? crossfade;
586
+ fn(bufA, bufB, out, width, height, progress);
587
+ const reply = {
588
+ ok: true,
589
+ bufferA,
590
+ bufferB,
591
+ output
592
+ };
593
+ parentPort.postMessage(reply, [bufferA, bufferB, output]);
594
+ } catch (err) {
595
+ const reply = {
596
+ ok: false,
597
+ error: err instanceof Error ? err.message : String(err),
598
+ bufferA,
599
+ bufferB,
600
+ output
601
+ };
602
+ parentPort.postMessage(reply, [bufferA, bufferB, output]);
603
+ }
604
+ });
605
+ }