pixi-effects 0.22.0 → 0.26.0
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.
- package/CHANGELOG.md +37 -0
- package/README.md +17 -15
- package/ai/CHAT.md +2 -2
- package/ai/chat-template.html +3 -3
- package/ai/tools/check.mjs +10 -3
- package/ai/tools/pixi-effects.mjs +48 -0
- package/ai/tools/render.mjs +3 -3
- package/ai/tools/view.mjs +3 -3
- package/dist/{Base-gu-5X0Cv.d.ts → Base-BgnRXbtJ.d.ts} +1 -1
- package/dist/{Base-BzlPgd-D.d.cts → Base-DHVKqA46.d.cts} +1 -1
- package/dist/Composition-2GJSCHPP.cjs +16 -0
- package/dist/{Composition-BK5SH6J7.cjs.map → Composition-2GJSCHPP.cjs.map} +1 -1
- package/dist/Composition-C4FSWJZF.js +7 -0
- package/dist/{Composition-Q5TVG3HM.js.map → Composition-C4FSWJZF.js.map} +1 -1
- package/dist/Controller.cjs +2 -2
- package/dist/Controller.d.cts +2 -2
- package/dist/Controller.d.ts +2 -2
- package/dist/Controller.js +1 -1
- package/dist/{Movie--_TJvdJa.d.ts → Movie-DP5p1r4E.d.ts} +5 -1
- package/dist/{Movie-DMxOoTdW.d.cts → Movie-DXReF4-W.d.cts} +5 -1
- package/dist/Presenter.cjs +2 -2
- package/dist/Presenter.d.cts +2 -2
- package/dist/Presenter.d.ts +2 -2
- package/dist/Presenter.js +1 -1
- package/dist/{blendModes-HCP5XTNP.js → blendModes-G3NOAU3T.js} +5 -5
- package/dist/{blendModes-HCP5XTNP.js.map → blendModes-G3NOAU3T.js.map} +1 -1
- package/dist/{blendModes-5E4G2ZZQ.cjs → blendModes-YV43K6E7.cjs} +6 -6
- package/dist/{blendModes-5E4G2ZZQ.cjs.map → blendModes-YV43K6E7.cjs.map} +1 -1
- package/dist/{chunk-K4JVI5HK.cjs → chunk-3DLYAPK7.cjs} +7 -9
- package/dist/{chunk-K4JVI5HK.cjs.map → chunk-3DLYAPK7.cjs.map} +1 -1
- package/dist/{chunk-YEPDQ7I3.js → chunk-AXZUKNXF.js} +6 -6
- package/dist/{chunk-YEPDQ7I3.js.map → chunk-AXZUKNXF.js.map} +1 -1
- package/dist/{chunk-NHICCDTC.js → chunk-BXOCEZ4U.js} +12 -3
- package/dist/chunk-BXOCEZ4U.js.map +1 -0
- package/dist/{chunk-IFZOI3JQ.cjs → chunk-DP37TTMO.cjs} +842 -40
- package/dist/chunk-DP37TTMO.cjs.map +1 -0
- package/dist/{chunk-BPTW7L25.cjs → chunk-ECA2WNRX.cjs} +23 -9
- package/dist/chunk-ECA2WNRX.cjs.map +1 -0
- package/dist/{chunk-DC4JPY6A.js → chunk-PRZ4U6JN.js} +814 -22
- package/dist/chunk-PRZ4U6JN.js.map +1 -0
- package/dist/chunk-SY27HZC5.cjs +1727 -0
- package/dist/chunk-SY27HZC5.cjs.map +1 -0
- package/dist/{chunk-E7RONUZ7.js → chunk-TLYTYBWX.js} +20 -6
- package/dist/chunk-TLYTYBWX.js.map +1 -0
- package/dist/{chunk-UZTKEYFP.cjs → chunk-TWZNOUM7.cjs} +12 -3
- package/dist/chunk-TWZNOUM7.cjs.map +1 -0
- package/dist/chunk-XS6GSJCN.js +1724 -0
- package/dist/chunk-XS6GSJCN.js.map +1 -0
- package/dist/index.cjs +234 -77
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +173 -16
- package/dist/index.js.map +1 -1
- package/dist/loader.css +1 -1
- package/dist/{music-FUN7N225.js → music-AF4VTFAF.js} +3 -3
- package/dist/{music-FUN7N225.js.map → music-AF4VTFAF.js.map} +1 -1
- package/dist/{music-GEAH2XCT.cjs → music-KB7YZLHP.cjs} +7 -7
- package/dist/{music-GEAH2XCT.cjs.map → music-KB7YZLHP.cjs.map} +1 -1
- package/dist/{sfx-2DYTYNYW.cjs → sfx-2O6UQEUP.cjs} +8 -8
- package/dist/{sfx-2DYTYNYW.cjs.map → sfx-2O6UQEUP.cjs.map} +1 -1
- package/dist/{sfx-3IDAJ3UZ.js → sfx-VUKARHDX.js} +3 -3
- package/dist/{sfx-3IDAJ3UZ.js.map → sfx-VUKARHDX.js.map} +1 -1
- package/dist/three.cjs +7 -7
- package/dist/three.d.cts +2 -2
- package/dist/three.d.ts +2 -2
- package/dist/three.js +3 -3
- package/dist/{types-DBbZVKGS.d.cts → types-CoT0ypcx.d.cts} +60 -4
- package/dist/{types-DBbZVKGS.d.ts → types-CoT0ypcx.d.ts} +60 -4
- package/docs/api.md +2 -2
- package/docs/dsl.md +140 -7
- package/llms-full.txt +328 -39
- package/llms.txt +6 -5
- package/package.json +3 -3
- package/{ai → skills/pixi-effects}/SKILL.md +16 -12
- package/{ai → skills/pixi-effects}/reference/cheatsheet.md +10 -7
- package/{ai → skills/pixi-effects}/reference/pitfalls.md +22 -4
- package/{ai → skills/pixi-effects}/reference/recipes.md +133 -2
- package/{ai/tools → skills/pixi-effects/scripts}/save-image.py +1 -1
- package/{ai → skills/pixi-effects}/template.html +6 -6
- package/dist/Composition-BK5SH6J7.cjs +0 -16
- package/dist/Composition-Q5TVG3HM.js +0 -7
- package/dist/chunk-BPTW7L25.cjs.map +0 -1
- package/dist/chunk-DC4JPY6A.js.map +0 -1
- package/dist/chunk-E7RONUZ7.js.map +0 -1
- package/dist/chunk-IFZOI3JQ.cjs.map +0 -1
- package/dist/chunk-MHOO2CVU.cjs +0 -840
- package/dist/chunk-MHOO2CVU.cjs.map +0 -1
- package/dist/chunk-NHICCDTC.js.map +0 -1
- package/dist/chunk-UQDEDYVM.js +0 -838
- package/dist/chunk-UQDEDYVM.js.map +0 -1
- package/dist/chunk-UZTKEYFP.cjs.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
3
|
+
var chunkECA2WNRX_cjs = require('./chunk-ECA2WNRX.cjs');
|
|
4
|
+
var chunkTWZNOUM7_cjs = require('./chunk-TWZNOUM7.cjs');
|
|
5
5
|
var PIXI = require('pixi.js');
|
|
6
6
|
var gsap = require('gsap');
|
|
7
7
|
|
|
@@ -501,7 +501,7 @@ function checkEase(ease, where) {
|
|
|
501
501
|
console.warn(`pixi-effects: ${where}: "${ease}" is a family, not an ease \u2014 write ${ease.toLowerCase()}.out, ${ease.toLowerCase()}.in or ${ease.toLowerCase()}.inOut`);
|
|
502
502
|
return;
|
|
503
503
|
}
|
|
504
|
-
const guess =
|
|
504
|
+
const guess = chunkTWZNOUM7_cjs.suggestName(ease, EASE_NAMES);
|
|
505
505
|
console.warn(`pixi-effects: ${where}: unknown ease "${ease}"${guess ? ` \u2014 did you mean "${guess}"?` : ""} (GSAP would run it as its default ease, power1.out). Examples: ${EASE_NAMES.slice(0, 7).join(", ")}, back.out(1.7), elastic.out(1, 0.3), steps(8)`);
|
|
506
506
|
}
|
|
507
507
|
|
|
@@ -549,8 +549,8 @@ function partitionProps(props) {
|
|
|
549
549
|
for (const k of Object.keys(props)) {
|
|
550
550
|
const m = k.match(/^filters\.([^.]+)\.(.+)$/);
|
|
551
551
|
if (m) {
|
|
552
|
-
const [, name,
|
|
553
|
-
(filterProps[name] ??= {})[
|
|
552
|
+
const [, name, sub2] = m;
|
|
553
|
+
(filterProps[name] ??= {})[sub2] = props[k];
|
|
554
554
|
} else {
|
|
555
555
|
ownProps[k] = props[k];
|
|
556
556
|
}
|
|
@@ -562,10 +562,10 @@ function splitRouted(props, routers) {
|
|
|
562
562
|
const rest = {};
|
|
563
563
|
const routed = [];
|
|
564
564
|
for (const k of Object.keys(props)) {
|
|
565
|
-
const
|
|
566
|
-
const router =
|
|
565
|
+
const dot2 = k.indexOf(".");
|
|
566
|
+
const router = dot2 > 0 ? routers[k.slice(0, dot2)] : void 0;
|
|
567
567
|
if (router) {
|
|
568
|
-
const hit = router(k.slice(
|
|
568
|
+
const hit = router(k.slice(dot2 + 1));
|
|
569
569
|
if (hit) routed.push({ target: hit.target, prop: hit.prop, key: k, value: props[k] });
|
|
570
570
|
} else {
|
|
571
571
|
rest[k] = props[k];
|
|
@@ -1111,7 +1111,7 @@ var GRAIN_KEYS = ["amount", "size", "seed", "fps", "color"];
|
|
|
1111
1111
|
var GrainFilter = class extends PIXI.Filter {
|
|
1112
1112
|
_fps;
|
|
1113
1113
|
constructor(options = {}) {
|
|
1114
|
-
|
|
1114
|
+
chunkTWZNOUM7_cjs.warnUnknownOptions("grain filter", options, GRAIN_KEYS);
|
|
1115
1115
|
const { amount = 0.08, size = 1.5, seed = 0, fps = 24, color = 0 } = options;
|
|
1116
1116
|
super({
|
|
1117
1117
|
glProgram: PIXI.GlProgram.from({ vertex: GL_VERTEX, fragment: GL_FRAGMENT2, name: "grain-filter" }),
|
|
@@ -1166,10 +1166,238 @@ var GrainFilter = class extends PIXI.Filter {
|
|
|
1166
1166
|
this.u.uFrame = this._fps > 0 ? Math.floor(t * this._fps + 1e-3) : 0;
|
|
1167
1167
|
}
|
|
1168
1168
|
};
|
|
1169
|
+
var WARP_KINDS = ["wave", "haze"];
|
|
1170
|
+
var OPTION_KEYS = ["kind", "strength", "scale", "speed", "angle", "seed"];
|
|
1171
|
+
var DEG = Math.PI / 180;
|
|
1172
|
+
var HASH_GL2 = `
|
|
1173
|
+
uint hash(uint x) { x ^= x >> 16; x *= 0x7feb352du; x ^= x >> 15; x *= 0x846ca68bu; x ^= x >> 16; return x; }
|
|
1174
|
+
float lattice(ivec2 p, uint k) {
|
|
1175
|
+
uint h = hash(uint(p.x) + hash(uint(p.y) + hash(k)));
|
|
1176
|
+
return float(h >> 8) / 16777215.0;
|
|
1177
|
+
}
|
|
1178
|
+
float valueNoise(vec2 q, uint k) {
|
|
1179
|
+
vec2 i = floor(q);
|
|
1180
|
+
vec2 f = fract(q);
|
|
1181
|
+
vec2 u = f * f * (3.0 - 2.0 * f);
|
|
1182
|
+
ivec2 p = ivec2(i);
|
|
1183
|
+
float a = lattice(p, k), b = lattice(p + ivec2(1, 0), k), c = lattice(p + ivec2(0, 1), k), d = lattice(p + ivec2(1, 1), k);
|
|
1184
|
+
return mix(mix(a, b, u.x), mix(c, d, u.x), u.y);
|
|
1185
|
+
}`;
|
|
1186
|
+
var GL_VERTEX2 = `#version 300 es
|
|
1187
|
+
precision highp float;
|
|
1188
|
+
in vec2 aPosition;
|
|
1189
|
+
out vec2 vTextureCoord;
|
|
1190
|
+
uniform highp vec4 uInputSize;
|
|
1191
|
+
uniform highp vec4 uOutputFrame;
|
|
1192
|
+
uniform highp vec4 uOutputTexture;
|
|
1193
|
+
void main(void) {
|
|
1194
|
+
vec2 position = aPosition * uOutputFrame.zw + uOutputFrame.xy;
|
|
1195
|
+
position.x = position.x * (2.0 / uOutputTexture.x) - 1.0;
|
|
1196
|
+
position.y = position.y * (2.0 * uOutputTexture.z / uOutputTexture.y) - uOutputTexture.z;
|
|
1197
|
+
gl_Position = vec4(position, 0.0, 1.0);
|
|
1198
|
+
vTextureCoord = aPosition * (uOutputFrame.zw * uInputSize.zw);
|
|
1199
|
+
}`;
|
|
1200
|
+
var GL_FRAGMENT3 = `#version 300 es
|
|
1201
|
+
precision highp float;
|
|
1202
|
+
precision highp int;
|
|
1203
|
+
in vec2 vTextureCoord;
|
|
1204
|
+
uniform sampler2D uTexture;
|
|
1205
|
+
uniform highp vec4 uInputSize;
|
|
1206
|
+
uniform highp vec4 uInputClamp;
|
|
1207
|
+
uniform float uStrength;
|
|
1208
|
+
uniform float uScale;
|
|
1209
|
+
uniform float uSpeed;
|
|
1210
|
+
uniform float uAngle;
|
|
1211
|
+
uniform float uSeed;
|
|
1212
|
+
uniform float uMode;
|
|
1213
|
+
uniform float uTime;
|
|
1214
|
+
out vec4 finalColor;
|
|
1215
|
+
${HASH_GL2}
|
|
1216
|
+
void main(void) {
|
|
1217
|
+
vec2 pos = vTextureCoord * uInputSize.xy;
|
|
1218
|
+
vec2 off;
|
|
1219
|
+
if (uMode < 0.5) {
|
|
1220
|
+
float phase = dot(pos, vec2(cos(uAngle), sin(uAngle))) / uScale - uSpeed * uTime;
|
|
1221
|
+
float s = uStrength * sin(6.28318530718 * phase);
|
|
1222
|
+
off = vec2(-sin(uAngle), cos(uAngle)) * s;
|
|
1223
|
+
} else {
|
|
1224
|
+
uint k = hash(uint(uSeed));
|
|
1225
|
+
vec2 p = vec2(pos.x / uScale, pos.y / uScale - uSpeed * uTime);
|
|
1226
|
+
off = uStrength * 2.0 * vec2(valueNoise(p, k) - 0.5, valueNoise(p + vec2(37.2, 17.8), k) - 0.5);
|
|
1227
|
+
}
|
|
1228
|
+
vec2 suv = clamp(vTextureCoord + off * uInputSize.zw, uInputClamp.xy, uInputClamp.zw);
|
|
1229
|
+
finalColor = texture(uTexture, suv);
|
|
1230
|
+
}`;
|
|
1231
|
+
var WGSL_SOURCE3 = `
|
|
1232
|
+
struct GlobalFilterUniforms {
|
|
1233
|
+
uInputSize: vec4<f32>,
|
|
1234
|
+
uInputPixel: vec4<f32>,
|
|
1235
|
+
uInputClamp: vec4<f32>,
|
|
1236
|
+
uOutputFrame: vec4<f32>,
|
|
1237
|
+
uGlobalFrame: vec4<f32>,
|
|
1238
|
+
uOutputTexture: vec4<f32>,
|
|
1239
|
+
};
|
|
1240
|
+
struct WarpUniforms {
|
|
1241
|
+
uStrength: f32,
|
|
1242
|
+
uScale: f32,
|
|
1243
|
+
uSpeed: f32,
|
|
1244
|
+
uAngle: f32,
|
|
1245
|
+
uSeed: f32,
|
|
1246
|
+
uMode: f32,
|
|
1247
|
+
uTime: f32,
|
|
1248
|
+
};
|
|
1249
|
+
@group(0) @binding(0) var<uniform> gfu: GlobalFilterUniforms;
|
|
1250
|
+
@group(0) @binding(1) var uTexture: texture_2d<f32>;
|
|
1251
|
+
@group(0) @binding(2) var uSampler : sampler;
|
|
1252
|
+
@group(1) @binding(0) var<uniform> warpUniforms : WarpUniforms;
|
|
1253
|
+
|
|
1254
|
+
struct VSOutput {
|
|
1255
|
+
@builtin(position) position: vec4<f32>,
|
|
1256
|
+
@location(0) uv : vec2<f32>,
|
|
1257
|
+
};
|
|
1258
|
+
fn filterVertexPosition(aPosition : vec2<f32>) -> vec4<f32> {
|
|
1259
|
+
var position = aPosition * gfu.uOutputFrame.zw + gfu.uOutputFrame.xy;
|
|
1260
|
+
position.x = position.x * (2.0 / gfu.uOutputTexture.x) - 1.0;
|
|
1261
|
+
position.y = position.y * (2.0 * gfu.uOutputTexture.z / gfu.uOutputTexture.y) - gfu.uOutputTexture.z;
|
|
1262
|
+
return vec4<f32>(position, 0.0, 1.0);
|
|
1263
|
+
}
|
|
1264
|
+
fn filterTextureCoord(aPosition : vec2<f32>) -> vec2<f32> {
|
|
1265
|
+
return aPosition * (gfu.uOutputFrame.zw * gfu.uInputSize.zw);
|
|
1266
|
+
}
|
|
1267
|
+
@vertex
|
|
1268
|
+
fn mainVertex(
|
|
1269
|
+
@location(0) aPosition : vec2<f32>,
|
|
1270
|
+
) -> VSOutput {
|
|
1271
|
+
return VSOutput(
|
|
1272
|
+
filterVertexPosition(aPosition),
|
|
1273
|
+
filterTextureCoord(aPosition),
|
|
1274
|
+
);
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1277
|
+
fn hash(xIn: u32) -> u32 {
|
|
1278
|
+
var x = xIn;
|
|
1279
|
+
x = x ^ (x >> 16u); x = x * 0x7feb352du; x = x ^ (x >> 15u); x = x * 0x846ca68bu; x = x ^ (x >> 16u);
|
|
1280
|
+
return x;
|
|
1281
|
+
}
|
|
1282
|
+
fn lattice(p: vec2<i32>, k: u32) -> f32 {
|
|
1283
|
+
let h = hash(u32(p.x) + hash(u32(p.y) + hash(k)));
|
|
1284
|
+
return f32(h >> 8u) / 16777215.0;
|
|
1285
|
+
}
|
|
1286
|
+
fn valueNoise(q: vec2<f32>, k: u32) -> f32 {
|
|
1287
|
+
let i = floor(q);
|
|
1288
|
+
let f = fract(q);
|
|
1289
|
+
let u = f * f * (3.0 - 2.0 * f);
|
|
1290
|
+
let p = vec2<i32>(i);
|
|
1291
|
+
let a = lattice(p, k);
|
|
1292
|
+
let b = lattice(p + vec2<i32>(1, 0), k);
|
|
1293
|
+
let c = lattice(p + vec2<i32>(0, 1), k);
|
|
1294
|
+
let d = lattice(p + vec2<i32>(1, 1), k);
|
|
1295
|
+
return mix(mix(a, b, u.x), mix(c, d, u.x), u.y);
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
@fragment
|
|
1299
|
+
fn mainFragment(@location(0) uv : vec2<f32>) -> @location(0) vec4<f32> {
|
|
1300
|
+
let pos = uv * gfu.uInputSize.xy;
|
|
1301
|
+
var off = vec2<f32>(0.0);
|
|
1302
|
+
if (warpUniforms.uMode < 0.5) {
|
|
1303
|
+
let phase = dot(pos, vec2<f32>(cos(warpUniforms.uAngle), sin(warpUniforms.uAngle))) / warpUniforms.uScale - warpUniforms.uSpeed * warpUniforms.uTime;
|
|
1304
|
+
let s = warpUniforms.uStrength * sin(6.28318530718 * phase);
|
|
1305
|
+
off = vec2<f32>(-sin(warpUniforms.uAngle), cos(warpUniforms.uAngle)) * s;
|
|
1306
|
+
} else {
|
|
1307
|
+
let k = hash(u32(warpUniforms.uSeed));
|
|
1308
|
+
let p = vec2<f32>(pos.x / warpUniforms.uScale, pos.y / warpUniforms.uScale - warpUniforms.uSpeed * warpUniforms.uTime);
|
|
1309
|
+
off = warpUniforms.uStrength * 2.0 * vec2<f32>(valueNoise(p, k) - 0.5, valueNoise(p + vec2<f32>(37.2, 17.8), k) - 0.5);
|
|
1310
|
+
}
|
|
1311
|
+
let suv = clamp(uv + off * gfu.uInputSize.zw, gfu.uInputClamp.xy, gfu.uInputClamp.zw);
|
|
1312
|
+
return textureSampleLevel(uTexture, uSampler, suv, 0.0);
|
|
1313
|
+
}`;
|
|
1314
|
+
var WarpFilter = class extends PIXI.Filter {
|
|
1315
|
+
constructor(options = {}) {
|
|
1316
|
+
chunkTWZNOUM7_cjs.warnUnknownOptions("warp filter", options, OPTION_KEYS);
|
|
1317
|
+
let { kind = "wave", strength = 6, scale = 80, speed = 0.5, angle = 0, seed = 0 } = options;
|
|
1318
|
+
if (!WARP_KINDS.includes(kind)) {
|
|
1319
|
+
const guess = chunkTWZNOUM7_cjs.suggestName(String(kind), WARP_KINDS);
|
|
1320
|
+
console.warn(`pixi-effects: warp: kind ${JSON.stringify(kind)} is not supported${guess ? `; did you mean "${guess}"?` : ""} (use ${WARP_KINDS.join(" or ")}); wave is used`);
|
|
1321
|
+
kind = "wave";
|
|
1322
|
+
}
|
|
1323
|
+
if (!(strength >= 0 && strength <= 200)) {
|
|
1324
|
+
console.warn(`pixi-effects: warp: strength ${strength} is not a number from 0 to 200: it is the largest shift in pixels (8 is a clear ripple); ${strength > 200 ? "200" : "0"} is used`);
|
|
1325
|
+
strength = strength > 200 ? 200 : 0;
|
|
1326
|
+
}
|
|
1327
|
+
if (!(seed >= 0)) {
|
|
1328
|
+
console.warn(`pixi-effects: warp: seed ${seed} must be 0 or more (an integer that picks the haze pattern); 0 is used`);
|
|
1329
|
+
seed = 0;
|
|
1330
|
+
}
|
|
1331
|
+
if (!(scale > 0)) {
|
|
1332
|
+
console.warn(`pixi-effects: warp: scale ${scale} must be above 0: it is the wavelength in pixels (80 is the default); 1 is used`);
|
|
1333
|
+
scale = 1;
|
|
1334
|
+
}
|
|
1335
|
+
super({
|
|
1336
|
+
glProgram: PIXI.GlProgram.from({ vertex: GL_VERTEX2, fragment: GL_FRAGMENT3, name: "warp-filter" }),
|
|
1337
|
+
gpuProgram: PIXI.GpuProgram.from({ vertex: { source: WGSL_SOURCE3, entryPoint: "mainVertex" }, fragment: { source: WGSL_SOURCE3, entryPoint: "mainFragment" } }),
|
|
1338
|
+
resources: {
|
|
1339
|
+
warpUniforms: new PIXI.UniformGroup({
|
|
1340
|
+
uStrength: { value: strength, type: "f32" },
|
|
1341
|
+
uScale: { value: scale, type: "f32" },
|
|
1342
|
+
uSpeed: { value: speed, type: "f32" },
|
|
1343
|
+
uAngle: { value: angle * DEG, type: "f32" },
|
|
1344
|
+
uSeed: { value: Math.floor(seed), type: "f32" },
|
|
1345
|
+
uMode: { value: kind === "haze" ? 1 : 0, type: "f32" },
|
|
1346
|
+
uTime: { value: 0, type: "f32" }
|
|
1347
|
+
})
|
|
1348
|
+
}
|
|
1349
|
+
});
|
|
1350
|
+
this.padding = Math.ceil(strength);
|
|
1351
|
+
}
|
|
1352
|
+
get u() {
|
|
1353
|
+
return this.resources.warpUniforms.uniforms;
|
|
1354
|
+
}
|
|
1355
|
+
get kind() {
|
|
1356
|
+
return this.u.uMode === 1 ? "haze" : "wave";
|
|
1357
|
+
}
|
|
1358
|
+
set kind(v) {
|
|
1359
|
+
this.u.uMode = v === "haze" ? 1 : 0;
|
|
1360
|
+
}
|
|
1361
|
+
get strength() {
|
|
1362
|
+
return this.u.uStrength;
|
|
1363
|
+
}
|
|
1364
|
+
set strength(v) {
|
|
1365
|
+
this.u.uStrength = v;
|
|
1366
|
+
this.padding = Math.ceil(Math.max(0, v));
|
|
1367
|
+
}
|
|
1368
|
+
get scale() {
|
|
1369
|
+
return this.u.uScale;
|
|
1370
|
+
}
|
|
1371
|
+
set scale(v) {
|
|
1372
|
+
this.u.uScale = Math.max(v, 1e-3);
|
|
1373
|
+
}
|
|
1374
|
+
get speed() {
|
|
1375
|
+
return this.u.uSpeed;
|
|
1376
|
+
}
|
|
1377
|
+
set speed(v) {
|
|
1378
|
+
this.u.uSpeed = v;
|
|
1379
|
+
}
|
|
1380
|
+
get angle() {
|
|
1381
|
+
return this.u.uAngle / DEG;
|
|
1382
|
+
}
|
|
1383
|
+
set angle(v) {
|
|
1384
|
+
this.u.uAngle = v * DEG;
|
|
1385
|
+
}
|
|
1386
|
+
get seed() {
|
|
1387
|
+
return this.u.uSeed;
|
|
1388
|
+
}
|
|
1389
|
+
set seed(v) {
|
|
1390
|
+
this.u.uSeed = v >= 0 ? Math.floor(v) : 0;
|
|
1391
|
+
}
|
|
1392
|
+
/** The movie calls this with the time (s) of the frame it is about to draw. */
|
|
1393
|
+
setTime(t) {
|
|
1394
|
+
this.u.uTime = t;
|
|
1395
|
+
}
|
|
1396
|
+
};
|
|
1169
1397
|
|
|
1170
1398
|
// src/filters/named.ts
|
|
1171
1399
|
var CORE = { blur: "BlurFilter", noise: "NoiseFilter", alpha: "AlphaFilter" };
|
|
1172
|
-
var CORE_TYPES = [...Object.keys(CORE), "colorMatrix", "grain"];
|
|
1400
|
+
var CORE_TYPES = [...Object.keys(CORE), "colorMatrix", "grain", "warp"];
|
|
1173
1401
|
var LIBRARY_TYPES = [
|
|
1174
1402
|
"adjustment",
|
|
1175
1403
|
"advancedBloom",
|
|
@@ -1219,7 +1447,7 @@ function isNamedFilterType(t) {
|
|
|
1219
1447
|
return !NOT_NAMED.has(t);
|
|
1220
1448
|
}
|
|
1221
1449
|
function unknownType(t) {
|
|
1222
|
-
const guess =
|
|
1450
|
+
const guess = chunkTWZNOUM7_cjs.suggestName(t, FILTER_TYPES);
|
|
1223
1451
|
return new Error(`pixi-effects: unknown filter type "${t}"${guess ? ` \u2014 did you mean "${guess}"?` : ""} (valid: ${[...FILTER_TYPES, "chromaKey", "custom"].join(", ")})`);
|
|
1224
1452
|
}
|
|
1225
1453
|
var library = null;
|
|
@@ -1268,7 +1496,7 @@ function colorMatrix(params) {
|
|
|
1268
1496
|
const preset = params.preset;
|
|
1269
1497
|
if (preset !== void 0) {
|
|
1270
1498
|
if (!MATRIX_PRESETS.includes(preset)) {
|
|
1271
|
-
const guess =
|
|
1499
|
+
const guess = chunkTWZNOUM7_cjs.suggestName(preset, MATRIX_PRESETS);
|
|
1272
1500
|
throw new Error(`pixi-effects: colorMatrix preset "${preset}" is not one of ${MATRIX_PRESETS.join(", ")}${guess ? ` \u2014 did you mean "${guess}"?` : ""}`);
|
|
1273
1501
|
}
|
|
1274
1502
|
f[preset === "grayscale" ? "desaturate" : preset].call(f);
|
|
@@ -1287,6 +1515,7 @@ function colorGradientParams(params) {
|
|
|
1287
1515
|
function createNamedFilter(type, params) {
|
|
1288
1516
|
if (lower(type) === "colormatrix") return colorMatrix(params);
|
|
1289
1517
|
if (lower(type) === "grain") return new GrainFilter(params);
|
|
1518
|
+
if (lower(type) === "warp") return new WarpFilter(params);
|
|
1290
1519
|
const core = Object.entries(CORE).find(([k]) => lower(k) === lower(type));
|
|
1291
1520
|
if (core) return new PIXI__namespace[core[1]](params);
|
|
1292
1521
|
if (!isLibraryType(type)) throw unknownType(type);
|
|
@@ -1542,7 +1771,7 @@ function clockTable(remap, prop, duration, at, scope, to) {
|
|
|
1542
1771
|
}
|
|
1543
1772
|
|
|
1544
1773
|
// src/space/math.ts
|
|
1545
|
-
var
|
|
1774
|
+
var DEG2 = Math.PI / 180;
|
|
1546
1775
|
var DEFAULT_FOV = 40;
|
|
1547
1776
|
var MIN_FOV = 1;
|
|
1548
1777
|
var MAX_FOV = 179;
|
|
@@ -1552,7 +1781,7 @@ function clampFov(fov) {
|
|
|
1552
1781
|
return Math.min(MAX_FOV, Math.max(MIN_FOV, fov));
|
|
1553
1782
|
}
|
|
1554
1783
|
function homeDistance(compHeight, fovDeg) {
|
|
1555
|
-
return compHeight / 2 / Math.tan(clampFov(fovDeg) *
|
|
1784
|
+
return compHeight / 2 / Math.tan(clampFov(fovDeg) * DEG2 / 2);
|
|
1556
1785
|
}
|
|
1557
1786
|
function homeCamera(compW, compH, fov = DEFAULT_FOV) {
|
|
1558
1787
|
return {
|
|
@@ -1606,7 +1835,7 @@ function cameraBasis(cam, compW, compH) {
|
|
|
1606
1835
|
fx,
|
|
1607
1836
|
fy,
|
|
1608
1837
|
fz,
|
|
1609
|
-
focal: compH / 2 / Math.tan(clampFov(cam.fov) *
|
|
1838
|
+
focal: compH / 2 / Math.tan(clampFov(cam.fov) * DEG2 / 2),
|
|
1610
1839
|
halfW: compW / 2,
|
|
1611
1840
|
halfH: compH / 2
|
|
1612
1841
|
};
|
|
@@ -1708,7 +1937,7 @@ function focusProblems(camera, siblings) {
|
|
|
1708
1937
|
said.add(name);
|
|
1709
1938
|
const same = siblings.filter((s) => s.name === name);
|
|
1710
1939
|
const hit = same.find((s) => s.threeD) ?? same[0];
|
|
1711
|
-
if (!hit) out.push({ kind: "missing", name, hint:
|
|
1940
|
+
if (!hit) out.push({ kind: "missing", name, hint: chunkTWZNOUM7_cjs.suggestName(name, threeD) });
|
|
1712
1941
|
else if (!hit.threeD) out.push({ kind: "not-threeD", name });
|
|
1713
1942
|
else {
|
|
1714
1943
|
if (same.length > 1) out.push({ kind: "duplicate", name, count: same.length });
|
|
@@ -1726,6 +1955,9 @@ var CameraSequence = class extends Sequence {
|
|
|
1726
1955
|
warnedAperture = false;
|
|
1727
1956
|
/** True when the camera writes `focus` or `aperture` anywhere: depth of field is on. */
|
|
1728
1957
|
dof = false;
|
|
1958
|
+
/** True when the camera writes any fog key anywhere: depth fog is on (nothing is made for a camera without fog). */
|
|
1959
|
+
fog = false;
|
|
1960
|
+
fogC = null;
|
|
1729
1961
|
zOfName = null;
|
|
1730
1962
|
layerNames = /* @__PURE__ */ new Set();
|
|
1731
1963
|
async build() {
|
|
@@ -1747,10 +1979,15 @@ var CameraSequence = class extends Sequence {
|
|
|
1747
1979
|
carrier.aperture = DEFAULT_APERTURE;
|
|
1748
1980
|
carrier.offsetX = carrier.offsetY = carrier.offsetZ = 0;
|
|
1749
1981
|
carrier.lookOffsetX = carrier.lookOffsetY = carrier.lookOffsetZ = 0;
|
|
1982
|
+
carrier.fogNear = home.z;
|
|
1983
|
+
carrier.fogFar = home.z * 3;
|
|
1984
|
+
carrier.fogColor = "#000000";
|
|
1985
|
+
carrier.fogAmount = 1;
|
|
1750
1986
|
this.target = carrier;
|
|
1751
|
-
const keys =
|
|
1987
|
+
const keys = chunkECA2WNRX_cjs.collectPropKeys(this.spec);
|
|
1752
1988
|
this.autoZ = !keys.has("z");
|
|
1753
1989
|
this.dof = keys.has("focus") || keys.has("aperture");
|
|
1990
|
+
this.fog = keys.has("fogNear") || keys.has("fogFar") || keys.has("fogColor") || keys.has("fogAmount");
|
|
1754
1991
|
}
|
|
1755
1992
|
/** The aperture to use now: off unless depth of field is on and the value is a number of 0 or more (said once if it is not). */
|
|
1756
1993
|
apertureNow(a) {
|
|
@@ -1798,6 +2035,20 @@ var CameraSequence = class extends Sequence {
|
|
|
1798
2035
|
aperture: this.apertureNow(c.aperture)
|
|
1799
2036
|
};
|
|
1800
2037
|
}
|
|
2038
|
+
/** The fog now (colour as 0..1 channels, distances, 0..1 amount), or null when the camera writes no fog key. */
|
|
2039
|
+
fogState() {
|
|
2040
|
+
if (!this.fog) return null;
|
|
2041
|
+
const c = this.target;
|
|
2042
|
+
const fc = this.fogC ??= new PIXI.Color();
|
|
2043
|
+
try {
|
|
2044
|
+
fc.setValue(c.fogColor);
|
|
2045
|
+
} catch {
|
|
2046
|
+
fc.setValue(0);
|
|
2047
|
+
}
|
|
2048
|
+
const [r, g, b] = fc.toArray();
|
|
2049
|
+
const amount = Number.isFinite(c.fogAmount) ? Math.min(1, Math.max(0, c.fogAmount)) : 1;
|
|
2050
|
+
return { r, g, b, near: c.fogNear, far: c.fogFar, amount };
|
|
2051
|
+
}
|
|
1801
2052
|
/** Lifespan on the global timeline (valid after bindTimeline). */
|
|
1802
2053
|
window() {
|
|
1803
2054
|
const start = this.absoluteStart ?? this.at;
|
|
@@ -1805,6 +2056,160 @@ var CameraSequence = class extends Sequence {
|
|
|
1805
2056
|
}
|
|
1806
2057
|
};
|
|
1807
2058
|
|
|
2059
|
+
// src/space/lighting.ts
|
|
2060
|
+
var LIGHT_KINDS = ["ambient", "point", "spot", "parallel"];
|
|
2061
|
+
var FALLOFFS = ["none", "smooth", "inverseSquare"];
|
|
2062
|
+
var LIGHT_PROPS = ["x", "y", "z", "lookAtX", "lookAtY", "lookAtZ", "intensity", "color", "coneAngle", "coneFeather", "radius", "falloffDistance", "shadowDarkness", "shadowDiffusion"];
|
|
2063
|
+
var MAX_LIGHTS = 8;
|
|
2064
|
+
var MAX_CASTERS = 4;
|
|
2065
|
+
var SHADOW_TAPS = 16;
|
|
2066
|
+
var FALLOFF_ID = { none: 0, smooth: 1, inverseSquare: 2 };
|
|
2067
|
+
var KIND_ID = { point: 1, spot: 2, parallel: 3 };
|
|
2068
|
+
function smoothstep(e0, e1, x) {
|
|
2069
|
+
const t = Math.min(1, Math.max(0, (x - e0) / (e1 - e0)));
|
|
2070
|
+
return t * t * (3 - 2 * t);
|
|
2071
|
+
}
|
|
2072
|
+
var DEG3 = Math.PI / 180;
|
|
2073
|
+
function norm(v) {
|
|
2074
|
+
const l = Math.hypot(v.x, v.y, v.z) || 1;
|
|
2075
|
+
return { x: v.x / l, y: v.y / l, z: v.z / l };
|
|
2076
|
+
}
|
|
2077
|
+
var dot = (a, b) => a.x * b.x + a.y * b.y + a.z * b.z;
|
|
2078
|
+
var sub = (a, b) => ({ x: a.x - b.x, y: a.y - b.y, z: a.z - b.z });
|
|
2079
|
+
function coneCos(l) {
|
|
2080
|
+
const half = Math.min(179, Math.max(0, l.coneAngle)) * DEG3 / 2;
|
|
2081
|
+
const inner = half * (1 - Math.min(1, Math.max(0, l.coneFeather)));
|
|
2082
|
+
const cosOuter = Math.cos(half);
|
|
2083
|
+
const cosInner = Math.max(Math.cos(inner), cosOuter + 1e-4);
|
|
2084
|
+
return { cosOuter, cosInner };
|
|
2085
|
+
}
|
|
2086
|
+
function packLights(lights) {
|
|
2087
|
+
const pos = new Float32Array(4 * MAX_LIGHTS), dir = new Float32Array(4 * MAX_LIGHTS), col = new Float32Array(4 * MAX_LIGHTS), fall = new Float32Array(4 * MAX_LIGHTS), shadow = new Float32Array(4 * MAX_LIGHTS);
|
|
2088
|
+
const ambient = [0, 0, 0];
|
|
2089
|
+
let n = 0;
|
|
2090
|
+
for (const l of lights) {
|
|
2091
|
+
if (l.kind === "ambient") {
|
|
2092
|
+
ambient[0] += l.r * l.intensity;
|
|
2093
|
+
ambient[1] += l.g * l.intensity;
|
|
2094
|
+
ambient[2] += l.b * l.intensity;
|
|
2095
|
+
continue;
|
|
2096
|
+
}
|
|
2097
|
+
if (n >= MAX_LIGHTS) continue;
|
|
2098
|
+
const d = norm({ x: l.lookAtX - l.x, y: l.lookAtY - l.y, z: l.lookAtZ - l.z });
|
|
2099
|
+
const { cosOuter, cosInner } = coneCos(l);
|
|
2100
|
+
pos.set([l.x, l.y, l.z, KIND_ID[l.kind]], 4 * n);
|
|
2101
|
+
dir.set([d.x, d.y, d.z, cosOuter], 4 * n);
|
|
2102
|
+
col.set([l.r * l.intensity, l.g * l.intensity, l.b * l.intensity, cosInner], 4 * n);
|
|
2103
|
+
fall.set([FALLOFF_ID[l.falloff], l.radius, l.falloffDistance, l.castsShadows ? 1 : 0], 4 * n);
|
|
2104
|
+
shadow.set([l.castsShadows ? l.shadowDarkness : 0, l.shadowDiffusion, 0, 0], 4 * n);
|
|
2105
|
+
n++;
|
|
2106
|
+
}
|
|
2107
|
+
return { count: n, ambient, pos, dir, col, fall, shadow };
|
|
2108
|
+
}
|
|
2109
|
+
function shadeReference(p, n, cam, lights) {
|
|
2110
|
+
let N = norm(n);
|
|
2111
|
+
if (dot(N, sub(cam, p)) < 0) N = { x: -N.x, y: -N.y, z: -N.z };
|
|
2112
|
+
const out = [0, 0, 0];
|
|
2113
|
+
for (const l of lights) {
|
|
2114
|
+
if (l.kind === "ambient") {
|
|
2115
|
+
out[0] += l.r * l.intensity;
|
|
2116
|
+
out[1] += l.g * l.intensity;
|
|
2117
|
+
out[2] += l.b * l.intensity;
|
|
2118
|
+
continue;
|
|
2119
|
+
}
|
|
2120
|
+
const dirLA = norm({ x: l.lookAtX - l.x, y: l.lookAtY - l.y, z: l.lookAtZ - l.z });
|
|
2121
|
+
let L;
|
|
2122
|
+
let dist = 0;
|
|
2123
|
+
if (l.kind === "parallel") L = { x: -dirLA.x, y: -dirLA.y, z: -dirLA.z };
|
|
2124
|
+
else {
|
|
2125
|
+
const d = sub({ x: l.x, y: l.y, z: l.z }, p);
|
|
2126
|
+
dist = Math.hypot(d.x, d.y, d.z);
|
|
2127
|
+
L = { x: d.x / dist, y: d.y / dist, z: d.z / dist };
|
|
2128
|
+
}
|
|
2129
|
+
const ndl = Math.max(0, dot(N, L));
|
|
2130
|
+
let att = 1;
|
|
2131
|
+
if (l.kind !== "parallel") {
|
|
2132
|
+
if (l.falloff === "smooth") att = 1 - smoothstep(l.radius, l.radius + Math.max(l.falloffDistance, 1e-3), dist);
|
|
2133
|
+
else if (l.falloff === "inverseSquare") att = Math.min(1, l.radius * l.radius / Math.max(dist * dist, 1e-6));
|
|
2134
|
+
}
|
|
2135
|
+
let cone = 1;
|
|
2136
|
+
if (l.kind === "spot") {
|
|
2137
|
+
const { cosOuter, cosInner } = coneCos(l);
|
|
2138
|
+
cone = smoothstep(cosOuter, cosInner, -dot(L, dirLA));
|
|
2139
|
+
}
|
|
2140
|
+
const k = l.intensity * ndl * att * cone;
|
|
2141
|
+
out[0] += l.r * k;
|
|
2142
|
+
out[1] += l.g * k;
|
|
2143
|
+
out[2] += l.b * k;
|
|
2144
|
+
}
|
|
2145
|
+
return out;
|
|
2146
|
+
}
|
|
2147
|
+
function lightLevel(frame, cam, lights) {
|
|
2148
|
+
const mid = { x: frame.o.x + 0.5 * frame.u.x + 0.5 * frame.v.x, y: frame.o.y + 0.5 * frame.u.y + 0.5 * frame.v.y, z: frame.o.z + 0.5 * frame.u.z + 0.5 * frame.v.z };
|
|
2149
|
+
const n = { x: frame.u.y * frame.v.z - frame.u.z * frame.v.y, y: frame.u.z * frame.v.x - frame.u.x * frame.v.z, z: frame.u.x * frame.v.y - frame.u.y * frame.v.x };
|
|
2150
|
+
const m = shadeReference(mid, n, cam, lights);
|
|
2151
|
+
return 0.2126 * m[0] + 0.7152 * m[1] + 0.0722 * m[2];
|
|
2152
|
+
}
|
|
2153
|
+
var LightSequence = class extends Sequence {
|
|
2154
|
+
color = new PIXI.Color();
|
|
2155
|
+
async build() {
|
|
2156
|
+
const w = this.parent?.width ?? this.root.width;
|
|
2157
|
+
const h = this.parent?.height ?? this.root.height;
|
|
2158
|
+
if (this.duration === void 0) this.duration = this.parent?.duration ?? this.root.duration;
|
|
2159
|
+
const c = new PIXI.Container();
|
|
2160
|
+
c.x = w * 0.3;
|
|
2161
|
+
c.y = h * 0.2;
|
|
2162
|
+
c.z = homeDistance(h, 40) * 0.6;
|
|
2163
|
+
c.lookAtX = w / 2;
|
|
2164
|
+
c.lookAtY = h / 2;
|
|
2165
|
+
c.lookAtZ = 0;
|
|
2166
|
+
c.intensity = 1;
|
|
2167
|
+
c.color = "#ffffff";
|
|
2168
|
+
c.coneAngle = 90;
|
|
2169
|
+
c.coneFeather = 0.5;
|
|
2170
|
+
c.radius = 500;
|
|
2171
|
+
c.falloffDistance = 500;
|
|
2172
|
+
c.shadowDarkness = 1;
|
|
2173
|
+
c.shadowDiffusion = 0;
|
|
2174
|
+
this.target = c;
|
|
2175
|
+
}
|
|
2176
|
+
state() {
|
|
2177
|
+
const c = this.target;
|
|
2178
|
+
try {
|
|
2179
|
+
this.color.setValue(c.color);
|
|
2180
|
+
} catch {
|
|
2181
|
+
this.color.setValue(16777215);
|
|
2182
|
+
}
|
|
2183
|
+
const [r, g, b] = this.color.toArray();
|
|
2184
|
+
return {
|
|
2185
|
+
// a kind or falloff nobody knows is the default the warning promises (the shader must never see an unknown id)
|
|
2186
|
+
kind: LIGHT_KINDS.includes(this.spec.kind) ? this.spec.kind : "point",
|
|
2187
|
+
x: c.x,
|
|
2188
|
+
y: c.y,
|
|
2189
|
+
z: c.z,
|
|
2190
|
+
lookAtX: c.lookAtX,
|
|
2191
|
+
lookAtY: c.lookAtY,
|
|
2192
|
+
lookAtZ: c.lookAtZ,
|
|
2193
|
+
r,
|
|
2194
|
+
g,
|
|
2195
|
+
b,
|
|
2196
|
+
intensity: Number.isFinite(c.intensity) ? Math.max(0, c.intensity) : 1,
|
|
2197
|
+
coneAngle: c.coneAngle,
|
|
2198
|
+
coneFeather: c.coneFeather,
|
|
2199
|
+
falloff: FALLOFFS.includes(this.spec.falloff) ? this.spec.falloff : "none",
|
|
2200
|
+
radius: c.radius,
|
|
2201
|
+
falloffDistance: c.falloffDistance,
|
|
2202
|
+
castsShadows: !!this.spec.castsShadows,
|
|
2203
|
+
shadowDarkness: Math.min(1, Math.max(0, c.shadowDarkness)),
|
|
2204
|
+
shadowDiffusion: Math.max(0, c.shadowDiffusion)
|
|
2205
|
+
};
|
|
2206
|
+
}
|
|
2207
|
+
window() {
|
|
2208
|
+
const start = this.absoluteStart ?? this.at;
|
|
2209
|
+
return { start, end: start + (this.duration ?? 0) };
|
|
2210
|
+
}
|
|
2211
|
+
};
|
|
2212
|
+
|
|
1808
2213
|
// src/core/revertibleSet.ts
|
|
1809
2214
|
function revertibleSet(timeline, at, read, write, value) {
|
|
1810
2215
|
let p = 0;
|
|
@@ -2164,7 +2569,7 @@ function validateGradientKeyframes(spec, who, warn = (m) => console.warn(m), kin
|
|
|
2164
2569
|
const p = value;
|
|
2165
2570
|
for (const k of Object.keys(p)) {
|
|
2166
2571
|
if (PATCH_KEYS.includes(k)) continue;
|
|
2167
|
-
const guess =
|
|
2572
|
+
const guess = chunkTWZNOUM7_cjs.suggestName(k, PATCH_KEYS.filter((x) => x !== "type"));
|
|
2168
2573
|
say(`fillGradient.${k} is not a gradient property${guess ? ` \u2014 did you mean "${guess}"?` : ""} (valid: ${PATCH_KEYS.join(", ")}); it is ignored`);
|
|
2169
2574
|
}
|
|
2170
2575
|
if (p.type !== void 0 && start && p.type !== start.type) say("fillGradient.type cannot change over time (linear <-> radial); it is ignored");
|
|
@@ -2174,8 +2579,8 @@ function validateGradientKeyframes(spec, who, warn = (m) => console.warn(m), kin
|
|
|
2174
2579
|
}
|
|
2175
2580
|
} else if (/^fillGradient\./i.test(key) || /^gradient/i.test(key)) {
|
|
2176
2581
|
const tail = key.replace(/^fillGradient\./i, "").replace(/^gradient/i, "");
|
|
2177
|
-
const
|
|
2178
|
-
say(`"${key}" is not an animatable property: write fillGradient: { ${PATCH_KEYS.includes(
|
|
2582
|
+
const sub2 = tail ? tail[0].toLowerCase() + tail.slice(1) : "angle";
|
|
2583
|
+
say(`"${key}" is not an animatable property: write fillGradient: { ${PATCH_KEYS.includes(sub2) ? sub2 : "angle"} } (the whole gradient is one object) in the keyframe's to / from / set`);
|
|
2179
2584
|
}
|
|
2180
2585
|
}
|
|
2181
2586
|
}
|
|
@@ -2372,7 +2777,7 @@ var TextSequence = class extends Sequence {
|
|
|
2372
2777
|
this.intrinsicWidth = text.width;
|
|
2373
2778
|
this.intrinsicHeight = text.height;
|
|
2374
2779
|
}
|
|
2375
|
-
validateGradientKeyframes(this.spec,
|
|
2780
|
+
validateGradientKeyframes(this.spec, chunkECA2WNRX_cjs.describeLayer(this.spec), void 0, "text");
|
|
2376
2781
|
const gradientSpec = this.spec.fillGradient ?? initialProps.fillGradient;
|
|
2377
2782
|
if (gradientSpec) {
|
|
2378
2783
|
this._grad = { grad: gradStateFrom(gradientSpec) };
|
|
@@ -2408,7 +2813,7 @@ var TextSequence = class extends Sequence {
|
|
|
2408
2813
|
bindTextKeyframes(timeline, keyframes, this.duration, origin, () => this._template, (t) => {
|
|
2409
2814
|
this._template = t;
|
|
2410
2815
|
refresh();
|
|
2411
|
-
},
|
|
2816
|
+
}, chunkECA2WNRX_cjs.describeLayer(this.spec));
|
|
2412
2817
|
}
|
|
2413
2818
|
};
|
|
2414
2819
|
function runSuperWithStrippedSpec(inst, strippedSpec, timeline, offset) {
|
|
@@ -2553,16 +2958,16 @@ var AudioSequence = class extends Sequence {
|
|
|
2553
2958
|
const playable = this._remap && this._remap.timeKfs.length > 0 ? Infinity : (data.duration ?? Infinity) / constant;
|
|
2554
2959
|
if (!spec.loop && Number.isFinite(playable) && this.duration > playable + 0.05) {
|
|
2555
2960
|
console.warn(
|
|
2556
|
-
`pixi-effects: ${
|
|
2961
|
+
`pixi-effects: ${chunkECA2WNRX_cjs.describeLayer(spec)}: audio asset "${spec.asset}" plays for ${playable.toFixed(1)}s (${data.duration.toFixed(1)}s at speed ${constant}) but the layer lasts ${this.duration.toFixed(1)}s, so it goes silent after ${playable.toFixed(1)}s. Add loop: true, or shorten the layer's duration.`
|
|
2557
2962
|
);
|
|
2558
2963
|
}
|
|
2559
2964
|
}
|
|
2560
2965
|
async _buildSfx(spec) {
|
|
2561
|
-
const who =
|
|
2966
|
+
const who = chunkECA2WNRX_cjs.describeLayer(spec);
|
|
2562
2967
|
const raw = spec;
|
|
2563
2968
|
if (raw.asset !== void 0) console.warn(`pixi-effects: ${who}: has both asset and sfx \u2014 the sfx plays; remove one`);
|
|
2564
2969
|
if (raw.loop) console.warn(`pixi-effects: ${who}: loop has no effect on an sfx \u2014 to repeat it, add one audio layer per hit (a JS loop)`);
|
|
2565
|
-
const { resolveSfx, renderSfx, sfxKey } = await import('./sfx-
|
|
2970
|
+
const { resolveSfx, renderSfx, sfxKey } = await import('./sfx-2O6UQEUP.cjs');
|
|
2566
2971
|
const sfx = resolveSfx(spec.sfx, spec.duration, who);
|
|
2567
2972
|
if (!sfx) return;
|
|
2568
2973
|
this.duration = sfx.length;
|
|
@@ -2577,11 +2982,11 @@ var AudioSequence = class extends Sequence {
|
|
|
2577
2982
|
});
|
|
2578
2983
|
}
|
|
2579
2984
|
async _buildMusic(spec) {
|
|
2580
|
-
const who =
|
|
2985
|
+
const who = chunkECA2WNRX_cjs.describeLayer(spec);
|
|
2581
2986
|
const raw = spec;
|
|
2582
2987
|
if (raw.asset !== void 0) console.warn(`pixi-effects: ${who}: has both asset and music \u2014 the music plays; remove one`);
|
|
2583
2988
|
if (raw.sfx !== void 0) console.warn(`pixi-effects: ${who}: has both sfx and music \u2014 the music plays; remove one`);
|
|
2584
|
-
const { resolveMusic, renderMusic, musicLength, musicKey } = await import('./music-
|
|
2989
|
+
const { resolveMusic, renderMusic, musicLength, musicKey } = await import('./music-KB7YZLHP.cjs');
|
|
2585
2990
|
const music = resolveMusic(spec.music, who);
|
|
2586
2991
|
if (!music) return;
|
|
2587
2992
|
const natural = musicLength(music);
|
|
@@ -2611,7 +3016,7 @@ var AudioSequence = class extends Sequence {
|
|
|
2611
3016
|
out.push({
|
|
2612
3017
|
...sourceMap ? { sourceMap } : {},
|
|
2613
3018
|
...this._audioBuffer ? { buffer: this._audioBuffer } : { synth: this._synth },
|
|
2614
|
-
layer:
|
|
3019
|
+
layer: chunkECA2WNRX_cjs.describeLayer(this.spec),
|
|
2615
3020
|
source: this._source,
|
|
2616
3021
|
loop: !this._synth && !!this.spec.loop,
|
|
2617
3022
|
start: t0,
|
|
@@ -2831,7 +3236,7 @@ var VideoSequence = class extends Sequence {
|
|
|
2831
3236
|
out.push({
|
|
2832
3237
|
...sourceMap ? { sourceMap } : {},
|
|
2833
3238
|
buffer: this._audioBuffer,
|
|
2834
|
-
layer:
|
|
3239
|
+
layer: chunkECA2WNRX_cjs.describeLayer(this.spec),
|
|
2835
3240
|
source: `video "${this.spec.asset}"`,
|
|
2836
3241
|
loop: !!this.spec.loop,
|
|
2837
3242
|
start: baseTime + this.at,
|
|
@@ -3099,20 +3504,20 @@ var ShapeSequence = class extends Sequence {
|
|
|
3099
3504
|
for (const k of geomKeys) this._liveKeys.add(k);
|
|
3100
3505
|
seedGeometry(this._state, this.spec, scope);
|
|
3101
3506
|
seedStyle(this._state, this.spec.initial ?? {}, scope);
|
|
3102
|
-
seedStrokeStyle(this._state, this.spec, this.spec.initial ?? {},
|
|
3507
|
+
seedStrokeStyle(this._state, this.spec, this.spec.initial ?? {}, chunkECA2WNRX_cjs.describeLayer(this.spec));
|
|
3103
3508
|
if (this.spec.shape === "arc") {
|
|
3104
3509
|
this._state.startAngle ??= 0;
|
|
3105
3510
|
this._state.endAngle ??= 360;
|
|
3106
3511
|
const top = this.spec, ini = this.spec.initial ?? {};
|
|
3107
3512
|
if ("trimStart" in top || "trimEnd" in top || "trimStart" in ini || "trimEnd" in ini) {
|
|
3108
|
-
console.warn(`pixi-effects: ${
|
|
3513
|
+
console.warn(`pixi-effects: ${chunkECA2WNRX_cjs.describeLayer(this.spec)}: trimStart / trimEnd do not apply to an arc: animate its endAngle (and startAngle) instead`);
|
|
3109
3514
|
}
|
|
3110
3515
|
} else {
|
|
3111
3516
|
this._state.trimStart ??= 0;
|
|
3112
3517
|
this._state.trimEnd ??= 1;
|
|
3113
3518
|
}
|
|
3114
3519
|
const gradientSpec = this.spec.fillGradient ?? this.spec.initial?.fillGradient;
|
|
3115
|
-
validateGradientKeyframes(this.spec,
|
|
3520
|
+
validateGradientKeyframes(this.spec, chunkECA2WNRX_cjs.describeLayer(this.spec));
|
|
3116
3521
|
if (gradientSpec) {
|
|
3117
3522
|
if (hasGradientKeys(this.spec.keyframes)) {
|
|
3118
3523
|
this._grad = { grad: gradStateFrom(gradientSpec) };
|
|
@@ -3154,9 +3559,9 @@ var ShapeSequence = class extends Sequence {
|
|
|
3154
3559
|
}
|
|
3155
3560
|
/** The prepared morph between `d` and `morphTo`, or null (and a warning when the spec asked for one that cannot work). */
|
|
3156
3561
|
_setupMorph() {
|
|
3157
|
-
const who =
|
|
3562
|
+
const who = chunkECA2WNRX_cjs.describeLayer(this.spec);
|
|
3158
3563
|
const top = this.spec;
|
|
3159
|
-
const wanted = this.spec.shape === "path" && (this._state.morph !== void 0 ||
|
|
3564
|
+
const wanted = this.spec.shape === "path" && (this._state.morph !== void 0 || chunkECA2WNRX_cjs.collectPropKeys(this.spec).has("morph"));
|
|
3160
3565
|
if (this.spec.shape !== "path") {
|
|
3161
3566
|
if ("morphTo" in top) console.warn(`pixi-effects: ${who}: morphTo only works on a path shape (shape: 'path'); ignored`);
|
|
3162
3567
|
return null;
|
|
@@ -3374,7 +3779,7 @@ function drawEllipseFromState(g, s) {
|
|
|
3374
3779
|
const ay = s.anchorY ?? 0.5;
|
|
3375
3780
|
g.ellipse((0.5 - ax) * 2 * rx, (0.5 - ay) * 2 * ry, rx, ry);
|
|
3376
3781
|
}
|
|
3377
|
-
var
|
|
3782
|
+
var DEG4 = Math.PI / 180;
|
|
3378
3783
|
function drawArcFromState(g, s) {
|
|
3379
3784
|
const r = s.radius ?? 0;
|
|
3380
3785
|
const ri = Math.max(0, Math.min(s.innerRadius ?? 0, r));
|
|
@@ -3389,7 +3794,7 @@ function drawArcFromState(g, s) {
|
|
|
3389
3794
|
}
|
|
3390
3795
|
endDeg = startDeg + Math.sign(endDeg - startDeg) * 359.999;
|
|
3391
3796
|
}
|
|
3392
|
-
const a0 = startDeg *
|
|
3797
|
+
const a0 = startDeg * DEG4, a1 = endDeg * DEG4;
|
|
3393
3798
|
const ccw = a1 < a0;
|
|
3394
3799
|
if (filled) g.moveTo(r * Math.cos(a0), r * Math.sin(a0));
|
|
3395
3800
|
g.arc(0, 0, r, a0, a1, ccw);
|
|
@@ -3571,11 +3976,396 @@ function numOrZero(v, scope) {
|
|
|
3571
3976
|
return 0;
|
|
3572
3977
|
}
|
|
3573
3978
|
|
|
3979
|
+
// src/core/glShared.ts
|
|
3980
|
+
var shared = null;
|
|
3981
|
+
var generation = 0;
|
|
3982
|
+
var refs = 0;
|
|
3983
|
+
var unavailable = false;
|
|
3984
|
+
function create() {
|
|
3985
|
+
if (typeof document === "undefined") return null;
|
|
3986
|
+
const canvas = document.createElement("canvas");
|
|
3987
|
+
const gl = canvas.getContext("webgl2", { alpha: true, premultipliedAlpha: true, preserveDrawingBuffer: true, antialias: false });
|
|
3988
|
+
if (!gl) return null;
|
|
3989
|
+
const made = { gl, canvas, generation: ++generation };
|
|
3990
|
+
canvas.addEventListener("webglcontextlost", (e) => {
|
|
3991
|
+
e.preventDefault();
|
|
3992
|
+
if (shared === made) shared = null;
|
|
3993
|
+
});
|
|
3994
|
+
return made;
|
|
3995
|
+
}
|
|
3996
|
+
function currentGl() {
|
|
3997
|
+
if (shared) return shared;
|
|
3998
|
+
if (unavailable) return null;
|
|
3999
|
+
shared = create();
|
|
4000
|
+
if (!shared) unavailable = true;
|
|
4001
|
+
return shared;
|
|
4002
|
+
}
|
|
4003
|
+
function acquireGl() {
|
|
4004
|
+
refs++;
|
|
4005
|
+
return currentGl();
|
|
4006
|
+
}
|
|
4007
|
+
function releaseGl() {
|
|
4008
|
+
refs = Math.max(0, refs - 1);
|
|
4009
|
+
if (refs === 0 && shared) {
|
|
4010
|
+
const lose = shared.gl.getExtension?.("WEBGL_lose_context");
|
|
4011
|
+
try {
|
|
4012
|
+
lose?.loseContext();
|
|
4013
|
+
} catch {
|
|
4014
|
+
}
|
|
4015
|
+
shared = null;
|
|
4016
|
+
}
|
|
4017
|
+
}
|
|
4018
|
+
|
|
4019
|
+
// src/core/shaderChecks.ts
|
|
4020
|
+
var SHADER_BUILTINS = ["iResolution", "iTime", "iFrame"];
|
|
4021
|
+
var SHADER_MISSING = ["iMouse", "iChannel0", "iChannel1", "iChannel2", "iChannel3", "iDate", "iTimeDelta", "iSampleRate"];
|
|
4022
|
+
var IDENT = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
4023
|
+
var HEX = /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
|
|
4024
|
+
var RESERVED = new Set(`attribute const uniform varying break continue do for while if else in out inout float int void bool true false discard return
|
|
4025
|
+
mat2 mat3 mat4 mat2x2 mat2x3 mat2x4 mat3x2 mat3x3 mat3x4 mat4x2 mat4x3 mat4x4 vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 uvec2 uvec3 uvec4 uint
|
|
4026
|
+
sampler2D sampler3D samplerCube sampler2DShadow samplerCubeShadow sampler2DArray sampler2DArrayShadow isampler2D isampler3D isamplerCube isampler2DArray
|
|
4027
|
+
usampler2D usampler3D usamplerCube usampler2DArray struct layout centroid flat smooth precision invariant highp mediump lowp
|
|
4028
|
+
sample patch subroutine common partition active asm class union enum typedef template this resource goto inline noinline public static extern external
|
|
4029
|
+
interface long short double half fixed unsigned superp input output hvec2 hvec3 hvec4 fvec2 fvec3 fvec4 dvec2 dvec3 dvec4 filter sizeof cast namespace using`.split(/\s+/));
|
|
4030
|
+
var isIdent = (name) => IDENT.test(name) && !name.startsWith("gl_") && !name.includes("__") && !RESERVED.has(name) && !SHADER_BUILTINS.includes(name);
|
|
4031
|
+
function uniformType(v) {
|
|
4032
|
+
if (typeof v === "number") return Number.isFinite(v) ? "float" : null;
|
|
4033
|
+
if (typeof v === "string") return HEX.test(v) ? "vec3" : null;
|
|
4034
|
+
if (Array.isArray(v) && v.length >= 2 && v.length <= 4 && v.every((n) => typeof n === "number" && Number.isFinite(n))) return `vec${v.length}`;
|
|
4035
|
+
return null;
|
|
4036
|
+
}
|
|
4037
|
+
function uniformFloats(v) {
|
|
4038
|
+
if (typeof v === "number") return [v];
|
|
4039
|
+
if (typeof v === "string") {
|
|
4040
|
+
const h = v.length === 4 ? v.slice(1).replace(/./g, (c) => c + c) : v.slice(1);
|
|
4041
|
+
return [0, 2, 4].map((i) => parseInt(h.slice(i, i + 2), 16) / 255);
|
|
4042
|
+
}
|
|
4043
|
+
return v.slice();
|
|
4044
|
+
}
|
|
4045
|
+
function uniformDecls(uniforms) {
|
|
4046
|
+
let out = "";
|
|
4047
|
+
for (const [name, v] of Object.entries(uniforms ?? {})) {
|
|
4048
|
+
const type = uniformType(v);
|
|
4049
|
+
if (type && isIdent(name)) out += `uniform ${type} ${name};
|
|
4050
|
+
`;
|
|
4051
|
+
}
|
|
4052
|
+
return out;
|
|
4053
|
+
}
|
|
4054
|
+
var HEAD = `#version 300 es
|
|
4055
|
+
#line 100001
|
|
4056
|
+
precision highp float;
|
|
4057
|
+
precision highp int;
|
|
4058
|
+
uniform vec3 iResolution;
|
|
4059
|
+
uniform float iTime;
|
|
4060
|
+
uniform int iFrame;
|
|
4061
|
+
out vec4 pe_out;
|
|
4062
|
+
`;
|
|
4063
|
+
var FOOT = (transparent) => `
|
|
4064
|
+
#line 200001
|
|
4065
|
+
void main() { vec4 c = vec4(0.0, 0.0, 0.0, 1.0); mainImage(c, gl_FragCoord.xy); ${transparent ? "pe_out = vec4(c.rgb * c.a, c.a);" : "pe_out = vec4(c.rgb, 1.0);"} }
|
|
4066
|
+
`;
|
|
4067
|
+
function wrapFragment(user, uniforms, transparent) {
|
|
4068
|
+
const prefix = HEAD + uniformDecls(uniforms) + "#line 1\n";
|
|
4069
|
+
return { source: prefix + user + FOOT(transparent), userLine: prefix.split("\n").length };
|
|
4070
|
+
}
|
|
4071
|
+
function glslErrors(log) {
|
|
4072
|
+
const out = [];
|
|
4073
|
+
for (const raw of (log ?? "").split("\n")) {
|
|
4074
|
+
const line = raw.trim();
|
|
4075
|
+
if (!line) continue;
|
|
4076
|
+
const angle = /^ERROR:\s*\d+:(\d+):\s*(.*)$/.exec(line);
|
|
4077
|
+
const mesa = /^\d+:(\d+)\(\d+\):\s*(?:error|warning):\s*(.*)$/.exec(line);
|
|
4078
|
+
const hit = angle ?? mesa;
|
|
4079
|
+
if (!hit) {
|
|
4080
|
+
out.push(line);
|
|
4081
|
+
continue;
|
|
4082
|
+
}
|
|
4083
|
+
const n = Number(hit[1]);
|
|
4084
|
+
if (n >= 200001) out.push(`in the main() made for you, which calls mainImage: ${hit[2]} (write void mainImage(out vec4 fragColor, in vec2 fragCoord))`);
|
|
4085
|
+
else if (n >= 100001) out.push(`in the declarations made from your uniforms: ${hit[2]} (a uniform name GLSL does not allow, such as a reserved word?)`);
|
|
4086
|
+
else out.push(`line ${n}: ${hit[2]}`);
|
|
4087
|
+
}
|
|
4088
|
+
return out;
|
|
4089
|
+
}
|
|
4090
|
+
var stripComments = (code) => code.replace(/\/\*[\s\S]*?\*\//g, " ").replace(/\/\/.*$/gm, " ");
|
|
4091
|
+
function shaderProblems(spec) {
|
|
4092
|
+
const out = [];
|
|
4093
|
+
const raw = spec;
|
|
4094
|
+
if (typeof raw.fragment !== "string" || raw.fragment.trim() === "") {
|
|
4095
|
+
out.push("fragment is the GLSL of the shader: write { type: 'shader', fragment: 'void mainImage(out vec4 fragColor, in vec2 fragCoord) { fragColor = vec4(fragCoord / iResolution.xy, 0.0, 1.0); }' }");
|
|
4096
|
+
} else {
|
|
4097
|
+
const code = stripComments(raw.fragment);
|
|
4098
|
+
if (!/\bvoid\s+mainImage\s*\(/.test(code)) {
|
|
4099
|
+
out.push("there is no mainImage: write void mainImage(out vec4 fragColor, in vec2 fragCoord) { \u2026 } (Shadertoy style; the layer calls it for every pixel)" + (/\bvoid\s+main\s*\(/.test(code) ? " and not main()" : ""));
|
|
4100
|
+
} else {
|
|
4101
|
+
if (/\bvoid\s+main\s*\(/.test(code)) out.push("main() is written for you (it calls your mainImage): remove your main()");
|
|
4102
|
+
if (!/\bvoid\s+mainImage\s*\(\s*(?:out|inout)\s+(?:(?:highp|mediump|lowp)\s+)?vec4\s+\w+\s*,\s*(?:in\s+)?(?:(?:highp|mediump|lowp)\s+)?vec2\s+\w+\s*\)/.test(code)) {
|
|
4103
|
+
out.push("the signature of mainImage must be void mainImage(out vec4 fragColor, in vec2 fragCoord): the colour parameter is out (without out the layer draws black and nothing says why) and the position is a vec2");
|
|
4104
|
+
}
|
|
4105
|
+
}
|
|
4106
|
+
if (/^\s*#version\b/m.test(code)) out.push("#version is added for you (GLSL ES 3.00): remove it");
|
|
4107
|
+
if (/\bgl_FragColor\b/.test(code)) out.push("gl_FragColor does not exist here: write the colour into the fragColor parameter of mainImage");
|
|
4108
|
+
if (/\btexture2D\s*\(|\btextureCube\s*\(/.test(code)) out.push("texture2D is GLSL ES 1.00: this is GLSL ES 3.00, write texture(\u2026) (and note that this version has no textures to read)");
|
|
4109
|
+
if (/\b(?:varying|attribute)\b/.test(code)) out.push("varying and attribute are not used in a fragment-only shader: remove them");
|
|
4110
|
+
for (const b of SHADER_BUILTINS) {
|
|
4111
|
+
if (new RegExp(`\\buniform\\s+\\w+\\s+${b}\\b`).test(code)) out.push(`${b} is declared for you: remove your uniform ${b}`);
|
|
4112
|
+
}
|
|
4113
|
+
const missing = SHADER_MISSING.filter((n) => new RegExp(`\\b${n}\\b`).test(code));
|
|
4114
|
+
if (missing.length) out.push(`${missing.join(", ")} ${missing.length > 1 ? "are" : "is"} not provided in this version (the shader has iResolution, iTime, iFrame and your uniforms); the shader will not compile`);
|
|
4115
|
+
if (/\bwhile\s*\(/.test(code)) out.push("a while loop may never end and a GPU cannot be stopped: use a for loop with a constant bound");
|
|
4116
|
+
const consts = new Set([...code.matchAll(/\bconst\s+(?:int|float|uint)\s+(\w+)/g)].map((m) => m[1]).concat([...code.matchAll(/#define\s+(\w+)/g)].map((m) => m[1])));
|
|
4117
|
+
const constant = (expr) => {
|
|
4118
|
+
const rest = expr.replace(/\d+\.?\d*(?:[eE][-+]?\d+)?[uUfF]?|\.\d+(?:[eE][-+]?\d+)?[fF]?|[A-Za-z_]\w*/g, (t) => /^[A-Za-z_]/.test(t) && !consts.has(t) ? "?" : "");
|
|
4119
|
+
return /^[\s+\-*/%()]*$/.test(rest);
|
|
4120
|
+
};
|
|
4121
|
+
for (const m of code.matchAll(/\bfor\s*\(\s*(?:int|float|uint)\s+\w+\s*=\s*[^;]+;\s*\w+\s*(?:<=|>=|<|>|!=)\s*([^;]+?)\s*;/g)) {
|
|
4122
|
+
const bound = m[1];
|
|
4123
|
+
const ands = bound.split("&&"), ors = bound.split("||");
|
|
4124
|
+
const ok = ors.length > 1 ? ors.every((part) => constant(part.split("&&")[0].replace(/<.*$/, ""))) : ands.length > 1 ? ands.some(constant) || constant(ands[0]) : constant(bound);
|
|
4125
|
+
if (!ok) {
|
|
4126
|
+
out.push(`a for loop with the bound "${bound}" may run for ever: use a constant bound (a number or a const) and break out early`);
|
|
4127
|
+
break;
|
|
4128
|
+
}
|
|
4129
|
+
}
|
|
4130
|
+
}
|
|
4131
|
+
if (raw.uniforms !== void 0) {
|
|
4132
|
+
if (raw.uniforms === null || typeof raw.uniforms !== "object" || Array.isArray(raw.uniforms)) {
|
|
4133
|
+
out.push("uniforms is an object of names to values: { speed: 1, tint: '#ff8040', pos: [0.5, 0.5] }");
|
|
4134
|
+
} else {
|
|
4135
|
+
for (const [name, v] of Object.entries(raw.uniforms)) {
|
|
4136
|
+
if (!isIdent(name)) out.push(`uniform "${name}" is not a name GLSL can use (letters, digits and _, not starting with a digit; not a GLSL keyword or reserved word such as sample, smooth, filter, input; not iResolution / iTime / iFrame)`);
|
|
4137
|
+
else if (uniformType(v) === null) out.push(`uniform "${name}": ${JSON.stringify(v)} is not a number, 2 to 4 numbers or a '#rrggbb' colour`);
|
|
4138
|
+
}
|
|
4139
|
+
}
|
|
4140
|
+
}
|
|
4141
|
+
if (raw.resolution !== void 0 && !(typeof raw.resolution === "number" && raw.resolution > 0 && raw.resolution <= 2)) {
|
|
4142
|
+
out.push(`resolution ${JSON.stringify(raw.resolution)} is not a number above 0 and at most 2 (0.5 draws a quarter of the pixels and scales up); 1 is used`);
|
|
4143
|
+
}
|
|
4144
|
+
if (raw.transparent !== void 0 && typeof raw.transparent !== "boolean") out.push("transparent is true or false (true uses the shader's alpha; the default draws opaque)");
|
|
4145
|
+
return out;
|
|
4146
|
+
}
|
|
4147
|
+
|
|
4148
|
+
// src/sequences/Shader.ts
|
|
4149
|
+
var VERT = `#version 300 es
|
|
4150
|
+
void main() { vec2 p = vec2(float((gl_VertexID << 1) & 2), float(gl_VertexID & 2)); gl_Position = vec4(p * 2.0 - 1.0, 0.0, 1.0); }`;
|
|
4151
|
+
var ShaderSequence = class extends Sequence {
|
|
4152
|
+
prog = null;
|
|
4153
|
+
progGeneration = -1;
|
|
4154
|
+
w = 1;
|
|
4155
|
+
h = 1;
|
|
4156
|
+
c2d = null;
|
|
4157
|
+
fps = 30;
|
|
4158
|
+
failed = false;
|
|
4159
|
+
warnedNoGl = false;
|
|
4160
|
+
acquired = false;
|
|
4161
|
+
warnedPaths = /* @__PURE__ */ new Set();
|
|
4162
|
+
/** The current value of every uniform: what keyframes move (`uniforms.speed`, `uniforms.tint.0`). */
|
|
4163
|
+
carrier = {};
|
|
4164
|
+
/** How many components each vector uniform has (a scalar is not listed). */
|
|
4165
|
+
dims = {};
|
|
4166
|
+
get shaderSpec() {
|
|
4167
|
+
return this.spec;
|
|
4168
|
+
}
|
|
4169
|
+
pathRouters() {
|
|
4170
|
+
return { uniforms: (path) => this.resolveUniform(path) };
|
|
4171
|
+
}
|
|
4172
|
+
async build() {
|
|
4173
|
+
const spec = this.shaderSpec;
|
|
4174
|
+
const who = chunkECA2WNRX_cjs.describeLayer(spec);
|
|
4175
|
+
for (const m of shaderProblems(spec)) console.warn(`pixi-effects: ${who}: ${m}`);
|
|
4176
|
+
if (this.duration === void 0) this.duration = this.parent?.duration ?? this.root.duration;
|
|
4177
|
+
const scope = buildScope(this, this.parent, this.root);
|
|
4178
|
+
const width = resolveDim(spec.width, scope) ?? this.parent?.width ?? this.root.width;
|
|
4179
|
+
const height = resolveDim(spec.height, scope) ?? this.parent?.height ?? this.root.height;
|
|
4180
|
+
const res = typeof spec.resolution === "number" && spec.resolution > 0 && spec.resolution <= 2 ? spec.resolution : 1;
|
|
4181
|
+
this.w = Math.max(1, Math.round(width * res));
|
|
4182
|
+
this.h = Math.max(1, Math.round(height * res));
|
|
4183
|
+
this.fps = this.root.frameRate ?? 30;
|
|
4184
|
+
for (const [name, v] of Object.entries(spec.uniforms ?? {})) {
|
|
4185
|
+
if (uniformType(v) === null) continue;
|
|
4186
|
+
if (typeof v === "number") this.carrier[name] = v;
|
|
4187
|
+
else {
|
|
4188
|
+
const f = uniformFloats(v);
|
|
4189
|
+
this.carrier[name] = Object.fromEntries(f.map((x, i) => [String(i), x]));
|
|
4190
|
+
this.dims[name] = f.length;
|
|
4191
|
+
}
|
|
4192
|
+
}
|
|
4193
|
+
this.c2d = document.createElement("canvas");
|
|
4194
|
+
this.c2d.width = this.w;
|
|
4195
|
+
this.c2d.height = this.h;
|
|
4196
|
+
const sprite = new PIXI.Sprite({ texture: PIXI.Texture.from(this.c2d), label: spec.name });
|
|
4197
|
+
sprite.width = width;
|
|
4198
|
+
sprite.height = height;
|
|
4199
|
+
this.target = sprite;
|
|
4200
|
+
this.intrinsicWidth = width;
|
|
4201
|
+
this.intrinsicHeight = height;
|
|
4202
|
+
this.buildFilters();
|
|
4203
|
+
if (typeof spec.fragment === "string" && spec.fragment.trim() !== "") this.acquire();
|
|
4204
|
+
else this.failed = true;
|
|
4205
|
+
this.drawAt(0);
|
|
4206
|
+
}
|
|
4207
|
+
async awaitFrameAt(local) {
|
|
4208
|
+
this.drawAt(Math.max(0, Math.min(local, this.duration ?? local)));
|
|
4209
|
+
}
|
|
4210
|
+
/** Resolve `uniforms.speed` / `uniforms.tint.0` for the keyframe pipeline; a name or index nobody has is said once and dropped. */
|
|
4211
|
+
resolveUniform(path) {
|
|
4212
|
+
const segs = path.split(".");
|
|
4213
|
+
const name = segs[0];
|
|
4214
|
+
const slot = this.carrier[name];
|
|
4215
|
+
const warn = (why) => {
|
|
4216
|
+
if (this.warnedPaths.has(path)) return;
|
|
4217
|
+
this.warnedPaths.add(path);
|
|
4218
|
+
console.warn(`pixi-effects: ${chunkECA2WNRX_cjs.describeLayer(this.spec)}: keyframe path uniforms.${path} ${why}; skipped`);
|
|
4219
|
+
};
|
|
4220
|
+
if (slot === void 0) {
|
|
4221
|
+
const guess = chunkTWZNOUM7_cjs.suggestName(name, Object.keys(this.carrier));
|
|
4222
|
+
warn(`names no uniform "${name}"${guess ? `; did you mean "${guess}"?` : ""} (declare it in uniforms with a starting value)`);
|
|
4223
|
+
return null;
|
|
4224
|
+
}
|
|
4225
|
+
if (typeof slot === "number") {
|
|
4226
|
+
if (segs.length !== 1) {
|
|
4227
|
+
warn(`has more than a name, but "${name}" is a single number`);
|
|
4228
|
+
return null;
|
|
4229
|
+
}
|
|
4230
|
+
return { target: this.carrier, prop: name };
|
|
4231
|
+
}
|
|
4232
|
+
const n = this.dims[name];
|
|
4233
|
+
const index = segs.length === 2 ? Number(segs[1]) : NaN;
|
|
4234
|
+
if (!Number.isInteger(index) || index < 0 || index >= n) {
|
|
4235
|
+
warn(`must name a component of "${name}" (0 to ${n - 1}): 'uniforms.${name}.0'`);
|
|
4236
|
+
return null;
|
|
4237
|
+
}
|
|
4238
|
+
return { target: slot, prop: String(index) };
|
|
4239
|
+
}
|
|
4240
|
+
acquire() {
|
|
4241
|
+
const sh = acquireGl();
|
|
4242
|
+
this.acquired = true;
|
|
4243
|
+
if (!sh) {
|
|
4244
|
+
this.noGl();
|
|
4245
|
+
return;
|
|
4246
|
+
}
|
|
4247
|
+
this.compile();
|
|
4248
|
+
}
|
|
4249
|
+
noGl() {
|
|
4250
|
+
this.failed = true;
|
|
4251
|
+
if (!this.warnedNoGl) {
|
|
4252
|
+
this.warnedNoGl = true;
|
|
4253
|
+
console.warn(`pixi-effects: ${chunkECA2WNRX_cjs.describeLayer(this.spec)}: this browser has no WebGL2, so the shader cannot run; the layer is drawn as a checkerboard`);
|
|
4254
|
+
}
|
|
4255
|
+
}
|
|
4256
|
+
compile() {
|
|
4257
|
+
const sh = currentGl();
|
|
4258
|
+
if (!sh) {
|
|
4259
|
+
this.noGl();
|
|
4260
|
+
return;
|
|
4261
|
+
}
|
|
4262
|
+
const { gl } = sh;
|
|
4263
|
+
const spec = this.shaderSpec;
|
|
4264
|
+
const make = (type, src) => {
|
|
4265
|
+
const s = gl.createShader(type);
|
|
4266
|
+
gl.shaderSource(s, src);
|
|
4267
|
+
gl.compileShader(s);
|
|
4268
|
+
return s;
|
|
4269
|
+
};
|
|
4270
|
+
const vs = make(gl.VERTEX_SHADER, VERT);
|
|
4271
|
+
const fs = make(gl.FRAGMENT_SHADER, wrapFragment(spec.fragment, spec.uniforms ?? {}, !!spec.transparent).source);
|
|
4272
|
+
const p = gl.createProgram();
|
|
4273
|
+
gl.attachShader(p, vs);
|
|
4274
|
+
gl.attachShader(p, fs);
|
|
4275
|
+
gl.linkProgram(p);
|
|
4276
|
+
const ok = gl.getProgramParameter(p, gl.LINK_STATUS);
|
|
4277
|
+
const log = ok ? "" : gl.getShaderInfoLog(fs) || gl.getProgramInfoLog(p) || "";
|
|
4278
|
+
gl.deleteShader(vs);
|
|
4279
|
+
gl.deleteShader(fs);
|
|
4280
|
+
if (!ok) {
|
|
4281
|
+
gl.deleteProgram(p);
|
|
4282
|
+
this.failed = true;
|
|
4283
|
+
this.prog = null;
|
|
4284
|
+
console.warn(`pixi-effects: ${chunkECA2WNRX_cjs.describeLayer(this.spec)}: the fragment shader did not compile (the line numbers are the lines of your code):
|
|
4285
|
+
${glslErrors(log).join("\n")}
|
|
4286
|
+
The layer is drawn as a checkerboard until it is fixed.`);
|
|
4287
|
+
return;
|
|
4288
|
+
}
|
|
4289
|
+
this.prog = p;
|
|
4290
|
+
this.progGeneration = sh.generation;
|
|
4291
|
+
}
|
|
4292
|
+
drawAt(local) {
|
|
4293
|
+
const c = this.c2d;
|
|
4294
|
+
if (!c) return;
|
|
4295
|
+
const ctx2 = c.getContext("2d");
|
|
4296
|
+
if (!ctx2) return;
|
|
4297
|
+
let sh = this.failed ? null : currentGl();
|
|
4298
|
+
if (sh && this.progGeneration !== sh.generation) {
|
|
4299
|
+
this.compile();
|
|
4300
|
+
sh = this.failed ? null : currentGl();
|
|
4301
|
+
}
|
|
4302
|
+
if (!sh || !this.prog) {
|
|
4303
|
+
const s = 32;
|
|
4304
|
+
for (let y = 0; y < c.height; y += s) for (let x = 0; x < c.width; x += s) {
|
|
4305
|
+
ctx2.fillStyle = x / s + y / s & 1 ? "#ff00ff" : "#220022";
|
|
4306
|
+
ctx2.fillRect(x, y, s, s);
|
|
4307
|
+
}
|
|
4308
|
+
} else {
|
|
4309
|
+
const { gl, canvas } = sh;
|
|
4310
|
+
if (canvas.width !== this.w || canvas.height !== this.h) {
|
|
4311
|
+
canvas.width = this.w;
|
|
4312
|
+
canvas.height = this.h;
|
|
4313
|
+
}
|
|
4314
|
+
gl.viewport(0, 0, this.w, this.h);
|
|
4315
|
+
gl.useProgram(this.prog);
|
|
4316
|
+
gl.uniform3f(gl.getUniformLocation(this.prog, "iResolution"), this.w, this.h, 1);
|
|
4317
|
+
gl.uniform1f(gl.getUniformLocation(this.prog, "iTime"), local);
|
|
4318
|
+
gl.uniform1i(gl.getUniformLocation(this.prog, "iFrame"), Math.round(local * this.fps));
|
|
4319
|
+
for (const [name, v] of Object.entries(this.carrier)) {
|
|
4320
|
+
const loc = gl.getUniformLocation(this.prog, name);
|
|
4321
|
+
if (typeof v === "number") {
|
|
4322
|
+
gl.uniform1f(loc, v);
|
|
4323
|
+
continue;
|
|
4324
|
+
}
|
|
4325
|
+
const n = this.dims[name];
|
|
4326
|
+
const comps = Array.from({ length: n }, (_, i) => v[String(i)] ?? 0);
|
|
4327
|
+
if (n === 2) gl.uniform2fv(loc, comps);
|
|
4328
|
+
else if (n === 3) gl.uniform3fv(loc, comps);
|
|
4329
|
+
else gl.uniform4fv(loc, comps);
|
|
4330
|
+
}
|
|
4331
|
+
gl.clearColor(0, 0, 0, 0);
|
|
4332
|
+
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
4333
|
+
gl.drawArrays(gl.TRIANGLES, 0, 3);
|
|
4334
|
+
ctx2.clearRect(0, 0, c.width, c.height);
|
|
4335
|
+
ctx2.drawImage(canvas, 0, 0);
|
|
4336
|
+
}
|
|
4337
|
+
this.target?.texture.source.update();
|
|
4338
|
+
}
|
|
4339
|
+
destroy() {
|
|
4340
|
+
const texture = this.target?.texture;
|
|
4341
|
+
if (this.prog) {
|
|
4342
|
+
const sh = currentGl();
|
|
4343
|
+
if (sh && this.progGeneration === sh.generation) sh.gl.deleteProgram(this.prog);
|
|
4344
|
+
this.prog = null;
|
|
4345
|
+
}
|
|
4346
|
+
if (this.acquired) {
|
|
4347
|
+
this.acquired = false;
|
|
4348
|
+
releaseGl();
|
|
4349
|
+
}
|
|
4350
|
+
if (this.c2d) {
|
|
4351
|
+
this.c2d.width = this.c2d.height = 1;
|
|
4352
|
+
this.c2d = null;
|
|
4353
|
+
}
|
|
4354
|
+
super.destroy();
|
|
4355
|
+
texture?.destroy(true);
|
|
4356
|
+
}
|
|
4357
|
+
};
|
|
4358
|
+
function resolveDim(v, scope) {
|
|
4359
|
+
if (v === void 0) return void 0;
|
|
4360
|
+
if (typeof v === "number") return v;
|
|
4361
|
+
return evaluateExpr(v, scope);
|
|
4362
|
+
}
|
|
4363
|
+
|
|
3574
4364
|
// src/core/Composition.ts
|
|
3575
4365
|
var _CompositionSequence = null;
|
|
3576
4366
|
async function getCompositionSequence() {
|
|
3577
4367
|
if (!_CompositionSequence) {
|
|
3578
|
-
_CompositionSequence = (await import('./Composition-
|
|
4368
|
+
_CompositionSequence = (await import('./Composition-2GJSCHPP.cjs')).CompositionSequence;
|
|
3579
4369
|
}
|
|
3580
4370
|
return _CompositionSequence;
|
|
3581
4371
|
}
|
|
@@ -3586,6 +4376,8 @@ var staticTypes = {
|
|
|
3586
4376
|
video: VideoSequence,
|
|
3587
4377
|
shape: ShapeSequence,
|
|
3588
4378
|
camera: CameraSequence,
|
|
4379
|
+
light: LightSequence,
|
|
4380
|
+
shader: ShaderSequence,
|
|
3589
4381
|
null: NullSequence
|
|
3590
4382
|
};
|
|
3591
4383
|
var registry2 = {};
|
|
@@ -3615,12 +4407,19 @@ async function buildSequenceTree(specs, parent, root) {
|
|
|
3615
4407
|
|
|
3616
4408
|
exports.CameraSequence = CameraSequence;
|
|
3617
4409
|
exports.DEFAULT_FOV = DEFAULT_FOV;
|
|
3618
|
-
exports.DEG =
|
|
4410
|
+
exports.DEG = DEG2;
|
|
4411
|
+
exports.FALLOFFS = FALLOFFS;
|
|
4412
|
+
exports.LIGHT_KINDS = LIGHT_KINDS;
|
|
4413
|
+
exports.LIGHT_PROPS = LIGHT_PROPS;
|
|
4414
|
+
exports.LightSequence = LightSequence;
|
|
3619
4415
|
exports.MANY_BLURRED = MANY_BLURRED;
|
|
3620
4416
|
exports.MAX_BLUR = MAX_BLUR;
|
|
4417
|
+
exports.MAX_CASTERS = MAX_CASTERS;
|
|
4418
|
+
exports.MAX_LIGHTS = MAX_LIGHTS;
|
|
3621
4419
|
exports.MIN_BLUR = MIN_BLUR;
|
|
3622
4420
|
exports.NEAR = NEAR;
|
|
3623
4421
|
exports.NullSequence = NullSequence;
|
|
4422
|
+
exports.SHADOW_TAPS = SHADOW_TAPS;
|
|
3624
4423
|
exports.Sequence = Sequence;
|
|
3625
4424
|
exports.bindClock = bindClock;
|
|
3626
4425
|
exports.blurRadius = blurRadius;
|
|
@@ -3637,7 +4436,10 @@ exports.focusProblems = focusProblems;
|
|
|
3637
4436
|
exports.homeCamera = homeCamera;
|
|
3638
4437
|
exports.homeDistance = homeDistance;
|
|
3639
4438
|
exports.layerInitialZ = layerInitialZ;
|
|
4439
|
+
exports.layerToWorld = layerToWorld;
|
|
4440
|
+
exports.lightLevel = lightLevel;
|
|
3640
4441
|
exports.noise = noise;
|
|
4442
|
+
exports.packLights = packLights;
|
|
3641
4443
|
exports.projectLayer = projectLayer;
|
|
3642
4444
|
exports.projectPoint = projectPoint;
|
|
3643
4445
|
exports.rand = rand;
|
|
@@ -3646,5 +4448,5 @@ exports.registerSequenceType = registerSequenceType;
|
|
|
3646
4448
|
exports.remapOf = remapOf;
|
|
3647
4449
|
exports.resolveAt = resolveAt;
|
|
3648
4450
|
exports.timeRemapOf = timeRemapOf;
|
|
3649
|
-
//# sourceMappingURL=chunk-
|
|
3650
|
-
//# sourceMappingURL=chunk-
|
|
4451
|
+
//# sourceMappingURL=chunk-DP37TTMO.cjs.map
|
|
4452
|
+
//# sourceMappingURL=chunk-DP37TTMO.cjs.map
|