pixi-effects 0.20.0 → 0.22.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 +31 -0
- package/README.md +6 -6
- package/ai/SKILL.md +3 -3
- package/ai/chat-template.html +3 -3
- package/ai/reference/cheatsheet.md +7 -7
- package/ai/reference/pitfalls.md +8 -1
- package/ai/reference/recipes.md +55 -0
- package/ai/template.html +5 -5
- package/ai/tools/check.mjs +15 -4
- package/dist/{Base-wYJQ2g5Q.d.cts → Base-BzlPgd-D.d.cts} +1 -1
- package/dist/{Base-CzfLGoDr.d.ts → Base-gu-5X0Cv.d.ts} +1 -1
- package/dist/Composition-BK5SH6J7.cjs +16 -0
- package/dist/{Composition-LL2XXU5N.cjs.map → Composition-BK5SH6J7.cjs.map} +1 -1
- package/dist/Composition-Q5TVG3HM.js +7 -0
- package/dist/{Composition-6PA4C4TV.js.map → Composition-Q5TVG3HM.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-CBxGH5ms.d.ts → Movie--_TJvdJa.d.ts} +3 -1
- package/dist/{Movie-CzzJw8A-.d.cts → Movie-DMxOoTdW.d.cts} +3 -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-5E4G2ZZQ.cjs +94 -0
- package/dist/blendModes-5E4G2ZZQ.cjs.map +1 -0
- package/dist/blendModes-HCP5XTNP.js +90 -0
- package/dist/blendModes-HCP5XTNP.js.map +1 -0
- package/dist/chunk-BPTW7L25.cjs +275 -0
- package/dist/chunk-BPTW7L25.cjs.map +1 -0
- package/dist/{chunk-DQHXVNOI.js → chunk-DC4JPY6A.js} +108 -273
- package/dist/chunk-DC4JPY6A.js.map +1 -0
- package/dist/chunk-E7RONUZ7.js +268 -0
- package/dist/chunk-E7RONUZ7.js.map +1 -0
- package/dist/{chunk-NO26HWR7.cjs → chunk-IFZOI3JQ.cjs} +131 -295
- package/dist/chunk-IFZOI3JQ.cjs.map +1 -0
- package/dist/chunk-K4JVI5HK.cjs +143 -0
- package/dist/chunk-K4JVI5HK.cjs.map +1 -0
- package/dist/{chunk-FFYA3UBU.cjs → chunk-MHOO2CVU.cjs} +290 -62
- package/dist/chunk-MHOO2CVU.cjs.map +1 -0
- package/dist/{chunk-MNM56B3X.js → chunk-NHICCDTC.js} +13 -3
- package/dist/chunk-NHICCDTC.js.map +1 -0
- package/dist/{chunk-TSPMKV2F.js → chunk-UQDEDYVM.js} +261 -33
- package/dist/chunk-UQDEDYVM.js.map +1 -0
- package/dist/{chunk-WTRKDIKH.cjs → chunk-UZTKEYFP.cjs} +13 -3
- package/dist/chunk-UZTKEYFP.cjs.map +1 -0
- package/dist/chunk-YEPDQ7I3.js +132 -0
- package/dist/chunk-YEPDQ7I3.js.map +1 -0
- package/dist/index.cjs +72 -68
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +11 -7
- package/dist/index.js.map +1 -1
- package/dist/loader.css +1 -1
- package/dist/{music-CFEC7HKL.js → music-FUN7N225.js} +3 -3
- package/dist/{music-CFEC7HKL.js.map → music-FUN7N225.js.map} +1 -1
- package/dist/{music-UAN7DXK4.cjs → music-GEAH2XCT.cjs} +7 -7
- package/dist/{music-UAN7DXK4.cjs.map → music-GEAH2XCT.cjs.map} +1 -1
- package/dist/{sfx-EX4PUBMV.cjs → sfx-2DYTYNYW.cjs} +8 -8
- package/dist/{sfx-EX4PUBMV.cjs.map → sfx-2DYTYNYW.cjs.map} +1 -1
- package/dist/{sfx-U3GM2MED.js → sfx-3IDAJ3UZ.js} +3 -3
- package/dist/{sfx-U3GM2MED.js.map → sfx-3IDAJ3UZ.js.map} +1 -1
- package/dist/three.cjs +7 -6
- package/dist/three.cjs.map +1 -1
- package/dist/three.d.cts +2 -2
- package/dist/three.d.ts +2 -2
- package/dist/three.js +3 -2
- package/dist/three.js.map +1 -1
- package/dist/{types-YmUaViL1.d.cts → types-DBbZVKGS.d.cts} +7 -4
- package/dist/{types-YmUaViL1.d.ts → types-DBbZVKGS.d.ts} +7 -4
- package/docs/dsl.md +82 -3
- package/llms-full.txt +155 -14
- package/package.json +1 -1
- package/dist/Composition-6PA4C4TV.js +0 -5
- package/dist/Composition-LL2XXU5N.cjs +0 -14
- package/dist/chunk-DQHXVNOI.js.map +0 -1
- package/dist/chunk-FFYA3UBU.cjs.map +0 -1
- package/dist/chunk-MNM56B3X.js.map +0 -1
- package/dist/chunk-NO26HWR7.cjs.map +0 -1
- package/dist/chunk-TSPMKV2F.js.map +0 -1
- package/dist/chunk-WTRKDIKH.cjs.map +0 -1
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
3
|
+
var chunkIFZOI3JQ_cjs = require('./chunk-IFZOI3JQ.cjs');
|
|
4
|
+
var chunkK4JVI5HK_cjs = require('./chunk-K4JVI5HK.cjs');
|
|
5
|
+
var chunkBPTW7L25_cjs = require('./chunk-BPTW7L25.cjs');
|
|
6
|
+
var chunkUZTKEYFP_cjs = require('./chunk-UZTKEYFP.cjs');
|
|
5
7
|
var pixi_js = require('pixi.js');
|
|
6
8
|
var gsap = require('gsap');
|
|
7
9
|
|
|
@@ -47,6 +49,91 @@ function assignDepthOrder(items) {
|
|
|
47
49
|
}
|
|
48
50
|
return out;
|
|
49
51
|
}
|
|
52
|
+
var DISC_TAPS = 48;
|
|
53
|
+
var GL_VERTEX = `#version 300 es
|
|
54
|
+
in vec2 aPosition;
|
|
55
|
+
out vec2 vTextureCoord;
|
|
56
|
+
uniform vec4 uInputSize;
|
|
57
|
+
uniform vec4 uOutputFrame;
|
|
58
|
+
uniform vec4 uOutputTexture;
|
|
59
|
+
void main(void) {
|
|
60
|
+
vec2 position = aPosition * uOutputFrame.zw + uOutputFrame.xy;
|
|
61
|
+
position.x = position.x * (2.0 / uOutputTexture.x) - 1.0;
|
|
62
|
+
position.y = position.y * (2.0 * uOutputTexture.z / uOutputTexture.y) - uOutputTexture.z;
|
|
63
|
+
gl_Position = vec4(position, 0.0, 1.0);
|
|
64
|
+
vTextureCoord = aPosition * (uOutputFrame.zw * uInputSize.zw);
|
|
65
|
+
}`;
|
|
66
|
+
var GL_FRAGMENT = `#version 300 es
|
|
67
|
+
precision highp float;
|
|
68
|
+
in vec2 vTextureCoord;
|
|
69
|
+
uniform sampler2D uTexture;
|
|
70
|
+
uniform vec4 uInputSize;
|
|
71
|
+
uniform float uRadius;
|
|
72
|
+
out vec4 finalColor;
|
|
73
|
+
void main(void) {
|
|
74
|
+
vec4 acc = vec4(0.0);
|
|
75
|
+
for (int i = 0; i < ${DISC_TAPS}; i++) {
|
|
76
|
+
float r = sqrt((float(i) + 0.5) / ${DISC_TAPS}.0) * uRadius;
|
|
77
|
+
float a = float(i) * 2.39996323;
|
|
78
|
+
acc += texture(uTexture, vTextureCoord + vec2(cos(a), sin(a)) * r * uInputSize.zw);
|
|
79
|
+
}
|
|
80
|
+
finalColor = acc / ${DISC_TAPS}.0;
|
|
81
|
+
}`;
|
|
82
|
+
var WGSL = `
|
|
83
|
+
struct GlobalFilterUniforms {
|
|
84
|
+
uInputSize: vec4<f32>, uInputPixel: vec4<f32>, uInputClamp: vec4<f32>,
|
|
85
|
+
uOutputFrame: vec4<f32>, uGlobalFrame: vec4<f32>, uOutputTexture: vec4<f32>,
|
|
86
|
+
};
|
|
87
|
+
struct DiscUniforms { uRadius: f32 };
|
|
88
|
+
@group(0) @binding(0) var<uniform> gfu: GlobalFilterUniforms;
|
|
89
|
+
@group(0) @binding(1) var uTexture: texture_2d<f32>;
|
|
90
|
+
@group(0) @binding(2) var uSampler : sampler;
|
|
91
|
+
@group(1) @binding(0) var<uniform> disc : DiscUniforms;
|
|
92
|
+
struct VSOutput { @builtin(position) position: vec4<f32>, @location(0) uv : vec2<f32> };
|
|
93
|
+
fn filterVertexPosition(aPosition : vec2<f32>) -> vec4<f32> {
|
|
94
|
+
var position = aPosition * gfu.uOutputFrame.zw + gfu.uOutputFrame.xy;
|
|
95
|
+
position.x = position.x * (2.0 / gfu.uOutputTexture.x) - 1.0;
|
|
96
|
+
position.y = position.y * (2.0 * gfu.uOutputTexture.z / gfu.uOutputTexture.y) - gfu.uOutputTexture.z;
|
|
97
|
+
return vec4<f32>(position, 0.0, 1.0);
|
|
98
|
+
}
|
|
99
|
+
fn filterTextureCoord(aPosition : vec2<f32>) -> vec2<f32> {
|
|
100
|
+
return aPosition * (gfu.uOutputFrame.zw * gfu.uInputSize.zw);
|
|
101
|
+
}
|
|
102
|
+
@vertex
|
|
103
|
+
fn mainVertex(@location(0) aPosition : vec2<f32>) -> VSOutput {
|
|
104
|
+
return VSOutput(filterVertexPosition(aPosition), filterTextureCoord(aPosition));
|
|
105
|
+
}
|
|
106
|
+
@fragment
|
|
107
|
+
fn mainFragment(@location(0) uv : vec2<f32>) -> @location(0) vec4<f32> {
|
|
108
|
+
var acc = vec4<f32>(0.0);
|
|
109
|
+
for (var i = 0; i < ${DISC_TAPS}; i++) {
|
|
110
|
+
let r = sqrt((f32(i) + 0.5) / ${DISC_TAPS}.0) * disc.uRadius;
|
|
111
|
+
let a = f32(i) * 2.39996323;
|
|
112
|
+
acc += textureSampleLevel(uTexture, uSampler, uv + vec2<f32>(cos(a), sin(a)) * r * gfu.uInputSize.zw, 0.0);
|
|
113
|
+
}
|
|
114
|
+
return acc / ${DISC_TAPS}.0;
|
|
115
|
+
}`;
|
|
116
|
+
var DiscBlurFilter = class extends pixi_js.Filter {
|
|
117
|
+
constructor(radius = 8) {
|
|
118
|
+
super({
|
|
119
|
+
glProgram: pixi_js.GlProgram.from({ vertex: GL_VERTEX, fragment: GL_FRAGMENT, name: "disc-blur" }),
|
|
120
|
+
gpuProgram: pixi_js.GpuProgram.from({ vertex: { source: WGSL, entryPoint: "mainVertex" }, fragment: { source: WGSL, entryPoint: "mainFragment" } }),
|
|
121
|
+
resources: { disc: new pixi_js.UniformGroup({ uRadius: { value: radius, type: "f32" } }) }
|
|
122
|
+
});
|
|
123
|
+
this.radius = radius;
|
|
124
|
+
}
|
|
125
|
+
/** Blur radius in pixels. The padding follows it, so the blurred edge is not cut off. */
|
|
126
|
+
get radius() {
|
|
127
|
+
return this.resources.disc.uniforms.uRadius;
|
|
128
|
+
}
|
|
129
|
+
set radius(v) {
|
|
130
|
+
const r = Math.max(0, v);
|
|
131
|
+
this.resources.disc.uniforms.uRadius = r;
|
|
132
|
+
this.padding = Math.ceil(r) + 2;
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
// src/space/Layer3D.ts
|
|
50
137
|
var MAX_TEXTURE_SIZE = 4096;
|
|
51
138
|
var SUPERSAMPLE = 2;
|
|
52
139
|
var MAX_TEXTURE_PIXELS = 2048 * 2048;
|
|
@@ -65,8 +152,8 @@ function readLayerTransform(target) {
|
|
|
65
152
|
x: c.x,
|
|
66
153
|
y: c.y,
|
|
67
154
|
z: c.z ?? 0,
|
|
68
|
-
rotationX: (c.rotationX ?? 0) *
|
|
69
|
-
rotationY: (c.rotationY ?? 0) *
|
|
155
|
+
rotationX: (c.rotationX ?? 0) * chunkIFZOI3JQ_cjs.DEG,
|
|
156
|
+
rotationY: (c.rotationY ?? 0) * chunkIFZOI3JQ_cjs.DEG,
|
|
70
157
|
rotationZ: c.rotation,
|
|
71
158
|
scaleX: c.scale.x,
|
|
72
159
|
scaleY: c.scale.y,
|
|
@@ -100,6 +187,11 @@ var Layer3D = class {
|
|
|
100
187
|
retired = [];
|
|
101
188
|
size = null;
|
|
102
189
|
warnedBehind = false;
|
|
190
|
+
/** Depth-of-field blur radius (px) from the last `setBlur`; 0 = no filter. */
|
|
191
|
+
blur = 0;
|
|
192
|
+
blurFilter = null;
|
|
193
|
+
blendWas = "normal";
|
|
194
|
+
blendFilter = null;
|
|
103
195
|
update(host, basis) {
|
|
104
196
|
this.flushRetired();
|
|
105
197
|
const target = this.seq.target;
|
|
@@ -111,19 +203,19 @@ var Layer3D = class {
|
|
|
111
203
|
if (!(needW >= 1 && needH >= 1) || !Number.isFinite(bounds.x) || !Number.isFinite(bounds.y)) return this.hide();
|
|
112
204
|
const size = this.sizeFor(needW, needH);
|
|
113
205
|
const frame = { x: bounds.x - pad, y: bounds.y - pad, width: size.w, height: size.h };
|
|
114
|
-
const projected =
|
|
206
|
+
const projected = chunkIFZOI3JQ_cjs.projectLayer(readLayerTransform(target), frame, basis);
|
|
115
207
|
this.depth = projected.depth;
|
|
116
208
|
if (!projected.visible) {
|
|
117
209
|
if (!this.warnedBehind) {
|
|
118
210
|
this.warnedBehind = true;
|
|
119
211
|
if (this.seq.spec.hideBehindCamera) return this.hide();
|
|
120
|
-
if (projected.depth >
|
|
212
|
+
if (projected.depth > chunkIFZOI3JQ_cjs.NEAR) {
|
|
121
213
|
console.warn(
|
|
122
|
-
`pixi-effects: ${
|
|
214
|
+
`pixi-effects: ${chunkBPTW7L25_cjs.describeLayer(this.seq.spec)}: part of it (a corner) reaches the camera plane (z = ${(target.z ?? 0).toFixed(0)}, rotationX ${(target.rotationX ?? 0).toFixed(0)}\xB0, rotationY ${(target.rotationY ?? 0).toFixed(0)}\xB0), and a layer is hidden whole when any corner is at or behind it. Tilt it less (rotationX / rotationY), make it smaller, or keep the camera further away from it (the default camera sits at z = (height/2)/tan(fov/2), about 989 for 720p at fov 40).`
|
|
123
215
|
);
|
|
124
216
|
} else {
|
|
125
217
|
console.warn(
|
|
126
|
-
`pixi-effects: ${
|
|
218
|
+
`pixi-effects: ${chunkBPTW7L25_cjs.describeLayer(this.seq.spec)} is at or behind the camera plane (z = ${(target.z ?? 0).toFixed(0)}) and is hidden. If that is unintended, lower its z or move the camera back (the default camera sits at z = (height/2)/tan(fov/2), about 989 for 720p at fov 40).`
|
|
127
219
|
);
|
|
128
220
|
}
|
|
129
221
|
}
|
|
@@ -140,7 +232,46 @@ var Layer3D = class {
|
|
|
140
232
|
this.display.geometry.setCorners(...projected.corners);
|
|
141
233
|
this.display.visible = true;
|
|
142
234
|
}
|
|
235
|
+
/**
|
|
236
|
+
* Depth-of-field blur on the projected mesh (screen space), so a tilted or scaled layer blurs by the size it is drawn at.
|
|
237
|
+
* A radius under MIN_BLUR removes the filter: a sharp layer costs nothing. A blend mode moves to the filter while it is on
|
|
238
|
+
* (a filtered object blends as a whole), and comes back when it goes.
|
|
239
|
+
*/
|
|
240
|
+
setBlur(radius) {
|
|
241
|
+
const d = this.display;
|
|
242
|
+
const r = radius > chunkIFZOI3JQ_cjs.MIN_BLUR ? Math.min(radius, chunkIFZOI3JQ_cjs.MAX_BLUR) : 0;
|
|
243
|
+
this.blur = r;
|
|
244
|
+
if (r === 0) {
|
|
245
|
+
if (this.blurFilter) {
|
|
246
|
+
d.filters = null;
|
|
247
|
+
d.blendMode = this.blendWas;
|
|
248
|
+
this.blurFilter.destroy();
|
|
249
|
+
this.blurFilter = null;
|
|
250
|
+
this.blendFilter?.destroy();
|
|
251
|
+
this.blendFilter = null;
|
|
252
|
+
}
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
if (!this.blurFilter) {
|
|
256
|
+
this.blurFilter = new DiscBlurFilter(r);
|
|
257
|
+
this.blendWas = d.blendMode ?? "normal";
|
|
258
|
+
const chain = [this.blurFilter];
|
|
259
|
+
if (chunkK4JVI5HK_cjs.isAdvancedBlend(this.blendWas)) {
|
|
260
|
+
this.blendFilter = chunkK4JVI5HK_cjs.blendFilterFor(this.blendWas);
|
|
261
|
+
if (this.blendFilter) {
|
|
262
|
+
chain.push(this.blendFilter);
|
|
263
|
+
d.blendMode = "normal";
|
|
264
|
+
}
|
|
265
|
+
} else if (this.blendWas !== "normal" && this.blendWas !== "inherit") {
|
|
266
|
+
this.blurFilter.blendMode = this.blendWas;
|
|
267
|
+
d.blendMode = "normal";
|
|
268
|
+
}
|
|
269
|
+
d.filters = chain;
|
|
270
|
+
}
|
|
271
|
+
this.blurFilter.radius = r;
|
|
272
|
+
}
|
|
143
273
|
destroy() {
|
|
274
|
+
this.setBlur(0);
|
|
144
275
|
this.display.destroy();
|
|
145
276
|
this.rt?.destroy(true);
|
|
146
277
|
this.rt = null;
|
|
@@ -192,6 +323,7 @@ var Layer3D = class {
|
|
|
192
323
|
// src/space/lint.ts
|
|
193
324
|
var defaultWarn = (m) => console.warn(m);
|
|
194
325
|
var FOV_HINT = `perspective is the camera's "fov" \u2014 add a { type: "camera" } layer and set fov in its initial / keyframes`;
|
|
326
|
+
var DOF_HINT = `depth of field is the camera's "focus" (the plane that is sharp: a layer name or a z) and "aperture" (how shallow: 0 = off, 30 = default) \u2014 put them in the camera's initial / keyframes`;
|
|
195
327
|
var LAYER_ALIASES = {
|
|
196
328
|
rotateX: 'did you mean "rotationX"?',
|
|
197
329
|
rotateY: 'did you mean "rotationY"?',
|
|
@@ -205,14 +337,21 @@ var LAYER_ALIASES = {
|
|
|
205
337
|
};
|
|
206
338
|
var CAMERA_ALIASES = {
|
|
207
339
|
pointOfInterest: 'did you mean "lookAtX / lookAtY / lookAtZ"?',
|
|
208
|
-
lookAt: 'did you mean "lookAtX / lookAtY / lookAtZ"?'
|
|
340
|
+
lookAt: 'did you mean "lookAtX / lookAtY / lookAtZ"?',
|
|
341
|
+
depthOfField: DOF_HINT,
|
|
342
|
+
dof: DOF_HINT,
|
|
343
|
+
focalDistance: DOF_HINT,
|
|
344
|
+
focusDistance: DOF_HINT,
|
|
345
|
+
fStop: DOF_HINT,
|
|
346
|
+
blurAmount: DOF_HINT
|
|
209
347
|
};
|
|
210
|
-
var CAMERA_PROPS = ["x", "y", "z", "fov", "lookAtX", "lookAtY", "lookAtZ", "offsetX", "offsetY", "offsetZ", "lookOffsetX", "lookOffsetY", "lookOffsetZ"];
|
|
348
|
+
var CAMERA_PROPS = ["x", "y", "z", "fov", "focus", "aperture", "lookAtX", "lookAtY", "lookAtZ", "offsetX", "offsetY", "offsetZ", "lookOffsetX", "lookOffsetY", "lookOffsetZ"];
|
|
211
349
|
var NEEDS_THREE_D = ["z", "rotationX", "rotationY"];
|
|
350
|
+
var CAMERA_ONLY = ["focus", "aperture"];
|
|
212
351
|
var SKEW_KEYS = ["skew", "skewX", "skewY"];
|
|
213
352
|
function lintSequence(spec, warn = defaultWarn) {
|
|
214
|
-
const who =
|
|
215
|
-
const keys =
|
|
353
|
+
const who = chunkBPTW7L25_cjs.describeLayer(spec);
|
|
354
|
+
const keys = chunkBPTW7L25_cjs.collectPropKeys(spec);
|
|
216
355
|
const explained = /* @__PURE__ */ new Set();
|
|
217
356
|
for (const k of keys) {
|
|
218
357
|
const hint = LAYER_ALIASES[k] ?? (spec.type === "camera" ? CAMERA_ALIASES[k] : void 0);
|
|
@@ -237,6 +376,9 @@ function lintSequence(spec, warn = defaultWarn) {
|
|
|
237
376
|
}
|
|
238
377
|
return;
|
|
239
378
|
}
|
|
379
|
+
for (const k of CAMERA_ONLY) {
|
|
380
|
+
if (keys.has(k)) warn(`pixi-effects: ${who}: "${k}" is a camera property and does nothing on this layer: write it in the initial / keyframes of a { type: 'camera' } layer`);
|
|
381
|
+
}
|
|
240
382
|
if (spec.type === "audio") {
|
|
241
383
|
if (spec.threeD) warn(`pixi-effects: ${who}: threeD has no effect on audio`);
|
|
242
384
|
return;
|
|
@@ -251,31 +393,32 @@ function lintSequence(spec, warn = defaultWarn) {
|
|
|
251
393
|
}
|
|
252
394
|
}
|
|
253
395
|
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
return;
|
|
396
|
+
function lintFocus(camera, siblings, warn = defaultWarn) {
|
|
397
|
+
if (camera.type !== "camera") return;
|
|
398
|
+
const who = chunkBPTW7L25_cjs.describeLayer(camera);
|
|
399
|
+
for (const p of chunkIFZOI3JQ_cjs.focusProblems(camera, siblings)) {
|
|
400
|
+
if (p.kind === "missing") {
|
|
401
|
+
warn(`pixi-effects: ${who}: focus: no layer named "${p.name}"${p.hint ? `; did you mean "${p.hint}"?` : ""} (the z = 0 plane is used). Write a threeD layer's name or a z number`);
|
|
402
|
+
} else if (p.kind === "not-threeD") {
|
|
403
|
+
warn(`pixi-effects: ${who}: focus "${p.name}" is not a threeD layer, so it has no depth (the z = 0 plane is used). Write a threeD layer's name or a z number`);
|
|
404
|
+
} else if (p.kind === "duplicate") {
|
|
405
|
+
warn(`pixi-effects: ${who}: focus "${p.name}": ${p.count} layers are named "${p.name}"; the first threeD one is used. Give the layers different names`);
|
|
406
|
+
} else {
|
|
407
|
+
warn(`pixi-effects: ${who}: focus "${p.name}" reads only the first z of that layer; its z moves later and the focus does not follow. Animate focus itself with numbers to follow it`);
|
|
408
|
+
}
|
|
268
409
|
}
|
|
269
|
-
display.blendMode = mode;
|
|
270
410
|
}
|
|
271
411
|
|
|
272
412
|
// src/sequences/Composition.ts
|
|
273
|
-
var CompositionSequence = class extends
|
|
413
|
+
var CompositionSequence = class extends chunkIFZOI3JQ_cjs.Sequence {
|
|
274
414
|
_innerContainer = null;
|
|
275
415
|
_compositionShape = null;
|
|
276
416
|
_children = [];
|
|
277
417
|
_cameras = [];
|
|
278
418
|
_layers3d = [];
|
|
419
|
+
_dofSaid = { behind: false, many: false };
|
|
420
|
+
/** What this composition made for blend modes (filters added to layers' chains, groups and their carrier filters): destroyed with it. */
|
|
421
|
+
_blendOwned = [];
|
|
279
422
|
/** Drawn children in stack order (cameras and target-less sequences excluded). */
|
|
280
423
|
_visual = [];
|
|
281
424
|
/** Layers drawn inside a null layer (`parent`): they are not in the composition's own stack. */
|
|
@@ -328,27 +471,46 @@ var CompositionSequence = class extends chunkNO26HWR7_cjs.Sequence {
|
|
|
328
471
|
this.intrinsicWidth = width;
|
|
329
472
|
this.intrinsicHeight = height;
|
|
330
473
|
this._innerContainer = inner;
|
|
331
|
-
const base =
|
|
332
|
-
const span = base ?
|
|
333
|
-
this._remap = base ?
|
|
474
|
+
const base = chunkIFZOI3JQ_cjs.timeRemapOf(this.spec);
|
|
475
|
+
const span = base ? chunkIFZOI3JQ_cjs.contentLength(base, this.duration) : this.duration;
|
|
476
|
+
this._remap = base ? chunkIFZOI3JQ_cjs.remapOf(this.spec, "time", span) : null;
|
|
334
477
|
this._contentSpan = span;
|
|
335
478
|
this._compositionShape = { width, height, duration: span };
|
|
336
479
|
const lateKeyframes = [];
|
|
337
480
|
for (const s of this.spec.sequences ?? []) {
|
|
338
481
|
lintSequence(s);
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
482
|
+
lintFocus(s, this.spec.sequences ?? []);
|
|
483
|
+
chunkBPTW7L25_cjs.lintTiming(s, span, (message, kind) => kind === "late-keyframe" ? lateKeyframes.push(message) : console.warn(message));
|
|
484
|
+
chunkBPTW7L25_cjs.lintText(s);
|
|
485
|
+
chunkBPTW7L25_cjs.lintKeys(s);
|
|
342
486
|
}
|
|
343
|
-
for (const message of
|
|
344
|
-
this.
|
|
487
|
+
for (const message of chunkBPTW7L25_cjs.summarizeWarnings(lateKeyframes)) console.warn(message);
|
|
488
|
+
const crowd = chunkK4JVI5HK_cjs.maxConcurrentAdvanced(this.spec.sequences ?? [], span);
|
|
489
|
+
if (crowd >= chunkK4JVI5HK_cjs.MANY_ADVANCED) {
|
|
490
|
+
console.warn(`pixi-effects: ${chunkBPTW7L25_cjs.describeLayer(this.spec)}: ${crowd} layers with an advanced blendMode are on screen at once (a composition with one counts each layer inside it, since its children blend one by one); each is a full-frame pass (about 2 ms on WebGL). Put fewer layers in the blend (or draw the glow as one layer), or use add / screen / multiply`);
|
|
491
|
+
}
|
|
492
|
+
this._children = await chunkIFZOI3JQ_cjs.buildSequenceTree(
|
|
345
493
|
this.spec.sequences ?? [],
|
|
346
494
|
this._compositionShape,
|
|
347
495
|
this.root
|
|
348
496
|
);
|
|
349
497
|
this._resolveParents();
|
|
498
|
+
const layerNames = new Set(this._children.map((c) => c.spec.name).filter((n) => !!n));
|
|
499
|
+
for (const cam of this._children) {
|
|
500
|
+
if (!(cam instanceof chunkIFZOI3JQ_cjs.CameraSequence)) continue;
|
|
501
|
+
cam.resolveFocusNames((name) => {
|
|
502
|
+
const hit = this._children.find((c) => c.spec.name === name && c.spec.threeD);
|
|
503
|
+
return hit ? chunkIFZOI3JQ_cjs.layerInitialZ(hit.spec, hit.scope()) : void 0;
|
|
504
|
+
}, layerNames);
|
|
505
|
+
}
|
|
506
|
+
const blendSaid = /* @__PURE__ */ new Map();
|
|
507
|
+
const report = (message, spec) => {
|
|
508
|
+
const seen = blendSaid.get(message);
|
|
509
|
+
if (seen) seen.n++;
|
|
510
|
+
else blendSaid.set(message, { spec, n: 1 });
|
|
511
|
+
};
|
|
350
512
|
for (const child of this._children) {
|
|
351
|
-
if (child instanceof
|
|
513
|
+
if (child instanceof chunkIFZOI3JQ_cjs.CameraSequence) {
|
|
352
514
|
this._cameras.push(child);
|
|
353
515
|
continue;
|
|
354
516
|
}
|
|
@@ -361,25 +523,57 @@ var CompositionSequence = class extends chunkNO26HWR7_cjs.Sequence {
|
|
|
361
523
|
inner.addChild(layer.display);
|
|
362
524
|
this._layers3d.push(layer);
|
|
363
525
|
this._visual.push({ seq: child, layer });
|
|
364
|
-
applyBlendMode(child.spec, layer.display);
|
|
526
|
+
const added3d = chunkK4JVI5HK_cjs.applyBlendMode(child.spec, layer.display, report);
|
|
527
|
+
if (added3d) this._blendOwned.push(added3d);
|
|
365
528
|
if (maskSpec) {
|
|
366
|
-
console.warn(`pixi-effects: ${
|
|
529
|
+
console.warn(`pixi-effects: ${chunkBPTW7L25_cjs.describeLayer(child.spec)}: mask is not supported on threeD layers yet; ignored`);
|
|
367
530
|
}
|
|
368
531
|
continue;
|
|
369
532
|
}
|
|
370
|
-
|
|
533
|
+
const mode = child.spec.blendMode;
|
|
534
|
+
const eraseMask = !!maskSpec && child.spec.maskInverted === true && mode !== void 0 && mode !== "normal" && chunkK4JVI5HK_cjs.blendProblem(mode) === null;
|
|
535
|
+
const alphaMaskLosesBlend = !!maskSpec && (maskSpec.type === "text" || maskSpec.type === "image" || maskSpec.type === "video") && !eraseMask && mode !== void 0 && mode !== "normal" && chunkK4JVI5HK_cjs.blendProblem(mode) === null;
|
|
536
|
+
if (alphaMaskLosesBlend) {
|
|
537
|
+
report(`blendMode "${mode}" cannot be used together with ${maskSpec.type === "image" ? "an" : "a"} ${maskSpec.type} layer as the mask (the blend is lost); the layer is drawn normal. Put the ${maskSpec.type} on a layer of its own with the blendMode instead of masking with it, or use maskInverted`, child.spec);
|
|
538
|
+
}
|
|
539
|
+
let wrap;
|
|
540
|
+
if (eraseMask) {
|
|
541
|
+
wrap = new pixi_js.Container();
|
|
542
|
+
wrap.addChild(child.target);
|
|
543
|
+
let carrier = null;
|
|
544
|
+
if (chunkK4JVI5HK_cjs.isAdvancedBlend(mode)) carrier = chunkK4JVI5HK_cjs.blendFilterFor(mode);
|
|
545
|
+
else {
|
|
546
|
+
const f = new pixi_js.AlphaFilter({ alpha: 1 });
|
|
547
|
+
f.blendMode = mode;
|
|
548
|
+
carrier = f;
|
|
549
|
+
}
|
|
550
|
+
if (carrier) {
|
|
551
|
+
wrap.filters = [carrier];
|
|
552
|
+
this._blendOwned.push(carrier);
|
|
553
|
+
} else report(chunkK4JVI5HK_cjs.blendUnavailableMessage(mode), child.spec);
|
|
554
|
+
this._blendOwned.push(wrap);
|
|
555
|
+
into.addChild(wrap);
|
|
556
|
+
} else into.addChild(child.target);
|
|
371
557
|
if (holder) this._nested.push(child);
|
|
372
|
-
else this._visual.push({ seq: child, layer: null });
|
|
373
|
-
|
|
558
|
+
else this._visual.push({ seq: child, layer: null, wrap });
|
|
559
|
+
if (!wrap && !alphaMaskLosesBlend) {
|
|
560
|
+
const added = chunkK4JVI5HK_cjs.applyBlendMode(child.spec, child.target, report);
|
|
561
|
+
if (added) this._blendOwned.push(added);
|
|
562
|
+
}
|
|
374
563
|
if (maskSpec) {
|
|
375
564
|
const lifetime = maskSpec.at === void 0 ? { at: child.at, duration: maskSpec.duration ?? child.duration } : {};
|
|
376
|
-
const built = await
|
|
565
|
+
const built = await chunkIFZOI3JQ_cjs.buildSequenceTree([{ ...maskSpec, ...lifetime }], this._compositionShape, this.root);
|
|
377
566
|
const maskSeq = built[0];
|
|
378
567
|
if (maskSeq?.target) {
|
|
379
|
-
into.addChild(maskSeq.target);
|
|
568
|
+
(wrap ?? into).addChild(maskSeq.target);
|
|
380
569
|
const inverse = child.spec.maskInverted ?? false;
|
|
381
570
|
const t = child.target;
|
|
382
|
-
if (
|
|
571
|
+
if (wrap) {
|
|
572
|
+
const mt = maskSeq.target;
|
|
573
|
+
const mf = Array.isArray(mt.filters) && mt.filters.length > 0 ? mt.filters[mt.filters.length - 1] : null;
|
|
574
|
+
if (mf) mf.blendMode = "erase";
|
|
575
|
+
else mt.blendMode = "erase";
|
|
576
|
+
} else if (inverse || maskSpec.type === "text") {
|
|
383
577
|
const effect = new pixi_js.AlphaMask({ mask: maskSeq.target });
|
|
384
578
|
effect.inverse = inverse;
|
|
385
579
|
t.setMask?.({ mask: void 0, inverse });
|
|
@@ -390,14 +584,17 @@ var CompositionSequence = class extends chunkNO26HWR7_cjs.Sequence {
|
|
|
390
584
|
t.mask = maskSeq.target;
|
|
391
585
|
}
|
|
392
586
|
child.maskSequence = maskSeq;
|
|
393
|
-
maskSeq.keepHidden = maskSpec.type === "image" || maskSpec.type === "video";
|
|
587
|
+
maskSeq.keepHidden = !wrap && (maskSpec.type === "image" || maskSpec.type === "video");
|
|
394
588
|
}
|
|
395
589
|
}
|
|
396
590
|
}
|
|
591
|
+
for (const [message, seen] of blendSaid) {
|
|
592
|
+
console.warn(`pixi-effects: ${chunkBPTW7L25_cjs.describeLayer(seen.spec)}: ${message}${seen.n > 1 ? ` (and ${seen.n - 1} more layers have the same mistake)` : ""}`);
|
|
593
|
+
}
|
|
397
594
|
if (this._layers3d.length > 0) {
|
|
398
595
|
inner.sortableChildren = true;
|
|
399
596
|
this._visual.forEach((v, i) => {
|
|
400
|
-
(v.layer?.display ?? v.seq.target).zIndex = i;
|
|
597
|
+
(v.layer?.display ?? v.wrap ?? v.seq.target).zIndex = i;
|
|
401
598
|
});
|
|
402
599
|
} else if (this._cameras.length > 0) {
|
|
403
600
|
console.warn("pixi-effects: camera has no effect: this composition has no threeD layers");
|
|
@@ -445,11 +642,11 @@ var CompositionSequence = class extends chunkNO26HWR7_cjs.Sequence {
|
|
|
445
642
|
this._clock = clock;
|
|
446
643
|
const scope = this.scope();
|
|
447
644
|
if (remap.start !== void 0 && remap.timeKfs.length === 0) clock.time = remap.start;
|
|
448
|
-
|
|
645
|
+
chunkIFZOI3JQ_cjs.bindClock(timeline, clock, "time", remap, this.duration, offset + this.at, scope);
|
|
449
646
|
inner.time(inner.duration());
|
|
450
647
|
inner.time(0);
|
|
451
648
|
last = NaN;
|
|
452
|
-
this._warnUnreachable(
|
|
649
|
+
this._warnUnreachable(chunkIFZOI3JQ_cjs.clockTable(remap, "time", this.duration, offset + this.at, scope, offset + this.at + this.duration), offset + this.at, offset + this.at + this.duration);
|
|
453
650
|
}
|
|
454
651
|
/**
|
|
455
652
|
* A child the clock never dwells in is never visible: say so. Its `at` is in THIS composition's local time, so the usual mistake is
|
|
@@ -473,7 +670,7 @@ var CompositionSequence = class extends chunkNO26HWR7_cjs.Sequence {
|
|
|
473
670
|
}
|
|
474
671
|
if (dwell >= 2) continue;
|
|
475
672
|
console.warn(
|
|
476
|
-
`pixi-effects: ${
|
|
673
|
+
`pixi-effects: ${chunkBPTW7L25_cjs.describeLayer(child.spec)} starts at ${at}s of ${chunkBPTW7L25_cjs.describeLayer(this.spec)}'s own time, but its clock only reaches ${Number(table.min.toFixed(3))}\u2013${Number(table.max.toFixed(3))}s (${how}), so it is never visible. Layers inside a remapped composition are placed in that composition's local time.`
|
|
477
674
|
);
|
|
478
675
|
}
|
|
479
676
|
}
|
|
@@ -487,26 +684,27 @@ var CompositionSequence = class extends chunkNO26HWR7_cjs.Sequence {
|
|
|
487
684
|
for (let p = this._parentOf.get(seq); p; p = this._parentOf.get(p)) out.push(p);
|
|
488
685
|
return out;
|
|
489
686
|
};
|
|
490
|
-
return [...this._visual.map((v) => v.seq), ...this._nested].filter((seq) => !(seq instanceof
|
|
687
|
+
return [...this._visual.map((v) => v.seq), ...this._nested].filter((seq) => !(seq instanceof chunkIFZOI3JQ_cjs.NullSequence)).map((seq) => {
|
|
491
688
|
const layer = this._visual.find((v) => v.seq === seq)?.layer ?? null;
|
|
492
689
|
return {
|
|
493
690
|
seq,
|
|
494
691
|
display: layer?.display ?? seq.target,
|
|
495
692
|
threeD: layer !== null,
|
|
496
|
-
carriers: carriersOf(seq)
|
|
693
|
+
carriers: carriersOf(seq),
|
|
694
|
+
depthBlur: layer?.blur ?? 0
|
|
497
695
|
};
|
|
498
696
|
});
|
|
499
697
|
}
|
|
500
698
|
/** Match every `parent: 'name'` to a null layer; anything that cannot work is said out loud and drawn unparented. */
|
|
501
699
|
_resolveParents() {
|
|
502
|
-
const nulls = this._children.filter((c) => c instanceof
|
|
700
|
+
const nulls = this._children.filter((c) => c instanceof chunkIFZOI3JQ_cjs.NullSequence);
|
|
503
701
|
const nullNames = nulls.map((n) => n.spec.name).filter((n) => !!n);
|
|
504
702
|
const warned = /* @__PURE__ */ new Set();
|
|
505
703
|
for (const child of this._children) {
|
|
506
704
|
const want = child.spec.parent;
|
|
507
705
|
if (want === void 0) continue;
|
|
508
|
-
const who =
|
|
509
|
-
if (child instanceof
|
|
706
|
+
const who = chunkBPTW7L25_cjs.describeLayer(child.spec);
|
|
707
|
+
if (child instanceof chunkIFZOI3JQ_cjs.CameraSequence) {
|
|
510
708
|
console.warn(`pixi-effects: ${who}: a camera cannot have a parent; ignored`);
|
|
511
709
|
continue;
|
|
512
710
|
}
|
|
@@ -516,11 +714,11 @@ var CompositionSequence = class extends chunkNO26HWR7_cjs.Sequence {
|
|
|
516
714
|
}
|
|
517
715
|
const same = this._children.filter((c) => c.spec.name === want);
|
|
518
716
|
if (same.length === 0) {
|
|
519
|
-
const hint =
|
|
717
|
+
const hint = chunkUZTKEYFP_cjs.suggestName(want, nullNames);
|
|
520
718
|
console.warn(`pixi-effects: ${who}: parent "${want}": no layer with that name${hint ? `; did you mean "${hint}"?` : ""} (the layer is drawn without a parent)`);
|
|
521
719
|
continue;
|
|
522
720
|
}
|
|
523
|
-
const holder = same.find((c) => c instanceof
|
|
721
|
+
const holder = same.find((c) => c instanceof chunkIFZOI3JQ_cjs.NullSequence);
|
|
524
722
|
if (!holder) {
|
|
525
723
|
console.warn(`pixi-effects: ${who}: parent "${want}" is a ${same[0].spec.type} layer; only { type: 'null' } layers can be parents (the layer is drawn without a parent)`);
|
|
526
724
|
continue;
|
|
@@ -560,12 +758,14 @@ var CompositionSequence = class extends chunkNO26HWR7_cjs.Sequence {
|
|
|
560
758
|
const { width, height } = this._compositionShape;
|
|
561
759
|
const compEnd = this._childBase + (this.duration ?? 0);
|
|
562
760
|
const active = pickActiveCamera(
|
|
563
|
-
this._cameras.map((
|
|
761
|
+
this._cameras.map((cam2) => ({ cam: cam2, ...cam2.window() })),
|
|
564
762
|
childT,
|
|
565
763
|
compEnd
|
|
566
764
|
);
|
|
567
|
-
const
|
|
765
|
+
const cam = active ? active.cam.state() : chunkIFZOI3JQ_cjs.homeCamera(width, height);
|
|
766
|
+
const basis = chunkIFZOI3JQ_cjs.cameraBasis(cam, width, height);
|
|
568
767
|
for (const layer of this._layers3d) layer.update(host, basis);
|
|
768
|
+
this._applyDepthOfField(cam, basis);
|
|
569
769
|
const order = assignDepthOrder(
|
|
570
770
|
this._visual.map((v, i) => ({ stackIndex: i, threeD: v.layer !== null, depth: v.layer?.depth ?? 0 }))
|
|
571
771
|
);
|
|
@@ -573,6 +773,32 @@ var CompositionSequence = class extends chunkNO26HWR7_cjs.Sequence {
|
|
|
573
773
|
if (v.layer) v.layer.display.zIndex = order[i];
|
|
574
774
|
});
|
|
575
775
|
}
|
|
776
|
+
/** Depth of field: each threeD layer is blurred by how far its depth is from the focal plane (a pure function of the camera and the layers). */
|
|
777
|
+
_applyDepthOfField(cam, basis) {
|
|
778
|
+
const aperture = cam.aperture ?? 0;
|
|
779
|
+
if (!(aperture > 0)) {
|
|
780
|
+
for (const l of this._layers3d) l.setBlur(0);
|
|
781
|
+
return;
|
|
782
|
+
}
|
|
783
|
+
const focusDepth = chunkIFZOI3JQ_cjs.projectPoint(basis, { x: cam.lookAtX, y: cam.lookAtY, z: cam.focus ?? 0 }).depth;
|
|
784
|
+
if (!(focusDepth > chunkIFZOI3JQ_cjs.NEAR)) {
|
|
785
|
+
if (!this._dofSaid.behind) {
|
|
786
|
+
this._dofSaid.behind = true;
|
|
787
|
+
console.warn(`pixi-effects: ${chunkBPTW7L25_cjs.describeLayer(this.spec)}: the camera's focus (z = ${(cam.focus ?? 0).toFixed(0)}) is at or behind the camera, so nothing is blurred. Put focus in front of the camera (a z below the camera's z)`);
|
|
788
|
+
}
|
|
789
|
+
for (const l of this._layers3d) l.setBlur(0);
|
|
790
|
+
return;
|
|
791
|
+
}
|
|
792
|
+
let blurred = 0;
|
|
793
|
+
for (const l of this._layers3d) {
|
|
794
|
+
l.setBlur(l.display.visible ? chunkIFZOI3JQ_cjs.blurRadius(aperture, basis.focal, l.depth, focusDepth) : 0);
|
|
795
|
+
if (l.blur > 0) blurred++;
|
|
796
|
+
}
|
|
797
|
+
if (blurred >= chunkIFZOI3JQ_cjs.MANY_BLURRED && !this._dofSaid.many) {
|
|
798
|
+
this._dofSaid.many = true;
|
|
799
|
+
console.warn(`pixi-effects: ${chunkBPTW7L25_cjs.describeLayer(this.spec)}: ${blurred} layers are blurred by depth of field at once; each costs a filter pass per frame (WebGPU more). Merge the far layers or lower aperture`);
|
|
800
|
+
}
|
|
801
|
+
}
|
|
576
802
|
collectAudio(out, baseTime) {
|
|
577
803
|
super.collectAudio(out, baseTime);
|
|
578
804
|
const remap = this._remap;
|
|
@@ -584,7 +810,7 @@ var CompositionSequence = class extends chunkNO26HWR7_cjs.Sequence {
|
|
|
584
810
|
const inner = [];
|
|
585
811
|
for (const child of this._children) child.collectAudio(inner, 0);
|
|
586
812
|
const lo = baseTime + this.at, hi = lo + this.duration;
|
|
587
|
-
const table =
|
|
813
|
+
const table = chunkIFZOI3JQ_cjs.clockTable(remap, "time", this.duration, lo, this.scope(), hi);
|
|
588
814
|
for (const d of inner) {
|
|
589
815
|
const prev = d.warp;
|
|
590
816
|
out.push({ ...d, warp: (t) => t < lo || t > hi ? NaN : prev ? prev(table.at(t)) : table.at(t) });
|
|
@@ -597,6 +823,8 @@ var CompositionSequence = class extends chunkNO26HWR7_cjs.Sequence {
|
|
|
597
823
|
for (const l of this._layers3d) l.destroy();
|
|
598
824
|
this._layers3d = [];
|
|
599
825
|
for (const c of this._children) c.destroy();
|
|
826
|
+
for (const o of this._blendOwned) o.destroy();
|
|
827
|
+
this._blendOwned = [];
|
|
600
828
|
super.destroy();
|
|
601
829
|
}
|
|
602
830
|
};
|
|
@@ -608,5 +836,5 @@ function frameOf(child) {
|
|
|
608
836
|
}
|
|
609
837
|
|
|
610
838
|
exports.CompositionSequence = CompositionSequence;
|
|
611
|
-
//# sourceMappingURL=chunk-
|
|
612
|
-
//# sourceMappingURL=chunk-
|
|
839
|
+
//# sourceMappingURL=chunk-MHOO2CVU.cjs.map
|
|
840
|
+
//# sourceMappingURL=chunk-MHOO2CVU.cjs.map
|