pixi-effects 0.40.0 → 0.41.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.
Files changed (57) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +5 -5
  3. package/ai/chat-template.html +3 -3
  4. package/ai/tools/check.mjs +19 -2
  5. package/dist/Composition-N6BOROJ2.cjs +16 -0
  6. package/dist/{Composition-C3UEVHQG.cjs.map → Composition-N6BOROJ2.cjs.map} +1 -1
  7. package/dist/Composition-YGBQX3HZ.js +7 -0
  8. package/dist/{Composition-KRWH72MA.js.map → Composition-YGBQX3HZ.js.map} +1 -1
  9. package/dist/Controller.d.cts +1 -1
  10. package/dist/Controller.d.ts +1 -1
  11. package/dist/{Movie-CG6Jy1tx.d.ts → Movie-CwqRLOzE.d.ts} +47 -1
  12. package/dist/{Movie-CMq4KFmc.d.cts → Movie-DWtxRiJ2.d.cts} +47 -1
  13. package/dist/{Spans-TWO4VN5H.js → Spans-6L2ZVECX.js} +4 -4
  14. package/dist/{Spans-TWO4VN5H.js.map → Spans-6L2ZVECX.js.map} +1 -1
  15. package/dist/{Spans-APNJHCYO.cjs → Spans-XTIWYSNO.cjs} +9 -9
  16. package/dist/{Spans-APNJHCYO.cjs.map → Spans-XTIWYSNO.cjs.map} +1 -1
  17. package/dist/{chunk-27PYJ4JY.cjs → chunk-3HZV3UHU.cjs} +67 -63
  18. package/dist/chunk-3HZV3UHU.cjs.map +1 -0
  19. package/dist/{chunk-LMWXR5OC.js → chunk-4QVQ5UJJ.js} +4 -4
  20. package/dist/{chunk-LMWXR5OC.js.map → chunk-4QVQ5UJJ.js.map} +1 -1
  21. package/dist/{chunk-26Z544SH.js → chunk-ICI6ACHY.js} +7 -3
  22. package/dist/chunk-ICI6ACHY.js.map +1 -0
  23. package/dist/{chunk-LEL7UNYQ.cjs → chunk-RN5FWGGM.cjs} +136 -39
  24. package/dist/chunk-RN5FWGGM.cjs.map +1 -0
  25. package/dist/{chunk-7EI2N7WO.cjs → chunk-X62H3RBG.cjs} +4 -4
  26. package/dist/{chunk-7EI2N7WO.cjs.map → chunk-X62H3RBG.cjs.map} +1 -1
  27. package/dist/{chunk-CT5CZVT5.js → chunk-Y2N6U3X5.js} +101 -4
  28. package/dist/chunk-Y2N6U3X5.js.map +1 -0
  29. package/dist/index.cjs +33 -33
  30. package/dist/index.d.cts +1 -1
  31. package/dist/index.d.ts +1 -1
  32. package/dist/index.js +3 -3
  33. package/dist/loader.css +1 -1
  34. package/dist/present.cjs +3 -3
  35. package/dist/present.d.cts +1 -1
  36. package/dist/present.d.ts +1 -1
  37. package/dist/present.js +3 -3
  38. package/dist/three.cjs +52 -6
  39. package/dist/three.cjs.map +1 -1
  40. package/dist/three.d.cts +16 -1
  41. package/dist/three.d.ts +16 -1
  42. package/dist/three.js +49 -3
  43. package/dist/three.js.map +1 -1
  44. package/docs/api.md +17 -0
  45. package/docs/dsl.md +1 -1
  46. package/llms-full.txt +44 -3
  47. package/package.json +1 -1
  48. package/skills/pixi-effects/SKILL.md +2 -2
  49. package/skills/pixi-effects/reference/cheatsheet.md +1 -0
  50. package/skills/pixi-effects/reference/recipes.md +23 -0
  51. package/skills/pixi-effects/template.html +6 -6
  52. package/dist/Composition-C3UEVHQG.cjs +0 -16
  53. package/dist/Composition-KRWH72MA.js +0 -7
  54. package/dist/chunk-26Z544SH.js.map +0 -1
  55. package/dist/chunk-27PYJ4JY.cjs.map +0 -1
  56. package/dist/chunk-CT5CZVT5.js.map +0 -1
  57. package/dist/chunk-LEL7UNYQ.cjs.map +0 -1
package/dist/three.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/three/defaults.ts","../src/three/spaceBridge.ts","../src/three/budget.ts","../src/three/ThreeSequence.ts","../src/three/gltf.ts","../src/three/index.ts"],"names":["PerspectiveCamera"],"mappings":"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","file":"three.js","sourcesContent":["/** The page-level default renderer of the three layers: `registerThree({ renderer })` sets it, a layer's own `renderer` wins. */\nexport type ThreeRendererKind = 'webgl' | 'webgpu';\n\nlet pageRenderer: ThreeRendererKind = 'webgl';\n\nexport function checkRendererKind(kind: unknown, where: string): asserts kind is ThreeRendererKind {\n if (kind !== 'webgl' && kind !== 'webgpu') throw new Error(`pixi-effects: ${where} must be 'webgl' or 'webgpu' (got ${JSON.stringify(kind)})`);\n}\nexport function setPageRenderer(kind: ThreeRendererKind): void { pageRenderer = kind; }\nexport function getPageRenderer(): ThreeRendererKind { return pageRenderer; }\n","/**\n * What lets a `three` layer live in the composition's space (`followCamera`, `followLights`): the composition's camera and lights, in three.\n *\n * The scene is in composition pixels with y flipped: a point the composition calls (x, y, z) is `new Vector3(x, -y, z)` here (the composition's y runs down, three's up;\n * +z is toward the viewer in both). A three camera with the composition camera's position, look-at point and vertical fov then projects that point to the pixel the\n * composition's own projection gives it (tests/three/spaceBridge.test.ts checks it to 1e-6 px).\n */\nimport { AmbientLight, Color, DirectionalLight, Fog, OrthographicCamera, PerspectiveCamera, PointLight, SRGBColorSpace, SpotLight, type Light, type Object3D, type Scene } from 'three';\nimport type { CameraState } from '../space/math';\nimport type { LightState } from '../space/lighting';\nimport type { FogState } from '../space/LitMaterial';\n\n/** The camera's near plane and far plane in composition pixels: the home camera sits about 740 px from the picture, a long dolly can be several thousand. */\nconst NEAR = 1;\nconst FAR = 20000;\n\n/** Put a three camera where the composition camera is. The aspect is the layer's (it must be the composition's: see `followCamera`). */\nexport function applyCameraState(camera: PerspectiveCamera, s: CameraState, aspect: number): void {\n camera.fov = s.fov;\n camera.aspect = aspect;\n camera.near = NEAR;\n camera.far = FAR;\n camera.up.set(0, 1, 0);\n camera.position.set(s.x, -s.y, s.z);\n const same = Math.hypot(s.lookAtX - s.x, s.lookAtY - s.y, s.lookAtZ - s.z) < 1e-9; // the composition then looks along -z\n camera.lookAt(same ? s.x : s.lookAtX, same ? -s.y : -s.lookAtY, same ? s.z - 1 : s.lookAtZ);\n camera.updateProjectionMatrix();\n camera.updateMatrixWorld();\n}\n\ninterface Entry { kind: LightState['kind']; light: Light; target: Object3D | null }\n\n/**\n * The composition's lights as three lights, one per light layer alive, in layer order. The objects are made once and moved every frame (a light that has ended is switched off,\n * not removed: the shader of a three layer must not be rebuilt as lights come and go).\n *\n * Intensity: three divides a diffuse surface by pi, so a light of intensity 1 is multiplied by pi to be \"as bright as the colour\" like a card's shading. Falloff: 'none' is no\n * attenuation; 'inverseSquare' is decay 2 with the intensity scaled so it is full at `radius`; 'smooth' is three's own cutoff at radius + falloffDistance (the same idea, not the\n * same curve). Shadows follow the light (castsShadows: the layer's own meshes cast and receive).\n */\nexport class LightMirror {\n private entries: Entry[] = [];\n /** True when a light alive casts shadows: the layer's renderer must have its shadow map on. */\n castsShadows = false;\n constructor(private readonly scene: Object3D, private readonly extent = 2000) {}\n\n update(lights: readonly LightState[]): void {\n this.castsShadows = lights.some((s) => s.castsShadows && s.kind !== 'ambient');\n lights.forEach((s, i) => {\n let e = this.entries[i];\n if (!e || e.kind !== s.kind) {\n if (e) this.remove(e);\n e = this.entries[i] = this.make(s.kind);\n }\n this.configure(e, s);\n });\n for (let i = lights.length; i < this.entries.length; i++) this.entries[i]!.light.visible = false;\n }\n\n dispose(): void {\n for (const e of this.entries) this.remove(e);\n this.entries = [];\n }\n\n private make(kind: LightState['kind']): Entry {\n const light: Light = kind === 'ambient' ? new AmbientLight() : kind === 'parallel' ? new DirectionalLight() : kind === 'spot' ? new SpotLight() : new PointLight();\n light.name = 'pixi-effects:composition-light';\n const target = (light as DirectionalLight | SpotLight).target ?? null;\n this.scene.add(light);\n if (target) this.scene.add(target);\n return { kind, light, target };\n }\n\n private remove(e: Entry): void {\n this.scene.remove(e.light);\n if (e.target) this.scene.remove(e.target);\n }\n\n private configure(e: Entry, s: LightState): void {\n const { light } = e;\n light.visible = true;\n light.color = (light.color ?? new Color()).setRGB(s.r, s.g, s.b, SRGBColorSpace);\n let intensity = s.intensity * Math.PI;\n if (s.kind !== 'ambient') {\n light.position.set(s.x, -s.y, s.z);\n e.target?.position.set(s.lookAtX, -s.lookAtY, s.lookAtZ);\n }\n if (s.kind === 'point' || s.kind === 'spot') {\n const l = light as PointLight | SpotLight;\n if (s.falloff === 'inverseSquare') { l.distance = 0; l.decay = 2; intensity *= s.radius * s.radius; }\n else if (s.falloff === 'smooth') { l.distance = s.radius + s.falloffDistance; l.decay = 0; }\n else { l.distance = 0; l.decay = 0; }\n }\n if (s.kind === 'spot') {\n const l = light as SpotLight;\n l.angle = ((s.coneAngle / 2) * Math.PI) / 180;\n l.penumbra = s.coneFeather;\n }\n light.intensity = intensity;\n if (s.kind !== 'ambient') {\n const l = light as PointLight | SpotLight | DirectionalLight;\n l.castShadow = s.castsShadows;\n if (s.castsShadows) {\n l.shadow.mapSize.set(2048, 2048);\n l.shadow.intensity = s.shadowDarkness;\n l.shadow.radius = Math.max(1, s.shadowDiffusion / 4);\n // Scale-aware: three compares depths AFTER the perspective divide, so a bias of b is about b·d²/near world units at distance d from the light. A near plane of 1 px and a bias of\n // -0.0005 hid every caster within ~250 px of its receiver at 1280 x 720 (found by an AI trial). The near plane follows the size of the composition (~20 px at 1280 x 720) and the\n // bias is small, so the gap is about a pixel or two; normalBias (world units, along the surface normal) is a pixel or two too.\n l.shadow.bias = -0.00005;\n l.shadow.normalBias = this.extent / 1000;\n const cam = l.shadow.camera;\n cam.near = Math.max(1, this.extent / 128); cam.far = 20000;\n if (s.kind === 'parallel') { const o = cam as OrthographicCamera; o.left = -this.extent; o.right = this.extent; o.top = this.extent; o.bottom = -this.extent; }\n cam.updateProjectionMatrix();\n }\n }\n light.updateMatrixWorld?.();\n e.target?.updateMatrixWorld?.();\n }\n}\n\n/**\n * The composition camera's fog as the scene's `Fog`: the same colour, `near` and `far` (distances along the view, in composition pixels). three's Fog fades with `smoothstep` where the\n * composition's fades linearly, and has no amount below 1: close, not equal (see docs/dsl.md). The Fog is made when the camera has one and removed when it has not; a Fog the layer made\n * itself is never touched.\n */\nexport class FogMirror {\n private own: Fog | null = null;\n constructor(private readonly scene: Scene) {}\n\n update(fog: FogState | null): void {\n if (!fog) {\n if (this.own && this.scene.fog === this.own) this.scene.fog = null;\n this.own = null;\n return;\n }\n if (!this.own || this.scene.fog !== this.own) {\n if (this.scene.fog && this.scene.fog !== this.own) return; // the layer has its own fog: leave it\n this.own = new Fog(0x000000, fog.near, fog.far);\n this.scene.fog = this.own;\n }\n this.own.color.setRGB(fog.r, fog.g, fog.b, SRGBColorSpace);\n this.own.near = fog.near;\n this.own.far = fog.far;\n }\n\n dispose(): void { this.update(null); }\n}\n","/**\n * How many three layers a page can hold. Each `three` layer owns a renderer, and a browser keeps only so many live graphics contexts for a whole page: about 16 for WebGL, about 32 for\n * WebGPU (measured 2026-10-15 on Chrome: layers beyond it draw nothing, without an error). PixiJS and a `shader` layer use contexts of their own, so the warning comes a little before the\n * limit: more than 12 WebGL layers, more than 28 WebGPU layers.\n */\nexport type ThreeKind = 'webgl' | 'webgpu';\n\nconst WARN_ABOVE: Record<ThreeKind, number> = { webgl: 12, webgpu: 28 };\nconst LIMIT: Record<ThreeKind, string> = { webgl: 'about 16 WebGL contexts', webgpu: 'about 32 WebGPU contexts' };\nconst live: Record<ThreeKind, number> = { webgl: 0, webgpu: 0 };\nconst warned = new Set<ThreeKind>();\n\n/** A three layer made its renderer: count it, and say once per kind when the page holds too many. */\nexport function trackThree(kind: ThreeKind): void {\n live[kind]++;\n if (live[kind] > WARN_ABOVE[kind] && !warned.has(kind)) {\n warned.add(kind);\n console.warn(`pixi-effects: ${live[kind]} three layers are alive with renderer: '${kind}', and a browser keeps ${LIMIT[kind]} for the whole page; layers beyond that draw nothing, without an error. ` +\n `Put several objects in one three layer, destroy layers that are over, ` + (kind === 'webgl' ? `or use renderer: 'webgpu' for some (its limit is about 32)` : `or use renderer: 'webgl' for some of them (a different pool of contexts)`));\n }\n}\n\n/** A three layer let its renderer go. */\nexport function releaseThree(kind: ThreeKind): void {\n live[kind] = Math.max(0, live[kind] - 1);\n}\n\n/** What the page holds now, per renderer. */\nexport function threeBudget(): Record<ThreeKind, number> {\n return { ...live };\n}\n\n/** For tests: forget everything. */\nexport function resetThreeBudget(): void {\n live.webgl = live.webgpu = 0;\n warned.clear();\n}\n","import { Sprite, Texture } from 'pixi.js';\nimport { PerspectiveCamera, Scene, WebGLRenderer, type Camera } from 'three';\nimport type { WebGPURenderer } from 'three/webgpu';\nimport { Sequence } from '../sequences/Base';\nimport { buildScope } from '../expr/Scope';\nimport { evaluateExpr } from '../expr/Parser';\nimport type { PathRouters } from '../core/Timeline';\nimport type { PropValue } from '../types';\nimport type { ThreeContext, ThreeSequenceSpec } from './types';\nimport { checkRendererKind, getPageRenderer } from './defaults';\nimport { applyCameraState, FogMirror, LightMirror } from './spaceBridge';\nimport { releaseThree, trackThree } from './budget';\nimport type { CanvasCheck } from '../sequences/Canvas';\n\n/** What makes a frame depend on more than the time (the same list as the canvas layer's). */\nconst NOT_PURE = /\\bMath\\s*\\.\\s*random\\s*\\(|\\bDate\\s*\\.\\s*now\\s*\\(|\\bperformance\\s*\\.\\s*now\\s*\\(|\\bnew\\s+Date\\s*\\(/;\n\nexport class ThreeSequence extends Sequence {\n private _renderer: WebGLRenderer | WebGPURenderer | null = null;\n /** The renderer this layer draws with (`'webgl'` or `'webgpu'`), once it is built. */\n renderer: 'webgl' | 'webgpu' | null = null;\n /** The backend under it: `'webgl'`, `'webgpu'`, or `'webgl2'` when three's WebGPURenderer found no WebGPU in this browser and used its own WebGL2 backend (the same picture). */\n backend: 'webgl' | 'webgpu' | 'webgl2' | null = null;\n private _gpu = false; // renderer: 'webgpu': async init and async render\n private _scene: Scene | null = null;\n private _camera: Camera | null = null;\n private _ctx: ThreeContext | null = null;\n private _objects: Record<string, object> = {};\n private _warnedUpdate = false;\n private _warnedNodeFrame = false;\n private _warnedPaths = new Set<string>();\n private _lightMirror: LightMirror | null = null;\n private _fogMirror: FogMirror | null = null;\n private _warnedSpace = new Set<string>();\n private _tracked = false;\n\n private get _threeSpec(): ThreeSequenceSpec {\n return this.spec as unknown as ThreeSequenceSpec;\n }\n\n protected override pathRouters(): PathRouters {\n return { three: (path) => this._resolveThreePath(path) };\n }\n\n async build(): Promise<void> {\n const spec = this._threeSpec;\n if (this.duration === undefined) {\n this.duration = this.parent?.duration ?? this.root.duration;\n }\n if (typeof spec.update === 'function' && NOT_PURE.test(spec.update.toString())) {\n console.warn(`pixi-effects: three layer${spec.name ? ` \"${spec.name}\"` : ''}: update calls Math.random, Date.now, performance.now or new Date, so it is not deterministic: the same frame would draw differently in playback, in a seek and in an export. Derive the value from t`);\n }\n\n // Resolve layer size. Expressions see the usual scope; intrinsic w/h are\n // still 0 here (same chicken-and-egg as shapes), so W/H/GW/GH carry it.\n const scope = buildScope(this, this.parent, this.root) as unknown as Record<string, number>;\n const width = resolveDim(spec.width, scope) ?? this.parent?.width ?? this.root.width;\n const height = resolveDim(spec.height, scope) ?? this.parent?.height ?? this.root.height;\n const resolution = spec.resolution ?? 1;\n\n // Offscreen canvas — never attached to the DOM. document.createElement\n // (not OffscreenCanvas) so PIXI's Texture.from and three both accept it.\n const canvas = document.createElement('canvas');\n const antialias = spec.antialias ?? true;\n const kind = spec.renderer ?? getPageRenderer();\n checkRendererKind(kind, \"a three layer's renderer\");\n this._gpu = kind === 'webgpu';\n this.renderer = kind;\n let renderer: WebGLRenderer | WebGPURenderer;\n if (this._gpu) {\n let mod: typeof import('three/webgpu');\n try { mod = await import('three/webgpu'); } catch (err) {\n throw new Error(`pixi-effects: renderer: 'webgpu' needs three 0.17x or later with \"three/webgpu\" in the import map (${err instanceof Error ? err.message : err})`);\n }\n renderer = new mod.WebGPURenderer({ canvas, alpha: true, antialias });\n this._renderer = renderer;\n this._track();\n // The device is made here: nothing may render before. Where there is no WebGPU three uses its own WebGL2 backend and says so with a warning: that is not a problem\n // (it draws the same picture), so it becomes `backend: 'webgl2'` instead of a line in the author's console.\n const warn = console.warn;\n let noGpu = false;\n console.warn = (...args: unknown[]) => { if (/WebGPU is not available/.test(String(args[0]))) noGpu = true; else warn.apply(console, args as []); };\n try { await renderer.init(); }\n catch (err) { this._disposeRenderer(); throw err; }\n finally { console.warn = warn; }\n this.backend = noGpu ? 'webgl2' : 'webgpu';\n } else {\n renderer = new WebGLRenderer({ canvas, alpha: true, antialias });\n this._renderer = renderer;\n this._track();\n let said = false;\n canvas.addEventListener('webglcontextlost', () => { // the browser took the context away: the layer draws nothing from now on\n if (said) return;\n said = true;\n console.warn(`pixi-effects: three layer${spec.name ? ` \"${spec.name}\"` : ''}: the browser took this layer's WebGL context away (a page keeps about 16 for all its layers, PixiJS and shader layers: too many were alive), so the layer draws nothing. Put several objects in one three layer, or destroy layers that are over`);\n });\n this.backend = 'webgl';\n }\n try {\n renderer.setSize(Math.round(width * resolution), Math.round(height * resolution), false);\n renderer.setClearColor(0x000000, 0);\n\n const scene = new Scene();\n const camera: Camera = new PerspectiveCamera(50, width / height, 0.1, 2000);\n const ctx: ThreeContext = { scene, camera, renderer, width, height };\n if (spec.followCamera) this._checkFollowShape(width, height, spec.name);\n\n let result: Awaited<ReturnType<ThreeSequenceSpec['setup']>>;\n try { result = await spec.setup(ctx); } catch (err) { throw this._gpu ? this._explainWebGpuError(err, spec.name) : err; }\n if (result?.camera) ctx.camera = result.camera;\n this._scene = scene;\n this._camera = ctx.camera;\n this._ctx = ctx;\n this._objects = { ...(result?.objects ?? {}) };\n if (!('camera' in this._objects)) this._objects.camera = this._camera;\n\n if (this._gpu) this._checkWebGpuMaterials(scene, spec.name);\n // Frame 0 so the texture is never blank before the first tick.\n this._draw(0);\n\n const texture = Texture.from(canvas);\n const sprite = new Sprite({ texture, label: spec.name });\n sprite.cullable = true;\n // Texture is canvas-sized (layer px × resolution); scale back to comp px.\n sprite.width = width;\n sprite.height = height;\n this.target = sprite;\n this.intrinsicWidth = width;\n this.intrinsicHeight = height;\n this.buildFilters();\n } catch (err) {\n this._disposeRenderer();\n throw err;\n }\n }\n\n /**\n * Per-frame sync hook. Movie._awaitVideoFrames duck-types on this method\n * (same contract as VideoSequence) and awaits it inside gotoFrame — the\n * single frame path shared by playback and export, which is what makes\n * three layers deterministic in both.\n */\n async awaitFrameAt(local: number): Promise<void> {\n if (!this._renderer || !this._scene || !this._camera || !this._ctx) return;\n const spec = this._threeSpec;\n const t = Math.max(0, Math.min(local, this.duration ?? local));\n this._followSpace(t);\n if (spec.update) {\n try {\n spec.update(t, this._ctx);\n } catch (err) {\n if (!this._warnedUpdate) {\n this._warnedUpdate = true;\n console.warn('pixi-effects: three update() threw (reported once) —', err);\n }\n }\n }\n this._draw(t);\n (this.target as Sprite | null)?.texture.source.update();\n }\n\n /**\n * The determinism check (`check`, `movie.review()`): the scene drawn at a few moments in two orders, with one draw thrown away first, and the pictures compared, as the canvas layer\n * does. A layer whose same frame is not the same picture (a clock, `Math.random`, a mixer advanced with `update(dt)`, any state that builds up from call to call) is reported.\n * It runs the layer's own `update`, draws with its renderer and reads the picture from the renderer's canvas in the same task; the next real frame draws again, so nothing is left behind.\n */\n checkDeterminism(times: number[]): CanvasCheck {\n const none: CanvasCheck = { differs: [], drawMs: 0, threw: [] };\n const renderer = this._renderer, ctx = this._ctx;\n if (!renderer || !this._scene || !this._camera || !ctx) return none;\n const source = (renderer as unknown as { domElement: HTMLCanvasElement }).domElement;\n const w = source.width, h = source.height;\n const scratch = document.createElement('canvas');\n scratch.width = w; scratch.height = h;\n const g = scratch.getContext('2d', { willReadFrequently: true });\n if (!g) return none;\n const keep = w * h * 4 * times.length <= 96e6;\n const hash = (d: Uint8ClampedArray): number => { let x = 0x811c9dc5; for (let i = 0; i < d.length; i++) { x ^= d[i]!; x = Math.imul(x, 0x01000193); } return x >>> 0; };\n const ms: number[] = [];\n const threw = new Set<number>();\n const once = (t: number, timed: boolean): Uint8ClampedArray => {\n const from = performance.now();\n try {\n this._followSpace(t);\n this._threeSpec.update?.(t, ctx);\n this._draw(t);\n g.clearRect(0, 0, w, h);\n g.drawImage(source, 0, 0);\n } catch { threw.add(t); }\n if (timed) { g.getImageData(0, 0, 1, 1); ms.push(performance.now() - from); }\n return g.getImageData(0, 0, w, h).data;\n };\n for (const t of times) once(t, false); // the warm-up\n const first = times.map(t => { const d = once(t, true); return keep ? d.slice() : hash(d); });\n const second = [...times].reverse().map(t => once(t, false)).reverse();\n scratch.width = scratch.height = 1;\n const differs: CanvasCheck['differs'] = [];\n times.forEach((t, i) => {\n const a = first[i]!, b = second[i]!;\n if (typeof a === 'number') { if (a !== hash(b)) differs.push({ t, pixels: -1, maxDiff: -1 }); return; }\n let pixels = 0, maxDiff = 0;\n for (let k = 0; k < a.length; k++) { const d = Math.abs(a[k]! - b[k]!); if (d) { pixels++; if (d > maxDiff) maxDiff = d; } }\n if (pixels) differs.push({ t, pixels, maxDiff });\n });\n ms.sort((x, y) => x - y);\n return { differs: differs.filter(d => !threw.has(d.t)), drawMs: ms.length ? ms[Math.floor(ms.length / 2)]! : 0, threw: times.filter(t => threw.has(t)) };\n }\n\n /** `followCamera` / `followLights`: before each frame, ask the composition for its camera and lights at this moment (the layer's time on the composition's clock) and mirror them in the scene. */\n private _followSpace(t: number): void {\n const spec = this._threeSpec;\n if (!spec.followCamera && !spec.followLights && !spec.followFog) return;\n const ctx = this._ctx, scene = this._scene;\n if (!ctx || !scene) return;\n if (!this.parent?.spaceAt) {\n this._saidOnce('parent', `followCamera / followLights / followFog need the layer to sit in a composition that has a camera or a light to follow; this layer's parent cannot say (it keeps its own camera and lights)`, spec.name);\n return;\n }\n const space = this.parent.spaceAt((this.absoluteStart ?? this.at) + t);\n ctx.space = space;\n if (spec.followCamera) {\n const camera = ctx.camera as PerspectiveCamera;\n if (!camera.isPerspectiveCamera) this._saidOnce('camera', `followCamera needs a PerspectiveCamera (this layer's camera is a ${(ctx.camera as { type?: string }).type ?? 'different camera'}); it keeps it as it is`, spec.name);\n else applyCameraState(camera, space.camera, ctx.width / ctx.height);\n }\n if (spec.followLights) {\n const mirror = (this._lightMirror ??= new LightMirror(scene, Math.max(ctx.width, ctx.height) * 2));\n mirror.update(space.lights);\n if (mirror.castsShadows && !ctx.renderer.shadowMap.enabled) ctx.renderer.shadowMap.enabled = true;\n }\n if (spec.followFog) {\n if (space.fog && space.fog.amount !== 1) this._saidOnce('fogAmount', `followFog: the camera's fogAmount is ${space.fog.amount}, and three's Fog has no amount below 1: the layer uses the full amount (set fogColor to the colour you want at the far end, or leave followFog off and make the fog yourself from ctx.space.fog)`, spec.name);\n (this._fogMirror ??= new FogMirror(scene)).update(space.fog);\n }\n }\n\n /** followCamera shows the whole composition through the layer's picture: a layer of another shape would show it squeezed or cut. Said once at build. */\n private _checkFollowShape(width: number, height: number, name: string | undefined): void {\n const p = this.parent;\n if (!p || !(p.width > 0 && p.height > 0)) return;\n if (Math.abs(width * p.height - height * p.width) <= 1e-3 * width * p.height) return;\n this._saidOnce('shape', `followCamera: the layer is ${width} x ${height} but the composition is ${p.width} x ${p.height}; the camera shows the whole composition, so the layer needs its aspect ratio (drop width / height to cover the composition)`, name);\n }\n\n private _saidOnce(key: string, message: string, name: string | undefined): void {\n if (this._warnedSpace.has(key)) return;\n this._warnedSpace.add(key);\n console.warn(`pixi-effects: three layer${name ? ` \"${name}\"` : ''}: ${message}`);\n }\n\n /**\n * One render of the scene at the layer-local time `t`. WebGPURenderer.render() needs `await init()` first (done in build); it queues the GPU work, and PixiJS reads the canvas after.\n *\n * Three's WebGPU node system updates the light uniforms (and its `time`) once per FRAME ID, and bumps that id in its own requestAnimationFrame loop only. Renders that\n * follow each other in one task (a seek, an export) would all show the lights of the last animation frame: a lamp keyframed with `three.lamp.intensity` would not move.\n * So before each render the layer advances the node frame itself, and gives `time` the layer's own time (not three's wall clock).\n */\n private _draw(t: number): void {\n if (!this._renderer || !this._scene || !this._camera) return;\n if (this._gpu) this._advanceNodeFrame(t);\n this._renderer.render(this._scene, this._camera);\n }\n\n /**\n * The author chose renderer: 'webgpu'. Three's WebGPU renderer turns materials into node materials: a ShaderMaterial / RawShaderMaterial cannot run there (three logs an error on\n * every render and draws a default material) and `onBeforeCompile` (a patch of the WebGL shader text) is ignored without a word. Stop, once, naming the first such material and the fix,\n * instead of drawing a picture that is wrong without saying so.\n */\n private _checkWebGpuMaterials(scene: Scene, layerName: string | undefined): void {\n const bad: string[] = [];\n const seen = new Set<unknown>();\n const check = (m: unknown): void => {\n if (!m || typeof m !== 'object' || seen.has(m)) return;\n seen.add(m);\n const mat = m as { type?: string; name?: string; isShaderMaterial?: boolean; isRawShaderMaterial?: boolean };\n const label = `${mat.name ? `\"${mat.name}\" ` : ''}${mat.type ?? 'material'}`;\n if (mat.isShaderMaterial || mat.isRawShaderMaterial) bad.push(`${label} is a ShaderMaterial (it cannot run on the WebGPU renderer)`);\n else if (Object.prototype.hasOwnProperty.call(mat, 'onBeforeCompile')) bad.push(`${label} sets onBeforeCompile (the WebGPU renderer ignores it)`);\n };\n scene.traverse?.((o: unknown) => {\n const mats = (o as { material?: unknown }).material;\n for (const m of Array.isArray(mats) ? mats : [mats]) check(m);\n });\n if (!bad.length) return;\n this._disposeRenderer();\n throw new Error(`pixi-effects: three layer${layerName ? ` \"${layerName}\"` : ''} with renderer: 'webgpu': ${bad[0]}${bad.length > 1 ? ` (and ${bad.length - 1} more)` : ''}. ` +\n `Add renderer: 'webgl' to this layer (or registerThree({ renderer: 'webgl' }) for the page), or write the look with three's node materials (TSL).`);\n }\n\n /** The one setup failure everybody meets on the WebGPU renderer: a PMREMGenerator imported from 'three' reads WebGL state the WebGPU renderer does not have. */\n private _explainWebGpuError(err: unknown, layerName: string | undefined): unknown {\n if (err instanceof TypeError && /reading 'buffers'|renderer\\.state/.test(err.message)) {\n return new Error(`pixi-effects: three layer${layerName ? ` \"${layerName}\"` : ''} with renderer: 'webgpu': setup used a WebGL-only helper, most likely a PMREMGenerator imported from 'three'. ` +\n `Import it from 'three/webgpu' (import * as THREE from 'three/webgpu'), or add renderer: 'webgl' to this layer.`, { cause: err });\n }\n return err;\n }\n\n private _advanceNodeFrame(t: number): void {\n const frame = (this._renderer as unknown as { _nodes?: { nodeFrame?: { update?: () => void; time: number; deltaTime: number } } })._nodes?.nodeFrame;\n if (!frame || typeof frame.update !== 'function') {\n if (!this._warnedNodeFrame) {\n this._warnedNodeFrame = true;\n console.warn(\"pixi-effects: this three has no node frame to advance (renderer: 'webgpu'): a light animated by keyframes may not follow the time in a seek or an export; use renderer: 'webgl' or report the three version\");\n }\n return;\n }\n frame.update();\n frame.time = t;\n frame.deltaTime = 1 / ((this.root as { frameRate?: number }).frameRate ?? 30);\n }\n\n private _resolveThreePath(path: string): { target: object; prop: string } | null {\n const segs = path.split('.');\n if (segs.length < 2) {\n this._warnPath(path, 'needs at least <object>.<prop>');\n return null;\n }\n let obj: unknown = this._objects[segs[0]!];\n if (obj == null) {\n this._warnPath(path, `unknown object \"${segs[0]}\" — expose it via setup's { objects }`);\n return null;\n }\n for (let i = 1; i < segs.length - 1; i++) {\n obj = (obj as Record<string, unknown>)[segs[i]!];\n if (obj == null) {\n this._warnPath(path, `\"${segs[i]}\" is undefined along the path`);\n return null;\n }\n }\n const prop = segs[segs.length - 1]!;\n if (typeof obj !== 'object' || !(prop in (obj as object))) {\n this._warnPath(path, `no property \"${prop}\"`);\n return null;\n }\n return { target: obj as object, prop };\n }\n\n private _warnPath(path: string, why: string): void {\n if (this._warnedPaths.has(path)) return;\n this._warnedPaths.add(path);\n console.warn(`pixi-effects: keyframe path three.${path} ${why}; skipped`);\n }\n\n /** Count this layer's renderer against the page's allowance of graphics contexts (given back when the renderer is disposed). */\n private _track(): void {\n this._tracked = true;\n trackThree(this._gpu ? 'webgpu' : 'webgl');\n }\n\n private _disposeRenderer(): void {\n if (!this._renderer) return;\n if (this._tracked) { this._tracked = false; releaseThree(this._gpu ? 'webgpu' : 'webgl'); }\n try {\n this._renderer.dispose();\n if (!this._gpu) (this._renderer as WebGLRenderer).forceContextLoss();\n } catch (err) {\n console.warn('pixi-effects: three renderer dispose threw —', err);\n }\n this._renderer = null;\n }\n\n override destroy(): void {\n const spec = this._threeSpec;\n if (this._ctx && spec.dispose) {\n try { spec.dispose(this._ctx); } catch (err) {\n console.warn('pixi-effects: three dispose() threw —', err);\n }\n }\n const texture = (this.target as Sprite | null)?.texture;\n this._lightMirror?.dispose();\n this._lightMirror = null;\n this._fogMirror?.dispose();\n this._fogMirror = null;\n this._disposeRenderer();\n this._scene = null;\n this._camera = null;\n this._ctx = null;\n this._objects = {};\n super.destroy();\n texture?.destroy(true); // canvas-backed source is per-sequence; safe to kill\n }\n}\n\nfunction resolveDim(v: PropValue | undefined, scope: Record<string, number>): number | undefined {\n if (v === undefined) return undefined;\n if (typeof v === 'number') return v;\n return evaluateExpr(v, scope);\n}\n","/**\n * Two helpers for a glTF model in a `three` layer's `setup` / `update` (the layer stays the free box; these are what is easy to get wrong by hand):\n *\n * const fox = await threeGltf('Fox.glb', { animation: 'Run' }); // in setup\n * ctx.scene.add(fox.object); threeFrameCamera(ctx.camera, fox.object);\n * ... update: (t) => fox.pose(t) // the clip at the layer's time: a function of t, never of a clock\n *\n * The loader is an addon: a page that never calls `threeGltf` never loads it (the import map needs `\"three/addons/\"` next to `\"three\"`).\n */\nimport { AnimationMixer, Box3, Group, LoopOnce, LoopRepeat, Vector3, type AnimationClip, type Camera, type Object3D, type PerspectiveCamera } from 'three';\n\nexport interface ThreeGltfOptions {\n /** A clip name, a clip index, or `false` (no animation: the model's bind pose). Default: the first clip, if the file has one. */\n animation?: string | number | false;\n /** The clip time is `t × speed + offset` (the layer's seconds). Defaults 1 and 0. */\n speed?: number;\n offset?: number;\n /** `true` (default): the clip repeats; `false`: it holds its last pose. */\n loop?: boolean;\n}\n\nexport interface ThreeGltfModel {\n /** Add this to `ctx.scene`. A group whose origin is the centre of the model's bounding box (bind pose): position, turn and `fit` it about its centre. */\n object: Group;\n /** The names of the clips the file has. */\n clips: string[];\n /** The size of the model's bounding box in the file's own units (bind pose, before `fit`). */\n size: Vector3;\n /** Pose the model at the layer's time `t` (seconds). `AnimationMixer.setTime` evaluates the clip from zero every call: a seek, an export and a repeat give the same pose. */\n pose(t: number): void;\n /** Scale `object` so the model's longest side is `px` (a model in metres in a scene in composition pixels). */\n fit(px: number): void;\n /** Stop the clip. Geometries, materials and textures are yours to dispose with the scene. */\n dispose(): void;\n}\n\nexport async function threeGltf(url: string, options: ThreeGltfOptions = {}): Promise<ThreeGltfModel> {\n const label = 'pixi-effects: threeGltf';\n if (typeof url !== 'string' || !url) throw new Error(`${label}: the first argument is the URL of a .glb or .gltf file`);\n let GLTFLoader: typeof import('three/addons/loaders/GLTFLoader.js').GLTFLoader;\n try { ({ GLTFLoader } = await import('three/addons/loaders/GLTFLoader.js')); } catch (err) {\n throw new Error(`${label}: needs \"three/addons/\" in the import map next to \"three\" (${err instanceof Error ? err.message : err})`);\n }\n let gltf: Awaited<ReturnType<InstanceType<typeof GLTFLoader>['loadAsync']>>;\n try { gltf = await new GLTFLoader().loadAsync(url); } catch (err) {\n throw new Error(`${label}: could not load \"${url}\" (${err instanceof Error ? err.message : err})`, { cause: err });\n }\n\n const clips: AnimationClip[] = gltf.animations ?? [];\n let clip: AnimationClip | undefined;\n const wanted = options.animation;\n if (wanted === false || (wanted === undefined && clips.length === 0)) clip = undefined;\n else if (wanted === undefined) clip = clips[0];\n else {\n clip = typeof wanted === 'number' ? clips[wanted] : clips.find((c) => c.name === wanted);\n if (!clip) throw new Error(`${label}: \"${url}\" has no animation ${JSON.stringify(wanted)}; its clips: ${clips.length ? clips.map((c, i) => `${i}: \"${c.name}\"`).join(', ') : '(none)'}`);\n }\n\n // The origin of the group is the centre of the box, so the model is placed and turned about its centre.\n const root: Object3D = gltf.scene;\n // A skinned mesh is always drawn. three culls a mesh by a bounding sphere, and a skinned mesh's sphere does not follow its animation or its place: a model that MOVES and throws a shadow\n // drew its shadow differently depending on the frames drawn before it (found on the Khronos Fox: `check` reported the layer as not a function of the time; with culling off the\n // pictures are the same in any order). The cost is that an off-screen model is still drawn.\n root.traverse((o) => { if ((o as { isSkinnedMesh?: boolean }).isSkinnedMesh) o.frustumCulled = false; });\n const object = new Group();\n object.add(root);\n const bounds = new Box3().setFromObject(root);\n const centre = bounds.getCenter(new Vector3());\n const size = bounds.getSize(new Vector3());\n root.position.sub(centre);\n\n let mixer: AnimationMixer | null = null;\n if (clip) {\n mixer = new AnimationMixer(root);\n const action = mixer.clipAction(clip);\n action.setLoop(options.loop === false ? LoopOnce : LoopRepeat, Infinity);\n action.clampWhenFinished = true;\n action.play();\n }\n const speed = options.speed ?? 1, offset = options.offset ?? 0;\n\n return {\n object,\n clips: clips.map((c) => c.name),\n size,\n pose: (t) => { mixer?.setTime(t * speed + offset); },\n fit: (px) => { object.scale.setScalar(px / Math.max(size.x, size.y, size.z, 1e-9)); },\n dispose: () => { mixer?.stopAllAction(); mixer?.uncacheRoot(root); mixer = null; },\n };\n}\n\nexport interface ThreeFrameCameraOptions {\n /** The direction the camera sits in from the centre of the model, any length. Default `[0.45, 0.3, 1]`: a three-quarter view, a little from the side and above. */\n direction?: [number, number, number];\n /** Free room around the model: 1.1 (the default) leaves 10 %. */\n margin?: number;\n}\n\n/**\n * Put `camera` where the whole of `object` (its bounding box now, with its scale and place) fits the frame, looking at its centre: the smallest distance at which the 8 corners of\n * the box all fit both the vertical and the horizontal field of view (a bounding sphere would leave a long model small and head-on). `near` and `far` follow the distance.\n * Uses the camera's own `fov` and `aspect`. For a clip that travels far, give your own camera: the box is the bind pose.\n */\nexport function threeFrameCamera(camera: PerspectiveCamera | Camera, object: Object3D, options: ThreeFrameCameraOptions = {}): void {\n const cam = camera as PerspectiveCamera;\n object.updateMatrixWorld(true);\n const bounds = new Box3().setFromObject(object);\n const centre = bounds.getCenter(new Vector3());\n const margin = options.margin ?? 1.1;\n const [dx, dy, dz] = options.direction ?? [0.45, 0.3, 1];\n const toCamera = new Vector3(dx, dy, dz).normalize();\n const right = new Vector3().crossVectors(new Vector3(0, 1, 0), toCamera);\n if (right.lengthSq() < 1e-12) right.set(1, 0, 0); // straight above or below: any right will do\n right.normalize();\n const up = new Vector3().crossVectors(toCamera, right);\n const tanV = Math.tan((cam.fov * Math.PI) / 360), tanH = tanV * cam.aspect;\n let distance = 1e-3;\n for (const x of [bounds.min.x, bounds.max.x]) for (const y of [bounds.min.y, bounds.max.y]) for (const z of [bounds.min.z, bounds.max.z]) {\n const r = new Vector3(x, y, z).sub(centre);\n distance = Math.max(distance, r.dot(toCamera) + (Math.abs(r.dot(right)) * margin) / tanH, r.dot(toCamera) + (Math.abs(r.dot(up)) * margin) / tanV);\n }\n cam.position.copy(centre).addScaledVector(toCamera, distance);\n cam.near = Math.max(distance / 100, 1e-4);\n cam.far = distance * 100;\n cam.lookAt(centre);\n cam.updateProjectionMatrix();\n}\n","/**\n * pixi-effects/three — optional three.js integration.\n *\n * Import this entry only when you use `type: 'three'` sequences; the core\n * `pixi-effects` entry never touches three.js. Call `registerThree()` once\n * before Movie.init builds a composition containing a three sequence.\n */\nimport { registerSequenceType, type SequenceCtor } from '../core/Composition';\nimport { ThreeSequence } from './ThreeSequence';\nimport { checkRendererKind, setPageRenderer, type ThreeRendererKind } from './defaults';\nimport type { SequenceSpec } from '../types';\nimport type { ThreeSequenceSpec } from './types';\n\nexport { ThreeSequence } from './ThreeSequence';\nexport { threeGltf, threeFrameCamera } from './gltf';\nexport type { ThreeGltfModel, ThreeGltfOptions, ThreeFrameCameraOptions } from './gltf';\nexport type { ThreeContext, ThreeSetupResult, ThreeSequenceSpec } from './types';\nexport type { ThreeRendererKind } from './defaults';\n\n/**\n * Register the 'three' sequence type. Explicit call so `sideEffects: false` bundlers can't drop it; calling it again is fine.\n * `registerThree({ renderer: 'webgpu' })` makes every three layer that does not name a `renderer` of its own use three's WebGPU renderer; the default is `'webgl'`\n * (the last call wins).\n */\nexport function registerThree(options: { renderer?: ThreeRendererKind } = {}): void {\n const kind = options.renderer ?? 'webgl';\n checkRendererKind(kind, \"registerThree's renderer\");\n setPageRenderer(kind);\n registerSequenceType('three', ThreeSequence as unknown as SequenceCtor);\n}\n\n/**\n * Typing helper: accepts a strongly-typed three spec and returns it as a\n * core SequenceSpec, keeping three.js types out of the core union.\n */\nexport function three(spec: ThreeSequenceSpec): SequenceSpec {\n return spec as unknown as SequenceSpec;\n}\n"]}
1
+ {"version":3,"sources":["../src/three/defaults.ts","../src/three/spaceBridge.ts","../src/three/budget.ts","../src/three/ThreeSequence.ts","../src/three/gltf.ts","../src/three/index.ts"],"names":["PerspectiveCamera","Box3","Vector3"],"mappings":"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","file":"three.js","sourcesContent":["/** The page-level default renderer of the three layers: `registerThree({ renderer })` sets it, a layer's own `renderer` wins. */\nexport type ThreeRendererKind = 'webgl' | 'webgpu';\n\nlet pageRenderer: ThreeRendererKind = 'webgl';\n\nexport function checkRendererKind(kind: unknown, where: string): asserts kind is ThreeRendererKind {\n if (kind !== 'webgl' && kind !== 'webgpu') throw new Error(`pixi-effects: ${where} must be 'webgl' or 'webgpu' (got ${JSON.stringify(kind)})`);\n}\nexport function setPageRenderer(kind: ThreeRendererKind): void { pageRenderer = kind; }\nexport function getPageRenderer(): ThreeRendererKind { return pageRenderer; }\n","/**\n * What lets a `three` layer live in the composition's space (`followCamera`, `followLights`): the composition's camera and lights, in three.\n *\n * The scene is in composition pixels with y flipped: a point the composition calls (x, y, z) is `new Vector3(x, -y, z)` here (the composition's y runs down, three's up;\n * +z is toward the viewer in both). A three camera with the composition camera's position, look-at point and vertical fov then projects that point to the pixel the\n * composition's own projection gives it (tests/three/spaceBridge.test.ts checks it to 1e-6 px).\n */\nimport { AmbientLight, Color, DirectionalLight, Fog, OrthographicCamera, PerspectiveCamera, PointLight, SRGBColorSpace, SpotLight, type Light, type Object3D, type Scene } from 'three';\nimport type { CameraState } from '../space/math';\nimport type { LightState } from '../space/lighting';\nimport type { FogState } from '../space/LitMaterial';\n\n/** The camera's near plane and far plane in composition pixels: the home camera sits about 740 px from the picture, a long dolly can be several thousand. */\nconst NEAR = 1;\nconst FAR = 20000;\n\n/** Put a three camera where the composition camera is. The aspect is the layer's (it must be the composition's: see `followCamera`). */\nexport function applyCameraState(camera: PerspectiveCamera, s: CameraState, aspect: number): void {\n camera.fov = s.fov;\n camera.aspect = aspect;\n camera.near = NEAR;\n camera.far = FAR;\n camera.up.set(0, 1, 0);\n camera.position.set(s.x, -s.y, s.z);\n const same = Math.hypot(s.lookAtX - s.x, s.lookAtY - s.y, s.lookAtZ - s.z) < 1e-9; // the composition then looks along -z\n camera.lookAt(same ? s.x : s.lookAtX, same ? -s.y : -s.lookAtY, same ? s.z - 1 : s.lookAtZ);\n camera.updateProjectionMatrix();\n camera.updateMatrixWorld();\n}\n\ninterface Entry { kind: LightState['kind']; light: Light; target: Object3D | null }\n\n/**\n * The composition's lights as three lights, one per light layer alive, in layer order. The objects are made once and moved every frame (a light that has ended is switched off,\n * not removed: the shader of a three layer must not be rebuilt as lights come and go).\n *\n * Intensity: three divides a diffuse surface by pi, so a light of intensity 1 is multiplied by pi to be \"as bright as the colour\" like a card's shading. Falloff: 'none' is no\n * attenuation; 'inverseSquare' is decay 2 with the intensity scaled so it is full at `radius` (it keeps rising inside it, where the composition's stays at 1); 'smooth' is three's\n * cut-off fitted to the composition's curve (see below). Shadows follow the light (castsShadows: the layer's own meshes cast and receive).\n */\nexport class LightMirror {\n private entries: Entry[] = [];\n /** True when a light alive casts shadows: the layer's renderer must have its shadow map on. */\n castsShadows = false;\n constructor(private readonly scene: Object3D, private readonly extent = 2000) {}\n\n update(lights: readonly LightState[]): void {\n this.castsShadows = lights.some((s) => s.castsShadows && s.kind !== 'ambient');\n lights.forEach((s, i) => {\n let e = this.entries[i];\n if (!e || e.kind !== s.kind) {\n if (e) this.remove(e);\n e = this.entries[i] = this.make(s.kind);\n }\n this.configure(e, s);\n });\n for (let i = lights.length; i < this.entries.length; i++) this.entries[i]!.light.visible = false;\n }\n\n dispose(): void {\n for (const e of this.entries) this.remove(e);\n this.entries = [];\n }\n\n private make(kind: LightState['kind']): Entry {\n const light: Light = kind === 'ambient' ? new AmbientLight() : kind === 'parallel' ? new DirectionalLight() : kind === 'spot' ? new SpotLight() : new PointLight();\n light.name = 'pixi-effects:composition-light';\n const target = (light as DirectionalLight | SpotLight).target ?? null;\n this.scene.add(light);\n if (target) this.scene.add(target);\n return { kind, light, target };\n }\n\n private remove(e: Entry): void {\n this.scene.remove(e.light);\n if (e.target) this.scene.remove(e.target);\n }\n\n private configure(e: Entry, s: LightState): void {\n const { light } = e;\n light.visible = true;\n light.color = (light.color ?? new Color()).setRGB(s.r, s.g, s.b, SRGBColorSpace);\n let intensity = s.intensity * Math.PI;\n if (s.kind !== 'ambient') {\n light.position.set(s.x, -s.y, s.z);\n e.target?.position.set(s.lookAtX, -s.lookAtY, s.lookAtZ);\n }\n if (s.kind === 'point' || s.kind === 'spot') {\n const l = light as PointLight | SpotLight;\n if (s.falloff === 'inverseSquare') { l.distance = 0; l.decay = 2; intensity *= s.radius * s.radius; }\n else if (s.falloff === 'smooth') {\n // The composition: 1 inside `radius`, a smoothstep down to 0 at radius + falloffDistance. three's cut-off distance D with decay 0 attenuates by saturate(1 - (d/D)^4)^2, a gentler curve that\n // starts to fall at once. A cut-off and a gain chosen from where the fall starts (p = radius / (radius + falloffDistance)) halve the largest difference over the range (0.15-0.40 with\n // D = radius + falloffDistance and no gain, 0.09-0.17 here for a fall that is not steep); a fall that is steep against its radius cannot be matched by three's curve.\n const reach = s.radius + Math.max(s.falloffDistance, 1e-3), p = s.radius / reach;\n l.distance = reach * (0.8 + 0.45 * p); l.decay = 0; intensity *= 0.87 + 0.45 * p;\n }\n else { l.distance = 0; l.decay = 0; }\n }\n if (s.kind === 'spot') {\n const l = light as SpotLight;\n l.angle = ((s.coneAngle / 2) * Math.PI) / 180;\n l.penumbra = s.coneFeather;\n }\n light.intensity = intensity;\n if (s.kind !== 'ambient') {\n const l = light as PointLight | SpotLight | DirectionalLight;\n l.castShadow = s.castsShadows;\n if (s.castsShadows) {\n l.shadow.mapSize.set(2048, 2048);\n l.shadow.intensity = s.shadowDarkness;\n l.shadow.radius = Math.max(1, s.shadowDiffusion / 4);\n // Scale-aware: three compares depths AFTER the perspective divide, so a bias of b is about b·d²/near world units at distance d from the light. A near plane of 1 px and a bias of\n // -0.0005 hid every caster within ~250 px of its receiver at 1280 x 720 (found by an AI trial). The near plane follows the size of the composition (~20 px at 1280 x 720) and the\n // bias is small, so the gap is about a pixel or two; normalBias (world units, along the surface normal) is a pixel or two too.\n l.shadow.bias = -0.00005;\n l.shadow.normalBias = this.extent / 1000;\n const cam = l.shadow.camera;\n cam.near = Math.max(1, this.extent / 128); cam.far = 20000;\n if (s.kind === 'parallel') { const o = cam as OrthographicCamera; o.left = -this.extent; o.right = this.extent; o.top = this.extent; o.bottom = -this.extent; }\n cam.updateProjectionMatrix();\n }\n }\n light.updateMatrixWorld?.();\n e.target?.updateMatrixWorld?.();\n }\n}\n\n/**\n * The composition camera's fog as the scene's `Fog`: the same colour, `near` and `far` (distances along the view, in composition pixels). three's Fog fades with `smoothstep` where the\n * composition's fades linearly, and has no amount below 1: close, not equal (see docs/dsl.md). The Fog is made when the camera has one and removed when it has not; a Fog the layer made\n * itself is never touched.\n */\nexport class FogMirror {\n private own: Fog | null = null;\n constructor(private readonly scene: Scene) {}\n\n update(fog: FogState | null): void {\n if (!fog) {\n if (this.own && this.scene.fog === this.own) this.scene.fog = null;\n this.own = null;\n return;\n }\n if (!this.own || this.scene.fog !== this.own) {\n if (this.scene.fog && this.scene.fog !== this.own) return; // the layer has its own fog: leave it\n this.own = new Fog(0x000000, fog.near, fog.far);\n this.scene.fog = this.own;\n }\n this.own.color.setRGB(fog.r, fog.g, fog.b, SRGBColorSpace);\n this.own.near = fog.near;\n this.own.far = fog.far;\n }\n\n dispose(): void { this.update(null); }\n}\n","/**\n * How many three layers a page can hold. Each `three` layer owns a renderer, and a browser keeps only so many live graphics contexts for a whole page: about 16 for WebGL, about 32 for\n * WebGPU (measured 2026-10-15 on Chrome: layers beyond it draw nothing, without an error). PixiJS and a `shader` layer use contexts of their own, so the warning comes a little before the\n * limit: more than 12 WebGL layers, more than 28 WebGPU layers.\n */\nexport type ThreeKind = 'webgl' | 'webgpu';\n\nconst WARN_ABOVE: Record<ThreeKind, number> = { webgl: 12, webgpu: 28 };\nconst LIMIT: Record<ThreeKind, string> = { webgl: 'about 16 WebGL contexts', webgpu: 'about 32 WebGPU contexts' };\nconst live: Record<ThreeKind, number> = { webgl: 0, webgpu: 0 };\nconst warned = new Set<ThreeKind>();\n\n/** A three layer made its renderer: count it, and say once per kind when the page holds too many. */\nexport function trackThree(kind: ThreeKind): void {\n live[kind]++;\n if (live[kind] > WARN_ABOVE[kind] && !warned.has(kind)) {\n warned.add(kind);\n console.warn(`pixi-effects: ${live[kind]} three layers are alive with renderer: '${kind}', and a browser keeps ${LIMIT[kind]} for the whole page; layers beyond that draw nothing, without an error. ` +\n `Put several objects in one three layer, destroy layers that are over, ` + (kind === 'webgl' ? `or use renderer: 'webgpu' for some (its limit is about 32)` : `or use renderer: 'webgl' for some of them (a different pool of contexts)`));\n }\n}\n\n/** A three layer let its renderer go. */\nexport function releaseThree(kind: ThreeKind): void {\n live[kind] = Math.max(0, live[kind] - 1);\n}\n\n/** What the page holds now, per renderer. */\nexport function threeBudget(): Record<ThreeKind, number> {\n return { ...live };\n}\n\n/** For tests: forget everything. */\nexport function resetThreeBudget(): void {\n live.webgl = live.webgpu = 0;\n warned.clear();\n}\n","import { Sprite, Texture } from 'pixi.js';\nimport { Box3, PerspectiveCamera, Raycaster, Scene, Vector2, Vector3, WebGLRenderer, type Camera, type Object3D } from 'three';\nimport type { WebGPURenderer } from 'three/webgpu';\nimport { Sequence } from '../sequences/Base';\nimport { buildScope } from '../expr/Scope';\nimport { evaluateExpr } from '../expr/Parser';\nimport type { PathRouters } from '../core/Timeline';\nimport type { PropValue } from '../types';\nimport type { ThreeContext, ThreeSequenceSpec } from './types';\nimport { checkRendererKind, getPageRenderer } from './defaults';\nimport { applyCameraState, FogMirror, LightMirror } from './spaceBridge';\nimport { releaseThree, trackThree } from './budget';\nimport type { CanvasCheck } from '../sequences/Canvas';\n\n/** What makes a frame depend on more than the time (the same list as the canvas layer's). */\nconst NOT_PURE = /\\bMath\\s*\\.\\s*random\\s*\\(|\\bDate\\s*\\.\\s*now\\s*\\(|\\bperformance\\s*\\.\\s*now\\s*\\(|\\bnew\\s+Date\\s*\\(/;\n\nexport class ThreeSequence extends Sequence {\n private _renderer: WebGLRenderer | WebGPURenderer | null = null;\n /** The renderer this layer draws with (`'webgl'` or `'webgpu'`), once it is built. */\n renderer: 'webgl' | 'webgpu' | null = null;\n /** The backend under it: `'webgl'`, `'webgpu'`, or `'webgl2'` when three's WebGPURenderer found no WebGPU in this browser and used its own WebGL2 backend (the same picture). */\n backend: 'webgl' | 'webgpu' | 'webgl2' | null = null;\n private _gpu = false; // renderer: 'webgpu': async init and async render\n private _scene: Scene | null = null;\n private _camera: Camera | null = null;\n private _ctx: ThreeContext | null = null;\n private _objects: Record<string, object> = {};\n private _warnedUpdate = false;\n private _warnedNodeFrame = false;\n private _warnedPaths = new Set<string>();\n private _lightMirror: LightMirror | null = null;\n private _fogMirror: FogMirror | null = null;\n private _warnedSpace = new Set<string>();\n private _tracked = false;\n\n private get _threeSpec(): ThreeSequenceSpec {\n return this.spec as unknown as ThreeSequenceSpec;\n }\n\n protected override pathRouters(): PathRouters {\n return { three: (path) => this._resolveThreePath(path) };\n }\n\n async build(): Promise<void> {\n const spec = this._threeSpec;\n if (this.duration === undefined) {\n this.duration = this.parent?.duration ?? this.root.duration;\n }\n if (typeof spec.update === 'function' && NOT_PURE.test(spec.update.toString())) {\n console.warn(`pixi-effects: three layer${spec.name ? ` \"${spec.name}\"` : ''}: update calls Math.random, Date.now, performance.now or new Date, so it is not deterministic: the same frame would draw differently in playback, in a seek and in an export. Derive the value from t`);\n }\n\n // Resolve layer size. Expressions see the usual scope; intrinsic w/h are\n // still 0 here (same chicken-and-egg as shapes), so W/H/GW/GH carry it.\n const scope = buildScope(this, this.parent, this.root) as unknown as Record<string, number>;\n const width = resolveDim(spec.width, scope) ?? this.parent?.width ?? this.root.width;\n const height = resolveDim(spec.height, scope) ?? this.parent?.height ?? this.root.height;\n const resolution = spec.resolution ?? 1;\n\n // Offscreen canvas — never attached to the DOM. document.createElement\n // (not OffscreenCanvas) so PIXI's Texture.from and three both accept it.\n const canvas = document.createElement('canvas');\n const antialias = spec.antialias ?? true;\n const kind = spec.renderer ?? getPageRenderer();\n checkRendererKind(kind, \"a three layer's renderer\");\n this._gpu = kind === 'webgpu';\n this.renderer = kind;\n let renderer: WebGLRenderer | WebGPURenderer;\n if (this._gpu) {\n let mod: typeof import('three/webgpu');\n try { mod = await import('three/webgpu'); } catch (err) {\n throw new Error(`pixi-effects: renderer: 'webgpu' needs three 0.17x or later with \"three/webgpu\" in the import map (${err instanceof Error ? err.message : err})`);\n }\n renderer = new mod.WebGPURenderer({ canvas, alpha: true, antialias });\n this._renderer = renderer;\n this._track();\n // The device is made here: nothing may render before. Where there is no WebGPU three uses its own WebGL2 backend and says so with a warning: that is not a problem\n // (it draws the same picture), so it becomes `backend: 'webgl2'` instead of a line in the author's console.\n const warn = console.warn;\n let noGpu = false;\n console.warn = (...args: unknown[]) => { if (/WebGPU is not available/.test(String(args[0]))) noGpu = true; else warn.apply(console, args as []); };\n try { await renderer.init(); }\n catch (err) { this._disposeRenderer(); throw err; }\n finally { console.warn = warn; }\n this.backend = noGpu ? 'webgl2' : 'webgpu';\n } else {\n renderer = new WebGLRenderer({ canvas, alpha: true, antialias });\n this._renderer = renderer;\n this._track();\n let said = false;\n canvas.addEventListener('webglcontextlost', () => { // the browser took the context away: the layer draws nothing from now on\n if (said) return;\n said = true;\n console.warn(`pixi-effects: three layer${spec.name ? ` \"${spec.name}\"` : ''}: the browser took this layer's WebGL context away (a page keeps about 16 for all its layers, PixiJS and shader layers: too many were alive), so the layer draws nothing. Put several objects in one three layer, or destroy layers that are over`);\n });\n this.backend = 'webgl';\n }\n try {\n renderer.setSize(Math.round(width * resolution), Math.round(height * resolution), false);\n renderer.setClearColor(0x000000, 0);\n\n const scene = new Scene();\n const camera: Camera = new PerspectiveCamera(50, width / height, 0.1, 2000);\n const ctx: ThreeContext = { scene, camera, renderer, width, height };\n if (spec.followCamera) this._checkFollowShape(width, height, spec.name);\n\n let result: Awaited<ReturnType<ThreeSequenceSpec['setup']>>;\n try { result = await spec.setup(ctx); } catch (err) { throw this._gpu ? this._explainWebGpuError(err, spec.name) : err; }\n if (result?.camera) ctx.camera = result.camera;\n this._scene = scene;\n this._camera = ctx.camera;\n this._ctx = ctx;\n this._objects = { ...(result?.objects ?? {}) };\n if (!('camera' in this._objects)) this._objects.camera = this._camera;\n\n if (this._gpu) this._checkWebGpuMaterials(scene, spec.name);\n // Frame 0 so the texture is never blank before the first tick.\n this._draw(0);\n\n const texture = Texture.from(canvas);\n const sprite = new Sprite({ texture, label: spec.name });\n sprite.cullable = true;\n // Texture is canvas-sized (layer px × resolution); scale back to comp px.\n sprite.width = width;\n sprite.height = height;\n this.target = sprite;\n this.intrinsicWidth = width;\n this.intrinsicHeight = height;\n this.buildFilters();\n } catch (err) {\n this._disposeRenderer();\n throw err;\n }\n }\n\n /**\n * Per-frame sync hook. Movie._awaitVideoFrames duck-types on this method\n * (same contract as VideoSequence) and awaits it inside gotoFrame — the\n * single frame path shared by playback and export, which is what makes\n * three layers deterministic in both.\n */\n async awaitFrameAt(local: number): Promise<void> {\n if (!this._renderer || !this._scene || !this._camera || !this._ctx) return;\n const spec = this._threeSpec;\n const t = Math.max(0, Math.min(local, this.duration ?? local));\n this._followSpace(t);\n if (spec.update) {\n try {\n spec.update(t, this._ctx);\n } catch (err) {\n if (!this._warnedUpdate) {\n this._warnedUpdate = true;\n console.warn('pixi-effects: three update() threw (reported once) —', err);\n }\n }\n }\n this._draw(t);\n (this.target as Sprite | null)?.texture.source.update();\n }\n\n /**\n * `movie.pick`: a ray through the point (u, v) of the layer's picture (0..1, v down) from the layer's camera, and what it meets first: the object's name (its own, or its nearest\n * ancestor's that has one), where, and how far from the camera. Invisible objects and groups are not met. null when the ray meets nothing.\n */\n pickAt(u: number, v: number): { object: string; point: [number, number, number]; distance: number; object3d: Object3D } | null {\n const scene = this._scene, camera = this._camera;\n if (!scene || !camera) return null;\n scene.updateMatrixWorld();\n camera.updateMatrixWorld();\n const ray = new Raycaster();\n ray.setFromCamera(new Vector2(u * 2 - 1, -(v * 2 - 1)), camera);\n const visibleChain = (o: Object3D | null): boolean => { for (let n = o; n; n = n.parent) if (!n.visible) return false; return true; };\n for (const hit of ray.intersectObjects(scene.children, true)) {\n if (!visibleChain(hit.object)) continue;\n let name = '';\n for (let n: Object3D | null = hit.object; n && n !== scene; n = n.parent) if (n.name) { name = n.name; break; }\n return { object: name, point: hit.point.toArray() as [number, number, number], distance: hit.distance, object3d: hit.object };\n }\n return null;\n }\n\n /**\n * The determinism check (`check`, `movie.review()`): the scene drawn at a few moments in two orders, with one draw thrown away first, and the pictures compared, as the canvas layer\n * does. A layer whose same frame is not the same picture (a clock, `Math.random`, a mixer advanced with `update(dt)`, any state that builds up from call to call) is reported.\n * It runs the layer's own `update`, draws with its renderer and reads the picture from the renderer's canvas in the same task; the next real frame draws again, so nothing is left behind.\n */\n checkDeterminism(times: number[]): CanvasCheck {\n const none: CanvasCheck = { differs: [], drawMs: 0, threw: [] };\n const renderer = this._renderer, ctx = this._ctx;\n if (!renderer || !this._scene || !this._camera || !ctx) return none;\n const source = (renderer as unknown as { domElement: HTMLCanvasElement }).domElement;\n const w = source.width, h = source.height;\n const scratch = document.createElement('canvas');\n scratch.width = w; scratch.height = h;\n const g = scratch.getContext('2d', { willReadFrequently: true });\n if (!g) return none;\n const keep = w * h * 4 * times.length <= 96e6;\n const hash = (d: Uint8ClampedArray): number => { let x = 0x811c9dc5; for (let i = 0; i < d.length; i++) { x ^= d[i]!; x = Math.imul(x, 0x01000193); } return x >>> 0; };\n const ms: number[] = [];\n const threw = new Set<number>();\n const once = (t: number, timed: boolean): Uint8ClampedArray => {\n const from = performance.now();\n try {\n this._followSpace(t);\n this._threeSpec.update?.(t, ctx);\n this._draw(t);\n g.clearRect(0, 0, w, h);\n g.drawImage(source, 0, 0);\n } catch { threw.add(t); }\n if (timed) { g.getImageData(0, 0, 1, 1); ms.push(performance.now() - from); }\n return g.getImageData(0, 0, w, h).data;\n };\n for (const t of times) once(t, false); // the warm-up\n const first = times.map(t => { const d = once(t, true); return keep ? d.slice() : hash(d); });\n const second = [...times].reverse().map(t => once(t, false)).reverse();\n scratch.width = scratch.height = 1;\n const differs: CanvasCheck['differs'] = [];\n times.forEach((t, i) => {\n const a = first[i]!, b = second[i]!;\n if (typeof a === 'number') { if (a !== hash(b)) differs.push({ t, pixels: -1, maxDiff: -1 }); return; }\n let pixels = 0, maxDiff = 0;\n for (let k = 0; k < a.length; k++) { const d = Math.abs(a[k]! - b[k]!); if (d) { pixels++; if (d > maxDiff) maxDiff = d; } }\n if (pixels) differs.push({ t, pixels, maxDiff });\n });\n ms.sort((x, y) => x - y);\n return { differs: differs.filter(d => !threw.has(d.t)), drawMs: ms.length ? ms[Math.floor(ms.length / 2)]! : 0, threw: times.filter(t => threw.has(t)) };\n }\n\n /** `followCamera` / `followLights`: before each frame, ask the composition for its camera and lights at this moment (the layer's time on the composition's clock) and mirror them in the scene. */\n private _followSpace(t: number): void {\n const spec = this._threeSpec;\n if (!spec.followCamera && !spec.followLights && !spec.followFog) return;\n const ctx = this._ctx, scene = this._scene;\n if (!ctx || !scene) return;\n if (!this.parent?.spaceAt) {\n this._saidOnce('parent', `followCamera / followLights / followFog need the layer to sit in a composition that has a camera or a light to follow; this layer's parent cannot say (it keeps its own camera and lights)`, spec.name);\n return;\n }\n const space = this.parent.spaceAt((this.absoluteStart ?? this.at) + t);\n ctx.space = space;\n if (spec.followCamera) {\n const camera = ctx.camera as PerspectiveCamera;\n if (!camera.isPerspectiveCamera) this._saidOnce('camera', `followCamera needs a PerspectiveCamera (this layer's camera is a ${(ctx.camera as { type?: string }).type ?? 'different camera'}); it keeps it as it is`, spec.name);\n else applyCameraState(camera, space.camera, ctx.width / ctx.height);\n }\n if (spec.followLights) {\n const mirror = (this._lightMirror ??= new LightMirror(scene, Math.max(ctx.width, ctx.height) * 2));\n mirror.update(space.lights);\n if (!this._warnedSpace.has('inverseSquare')) this._checkInverseSquare(space.lights, scene, spec.name);\n if (mirror.castsShadows && !ctx.renderer.shadowMap.enabled) ctx.renderer.shadowMap.enabled = true;\n }\n if (spec.followFog) {\n if (space.fog && space.fog.amount !== 1) this._saidOnce('fogAmount', `followFog: the camera's fogAmount is ${space.fog.amount}, and three's Fog has no amount below 1: the layer uses the full amount (set fogColor to the colour you want at the far end, or leave followFog off and make the fog yourself from ctx.space.fog)`, spec.name);\n (this._fogMirror ??= new FogMirror(scene)).update(space.fog);\n }\n }\n\n /**\n * An inverse-square light is held at full strength inside its `radius` by the composition; three's decay-2 light keeps rising (4x at half the radius, 11x at a third). When the scene has\n * an object closer to such a light than 0.8 of its radius, say so once, with the way out. (The check is the scene's bounding box against the light's place: no object is measured.)\n */\n private _checkInverseSquare(lights: ReadonlyArray<{ kind: string; falloff: string; radius: number; x: number; y: number; z: number }>, scene: Scene, name: string | undefined): void {\n const near = lights.filter((l) => l.falloff === 'inverseSquare' && (l.kind === 'point' || l.kind === 'spot'));\n if (!near.length) return;\n const box = new Box3().setFromObject(scene);\n if (box.isEmpty()) return;\n for (const l of near) {\n const d = box.distanceToPoint(new Vector3(l.x, -l.y, l.z));\n if (d < 0.8 * l.radius) {\n this._saidOnce('inverseSquare', `followLights: a light with falloff 'inverseSquare' and radius ${l.radius} is only ${Math.round(d)} px from the nearest part of the scene. The composition holds such a light at full strength inside its radius; three's inverse-square light keeps rising there (${(Math.pow(l.radius / Math.max(d, 1), 2)).toFixed(1)}x at that distance), so those parts come out much brighter. Make the radius smaller than that distance, or use falloff 'smooth' (it is fitted to the composition's curve)`, name);\n return;\n }\n }\n }\n\n /** followCamera shows the whole composition through the layer's picture: a layer of another shape would show it squeezed or cut. Said once at build. */\n private _checkFollowShape(width: number, height: number, name: string | undefined): void {\n const p = this.parent;\n if (!p || !(p.width > 0 && p.height > 0)) return;\n if (Math.abs(width * p.height - height * p.width) <= 1e-3 * width * p.height) return;\n this._saidOnce('shape', `followCamera: the layer is ${width} x ${height} but the composition is ${p.width} x ${p.height}; the camera shows the whole composition, so the layer needs its aspect ratio (drop width / height to cover the composition)`, name);\n }\n\n private _saidOnce(key: string, message: string, name: string | undefined): void {\n if (this._warnedSpace.has(key)) return;\n this._warnedSpace.add(key);\n console.warn(`pixi-effects: three layer${name ? ` \"${name}\"` : ''}: ${message}`);\n }\n\n /**\n * One render of the scene at the layer-local time `t`. WebGPURenderer.render() needs `await init()` first (done in build); it queues the GPU work, and PixiJS reads the canvas after.\n *\n * Three's WebGPU node system updates the light uniforms (and its `time`) once per FRAME ID, and bumps that id in its own requestAnimationFrame loop only. Renders that\n * follow each other in one task (a seek, an export) would all show the lights of the last animation frame: a lamp keyframed with `three.lamp.intensity` would not move.\n * So before each render the layer advances the node frame itself, and gives `time` the layer's own time (not three's wall clock).\n */\n private _draw(t: number): void {\n if (!this._renderer || !this._scene || !this._camera) return;\n if (this._gpu) this._advanceNodeFrame(t);\n this._renderer.render(this._scene, this._camera);\n }\n\n /**\n * The author chose renderer: 'webgpu'. Three's WebGPU renderer turns materials into node materials: a ShaderMaterial / RawShaderMaterial cannot run there (three logs an error on\n * every render and draws a default material) and `onBeforeCompile` (a patch of the WebGL shader text) is ignored without a word. Stop, once, naming the first such material and the fix,\n * instead of drawing a picture that is wrong without saying so.\n */\n private _checkWebGpuMaterials(scene: Scene, layerName: string | undefined): void {\n const bad: string[] = [];\n const seen = new Set<unknown>();\n const check = (m: unknown): void => {\n if (!m || typeof m !== 'object' || seen.has(m)) return;\n seen.add(m);\n const mat = m as { type?: string; name?: string; isShaderMaterial?: boolean; isRawShaderMaterial?: boolean };\n const label = `${mat.name ? `\"${mat.name}\" ` : ''}${mat.type ?? 'material'}`;\n if (mat.isShaderMaterial || mat.isRawShaderMaterial) bad.push(`${label} is a ShaderMaterial (it cannot run on the WebGPU renderer)`);\n else if (Object.prototype.hasOwnProperty.call(mat, 'onBeforeCompile')) bad.push(`${label} sets onBeforeCompile (the WebGPU renderer ignores it)`);\n };\n scene.traverse?.((o: unknown) => {\n const mats = (o as { material?: unknown }).material;\n for (const m of Array.isArray(mats) ? mats : [mats]) check(m);\n });\n if (!bad.length) return;\n this._disposeRenderer();\n throw new Error(`pixi-effects: three layer${layerName ? ` \"${layerName}\"` : ''} with renderer: 'webgpu': ${bad[0]}${bad.length > 1 ? ` (and ${bad.length - 1} more)` : ''}. ` +\n `Add renderer: 'webgl' to this layer (or registerThree({ renderer: 'webgl' }) for the page), or write the look with three's node materials (TSL).`);\n }\n\n /** The one setup failure everybody meets on the WebGPU renderer: a PMREMGenerator imported from 'three' reads WebGL state the WebGPU renderer does not have. */\n private _explainWebGpuError(err: unknown, layerName: string | undefined): unknown {\n if (err instanceof TypeError && /reading 'buffers'|renderer\\.state/.test(err.message)) {\n return new Error(`pixi-effects: three layer${layerName ? ` \"${layerName}\"` : ''} with renderer: 'webgpu': setup used a WebGL-only helper, most likely a PMREMGenerator imported from 'three'. ` +\n `Import it from 'three/webgpu' (import * as THREE from 'three/webgpu'), or add renderer: 'webgl' to this layer.`, { cause: err });\n }\n return err;\n }\n\n private _advanceNodeFrame(t: number): void {\n const frame = (this._renderer as unknown as { _nodes?: { nodeFrame?: { update?: () => void; time: number; deltaTime: number } } })._nodes?.nodeFrame;\n if (!frame || typeof frame.update !== 'function') {\n if (!this._warnedNodeFrame) {\n this._warnedNodeFrame = true;\n console.warn(\"pixi-effects: this three has no node frame to advance (renderer: 'webgpu'): a light animated by keyframes may not follow the time in a seek or an export; use renderer: 'webgl' or report the three version\");\n }\n return;\n }\n frame.update();\n frame.time = t;\n frame.deltaTime = 1 / ((this.root as { frameRate?: number }).frameRate ?? 30);\n }\n\n private _resolveThreePath(path: string): { target: object; prop: string } | null {\n const segs = path.split('.');\n if (segs.length < 2) {\n this._warnPath(path, 'needs at least <object>.<prop>');\n return null;\n }\n let obj: unknown = this._objects[segs[0]!];\n if (obj == null) {\n this._warnPath(path, `unknown object \"${segs[0]}\" — expose it via setup's { objects }`);\n return null;\n }\n for (let i = 1; i < segs.length - 1; i++) {\n obj = (obj as Record<string, unknown>)[segs[i]!];\n if (obj == null) {\n this._warnPath(path, `\"${segs[i]}\" is undefined along the path`);\n return null;\n }\n }\n const prop = segs[segs.length - 1]!;\n if (typeof obj !== 'object' || !(prop in (obj as object))) {\n this._warnPath(path, `no property \"${prop}\"`);\n return null;\n }\n return { target: obj as object, prop };\n }\n\n private _warnPath(path: string, why: string): void {\n if (this._warnedPaths.has(path)) return;\n this._warnedPaths.add(path);\n console.warn(`pixi-effects: keyframe path three.${path} ${why}; skipped`);\n }\n\n /** Count this layer's renderer against the page's allowance of graphics contexts (given back when the renderer is disposed). */\n private _track(): void {\n this._tracked = true;\n trackThree(this._gpu ? 'webgpu' : 'webgl');\n }\n\n private _disposeRenderer(): void {\n if (!this._renderer) return;\n if (this._tracked) { this._tracked = false; releaseThree(this._gpu ? 'webgpu' : 'webgl'); }\n try {\n this._renderer.dispose();\n if (!this._gpu) (this._renderer as WebGLRenderer).forceContextLoss();\n } catch (err) {\n console.warn('pixi-effects: three renderer dispose threw —', err);\n }\n this._renderer = null;\n }\n\n override destroy(): void {\n const spec = this._threeSpec;\n if (this._ctx && spec.dispose) {\n try { spec.dispose(this._ctx); } catch (err) {\n console.warn('pixi-effects: three dispose() threw —', err);\n }\n }\n const texture = (this.target as Sprite | null)?.texture;\n this._lightMirror?.dispose();\n this._lightMirror = null;\n this._fogMirror?.dispose();\n this._fogMirror = null;\n this._disposeRenderer();\n this._scene = null;\n this._camera = null;\n this._ctx = null;\n this._objects = {};\n super.destroy();\n texture?.destroy(true); // canvas-backed source is per-sequence; safe to kill\n }\n}\n\nfunction resolveDim(v: PropValue | undefined, scope: Record<string, number>): number | undefined {\n if (v === undefined) return undefined;\n if (typeof v === 'number') return v;\n return evaluateExpr(v, scope);\n}\n","/**\n * Two helpers for a glTF model in a `three` layer's `setup` / `update` (the layer stays the free box; these are what is easy to get wrong by hand):\n *\n * const fox = await threeGltf('Fox.glb', { animation: 'Run' }); // in setup\n * ctx.scene.add(fox.object); threeFrameCamera(ctx.camera, fox.object);\n * ... update: (t) => fox.pose(t) // the clip at the layer's time: a function of t, never of a clock\n *\n * The loader is an addon: a page that never calls `threeGltf` never loads it (the import map needs `\"three/addons/\"` next to `\"three\"`).\n */\nimport { AnimationMixer, Box3, Group, LoopOnce, LoopRepeat, Vector3, type AnimationClip, type Camera, type Object3D, type PerspectiveCamera } from 'three';\n\nexport interface ThreeGltfOptions {\n /** A clip name, a clip index, or `false` (no animation: the model's bind pose). Default: the first clip, if the file has one. */\n animation?: string | number | false;\n /** The clip time is `t × speed + offset` (the layer's seconds). Defaults 1 and 0. */\n speed?: number;\n offset?: number;\n /** `true` (default): the clip repeats; `false`: it holds its last pose. */\n loop?: boolean;\n}\n\nexport interface ThreeGltfModel {\n /** Add this to `ctx.scene`. A group whose origin is the centre of the model's bounding box (bind pose): position, turn and `fit` it about its centre. */\n object: Group;\n /** The names of the clips the file has. */\n clips: string[];\n /** The size of the model's bounding box in the file's own units (bind pose, before `fit`). */\n size: Vector3;\n /** Pose the model at the layer's time `t` (seconds). `AnimationMixer.setTime` evaluates the clip from zero every call: a seek, an export and a repeat give the same pose. */\n pose(t: number): void;\n /** Scale `object` so the model's longest side is `px` (a model in metres in a scene in composition pixels). */\n fit(px: number): void;\n /** Stop the clip. Geometries, materials and textures are yours to dispose with the scene. */\n dispose(): void;\n}\n\nexport async function threeGltf(url: string, options: ThreeGltfOptions = {}): Promise<ThreeGltfModel> {\n const label = 'pixi-effects: threeGltf';\n if (typeof url !== 'string' || !url) throw new Error(`${label}: the first argument is the URL of a .glb or .gltf file`);\n let GLTFLoader: typeof import('three/addons/loaders/GLTFLoader.js').GLTFLoader;\n try { ({ GLTFLoader } = await import('three/addons/loaders/GLTFLoader.js')); } catch (err) {\n throw new Error(`${label}: needs \"three/addons/\" in the import map next to \"three\" (${err instanceof Error ? err.message : err})`);\n }\n let gltf: Awaited<ReturnType<InstanceType<typeof GLTFLoader>['loadAsync']>>;\n try { gltf = await new GLTFLoader().loadAsync(url); } catch (err) {\n throw new Error(`${label}: could not load \"${url}\" (${err instanceof Error ? err.message : err})`, { cause: err });\n }\n\n const clips: AnimationClip[] = gltf.animations ?? [];\n let clip: AnimationClip | undefined;\n const wanted = options.animation;\n if (wanted === false || (wanted === undefined && clips.length === 0)) clip = undefined;\n else if (wanted === undefined) clip = clips[0];\n else {\n clip = typeof wanted === 'number' ? clips[wanted] : clips.find((c) => c.name === wanted);\n if (!clip) throw new Error(`${label}: \"${url}\" has no animation ${JSON.stringify(wanted)}; its clips: ${clips.length ? clips.map((c, i) => `${i}: \"${c.name}\"`).join(', ') : '(none)'}`);\n }\n\n // The origin of the group is the centre of the box, so the model is placed and turned about its centre.\n const root: Object3D = gltf.scene;\n // A skinned mesh is always drawn. three culls a mesh by a bounding sphere, and a skinned mesh's sphere does not follow its animation or its place: a model that MOVES and throws a shadow\n // drew its shadow differently depending on the frames drawn before it (found on the Khronos Fox: `check` reported the layer as not a function of the time; with culling off the\n // pictures are the same in any order). The cost is that an off-screen model is still drawn.\n root.traverse((o) => { if ((o as { isSkinnedMesh?: boolean }).isSkinnedMesh) o.frustumCulled = false; });\n const object = new Group();\n object.add(root);\n const bounds = new Box3().setFromObject(root);\n const centre = bounds.getCenter(new Vector3());\n const size = bounds.getSize(new Vector3());\n root.position.sub(centre);\n\n let mixer: AnimationMixer | null = null;\n if (clip) {\n mixer = new AnimationMixer(root);\n const action = mixer.clipAction(clip);\n action.setLoop(options.loop === false ? LoopOnce : LoopRepeat, Infinity);\n action.clampWhenFinished = true;\n action.play();\n }\n const speed = options.speed ?? 1, offset = options.offset ?? 0;\n\n return {\n object,\n clips: clips.map((c) => c.name),\n size,\n pose: (t) => { mixer?.setTime(t * speed + offset); },\n fit: (px) => { object.scale.setScalar(px / Math.max(size.x, size.y, size.z, 1e-9)); },\n dispose: () => { mixer?.stopAllAction(); mixer?.uncacheRoot(root); mixer = null; },\n };\n}\n\nexport interface ThreeFrameCameraOptions {\n /** The direction the camera sits in from the centre of the model, any length. Default `[0.45, 0.3, 1]`: a three-quarter view, a little from the side and above. */\n direction?: [number, number, number];\n /** Free room around the model: 1.1 (the default) leaves 10 %. */\n margin?: number;\n}\n\n/**\n * Put `camera` where the whole of `object` (its bounding box now, with its scale and place) fits the frame, looking at its centre: the smallest distance at which the 8 corners of\n * the box all fit both the vertical and the horizontal field of view (a bounding sphere would leave a long model small and head-on). `near` and `far` follow the distance.\n * Uses the camera's own `fov` and `aspect`. For a clip that travels far, give your own camera: the box is the bind pose.\n */\nexport function threeFrameCamera(camera: PerspectiveCamera | Camera, object: Object3D, options: ThreeFrameCameraOptions = {}): void {\n const cam = camera as PerspectiveCamera;\n object.updateMatrixWorld(true);\n const bounds = new Box3().setFromObject(object);\n const centre = bounds.getCenter(new Vector3());\n const margin = options.margin ?? 1.1;\n const [dx, dy, dz] = options.direction ?? [0.45, 0.3, 1];\n const toCamera = new Vector3(dx, dy, dz).normalize();\n const right = new Vector3().crossVectors(new Vector3(0, 1, 0), toCamera);\n if (right.lengthSq() < 1e-12) right.set(1, 0, 0); // straight above or below: any right will do\n right.normalize();\n const up = new Vector3().crossVectors(toCamera, right);\n const tanV = Math.tan((cam.fov * Math.PI) / 360), tanH = tanV * cam.aspect;\n let distance = 1e-3;\n for (const x of [bounds.min.x, bounds.max.x]) for (const y of [bounds.min.y, bounds.max.y]) for (const z of [bounds.min.z, bounds.max.z]) {\n const r = new Vector3(x, y, z).sub(centre);\n distance = Math.max(distance, r.dot(toCamera) + (Math.abs(r.dot(right)) * margin) / tanH, r.dot(toCamera) + (Math.abs(r.dot(up)) * margin) / tanV);\n }\n cam.position.copy(centre).addScaledVector(toCamera, distance);\n cam.near = Math.max(distance / 100, 1e-4);\n cam.far = distance * 100;\n cam.lookAt(centre);\n cam.updateProjectionMatrix();\n}\n","/**\n * pixi-effects/three — optional three.js integration.\n *\n * Import this entry only when you use `type: 'three'` sequences; the core\n * `pixi-effects` entry never touches three.js. Call `registerThree()` once\n * before Movie.init builds a composition containing a three sequence.\n */\nimport { registerSequenceType, type SequenceCtor } from '../core/Composition';\nimport { ThreeSequence } from './ThreeSequence';\nimport { checkRendererKind, setPageRenderer, type ThreeRendererKind } from './defaults';\nimport type { SequenceSpec } from '../types';\nimport type { ThreeSequenceSpec } from './types';\n\nexport { ThreeSequence } from './ThreeSequence';\nexport { threeGltf, threeFrameCamera } from './gltf';\nexport type { ThreeGltfModel, ThreeGltfOptions, ThreeFrameCameraOptions } from './gltf';\nexport type { ThreeContext, ThreeSetupResult, ThreeSequenceSpec } from './types';\nexport type { ThreeRendererKind } from './defaults';\n\n/**\n * Register the 'three' sequence type. Explicit call so `sideEffects: false` bundlers can't drop it; calling it again is fine.\n * `registerThree({ renderer: 'webgpu' })` makes every three layer that does not name a `renderer` of its own use three's WebGPU renderer; the default is `'webgl'`\n * (the last call wins).\n */\nexport function registerThree(options: { renderer?: ThreeRendererKind } = {}): void {\n const kind = options.renderer ?? 'webgl';\n checkRendererKind(kind, \"registerThree's renderer\");\n setPageRenderer(kind);\n registerSequenceType('three', ThreeSequence as unknown as SequenceCtor);\n}\n\n/**\n * Typing helper: accepts a strongly-typed three spec and returns it as a\n * core SequenceSpec, keeping three.js types out of the core union.\n */\nexport function three(spec: ThreeSequenceSpec): SequenceSpec {\n return spec as unknown as SequenceSpec;\n}\n"]}
package/docs/api.md CHANGED
@@ -165,6 +165,23 @@ interface InspectReport {
165
165
  }
166
166
  ```
167
167
 
168
+ ### `movie.pick(x, y, options?): PickHit | null`, `movie.pickAll(x, y, options?): PickHit[]`, `movie.canvasPoint(event): [x, y]`
169
+
170
+ What is under a point of the canvas, at the frame that is on screen: the layer on top (`pick`), or every layer under the point, the top first (`pickAll`). `x`, `y` are canvas pixels (the movie's own `width` × `height`); `canvasPoint(event)` makes them from a pointer event (`clientX` / `clientY`) when the canvas is shown larger or smaller than its own size: `movie.pick(...movie.canvasPoint(event))`. It reads the frame as the last draw left it, so after `await movie.snapshot(frame)` or any seek it answers for that frame; it takes no time and has no clock.
171
+
172
+ ```ts
173
+ interface PickHit {
174
+ name?: string; path: string; type: string; // path: as in inspect(), names or type#index joined by '/'
175
+ kind: 'flat' | 'card' | 'three'; // a 2D layer, a threeD layer (its projected card), a three layer
176
+ point: { x: number; y: number }; // the point asked about
177
+ local?: { x: number; y: number }; // a flat layer: the point in the layer's own pixels
178
+ three?: { object: string; point: [number, number, number]; distance: number; object3d: unknown }; // a three layer: what the ray met first
179
+ }
180
+ // options: { only?: string[], ignore?: string[] } layer names or paths
181
+ ```
182
+
183
+ How a layer is asked: a flat layer by its own shape (a rotated one by its rotated rectangle, a shape by its outline: a circle is hit inside the circle, not at the corners of its box), text, images and video by their box; a `threeD` layer by its projected quad (the card seen from behind is hit too; a `threeD` composition is one card: what is inside it is not asked); a `three` layer by a ray through its camera (with `followCamera` the composition's camera), skipping invisible objects: `hit.three.object` is the name of the object it met (its own, or its nearest ancestor's that has one) and `object3d` the live three object. A layer not alive at the frame, at alpha 0, hidden by a parent, or outside its mask is not hit; a group (a nested composition without `threeD`) is not a target, the layers in it are. A transparent corner of a picture still counts as the picture (the box is what is asked). What is not here: hover and cursor, dragging, touch with several fingers.
184
+
168
185
  ### `movie.inspectAudio(options?): AudioReport`
169
186
 
170
187
  The soundtrack as numbers — for checking sound without listening. Every sound is also measured on its own, so overlaps do not blur it. `options.window`: seconds per row of `windows` (default 0.1).
package/docs/dsl.md CHANGED
@@ -822,7 +822,7 @@ three({ type: 'three', name: 'world', followCamera: true, followLights: true,
822
822
  ```
823
823
 
824
824
  - **`followCamera`** puts the layer's `PerspectiveCamera` where the composition's active camera is, every frame: position, look-at point and vertical `fov` (also the `offset` props of a handheld shake). The scene is in **composition pixels with y flipped** (three's y runs up, the composition's down; +z is toward the viewer in both), so a flat layer and a three object at the same `(x, -y, z)` land on the same pixel (checked to 1e-6 px for several cameras, and in the real picture against the composition's own cards: mean 0.14–0.19 of 255, edges only). `near` is 1 and `far` 20000 (it is px: the default camera is about 740 away). The camera must be a `PerspectiveCamera` and the layer must have the composition's aspect ratio (the camera shows the whole composition): both are warned once. Your own `update(t, ctx)` runs after the camera is set, so it may nudge it.
825
- - **`followLights`** makes the composition's `light` layers three lights in `ctx.scene`, one per light alive, moved every frame (a light that ended is switched off). `ambient` → `AmbientLight`, `point` → `PointLight`, `spot` → `SpotLight` (`coneAngle` / 2 is the angle, `coneFeather` the penumbra), `parallel` → `DirectionalLight` toward its look-at point; position `(x, -y, z)`, colour and `intensity` as written (three divides a diffuse surface by π, so the layer multiplies by π: intensity 1 is "as bright as the colour", like a card). `falloff: 'none'` is no attenuation; `'inverseSquare'` is decay 2 and full at `radius`; `'smooth'` is three's own cutoff at `radius + falloffDistance` (the same idea, not the same curve). **Shadows** follow the light: a light with `castsShadows: true` casts in three (the darkness is the shadow's intensity, `shadowDiffusion` softens its edge; the layer switches its renderer's shadow map on), and the layer's own meshes decide who casts and who receives (`mesh.castShadow = true`, `mesh.receiveShadow = true`; a plane needs `material.shadowSide = THREE.DoubleSide` to cast). The composition's `castsShadows` on a layer is not read (its layers are not in the scene). **Fog** is `followFog`. The layer's own lights stay as they are.
825
+ - **`followLights`** makes the composition's `light` layers three lights in `ctx.scene`, one per light alive, moved every frame (a light that ended is switched off). `ambient` → `AmbientLight`, `point` → `PointLight`, `spot` → `SpotLight` (`coneAngle` / 2 is the angle, `coneFeather` the penumbra), `parallel` → `DirectionalLight` toward its look-at point; position `(x, -y, z)`, colour and `intensity` as written (three divides a diffuse surface by π, so the layer multiplies by π: intensity 1 is "as bright as the colour", like a card). `falloff: 'none'` is no attenuation. `'inverseSquare'` is decay 2 and full at `radius`: **outside the radius it matches the composition's** (measured mean 0.02–0.03 of 255), but inside it three keeps rising where the composition holds 1 (4× at half the radius): the layer warns once when an object is closer than 0.8 of the radius, and the way out is a smaller radius or `'smooth'`. `'smooth'` fits three's cut-off to the composition's curve (1 inside `radius`, a smoothstep to 0 at `radius + falloffDistance`): three's curve is gentler, so the fit halves the largest difference (about 0.09–0.17 of the light's strength for a fall that is not steep, mean 0.08–0.28 of 255 in the real picture; a fall that is steep against its radius, say `falloffDistance` 100 at `radius` 500, can differ by about 0.3). **Shadows** follow the light: a light with `castsShadows: true` casts in three (the darkness is the shadow's intensity, `shadowDiffusion` softens its edge; the layer switches its renderer's shadow map on), and the layer's own meshes decide who casts and who receives (`mesh.castShadow = true`, `mesh.receiveShadow = true`; a plane needs `material.shadowSide = THREE.DoubleSide` to cast). The composition's `castsShadows` on a layer is not read (its layers are not in the scene). **Fog** is `followFog`. The layer's own lights stay as they are.
826
826
  - **`followFog`** makes the composition camera's fog (`fogNear`, `fogFar`, `fogColor`) the scene's `Fog`, every frame (the `Fog` goes when the camera that wrote it is over; a `scene.fog` the layer made itself is never touched; `ctx.space.fog` has the numbers). It is **close, not equal**: three fades with `smoothstep` between `near` and `far` where the composition fades linearly, and three's Fog has no amount below 1 (`fogAmount` other than 1 warns once and the full amount is used). Measured against the composition's own cards: a mean difference of 0.5–1.8 of 255, where the fog itself changes the picture by 2–7. On `renderer: 'webgpu'` fog is blended before tone mapping, as for any three scene (see below).
827
827
  - **How close the shadow is to a card's.** A card in front of a wall under a spot light throws the same shadow on the wall as the composition's cards do (same place, size and darkness): mean difference 0.2–0.35 of 255, on WebGL and WebGPU; what differs is the edge of the shadow map (a hard shadow of a small card is a little jagged at the default 2048 map). Soft shadows (`shadowDiffusion`) are three's PCF blur, not the composition's 16-sample penumbra: similar in kind, not in shape.
828
828
  - **How close the light is to a card's.** The composition shades a card on sRGB values (`colour × (ambient + the lights)`); three lights in linear light. With `MeshLambertMaterial` and three's colour management off (`THREE.ColorManagement.enabled = false` and `ctx.renderer.outputColorSpace = THREE.LinearSRGBColorSpace` at the top of `setup`; **both are global to the page's three**, so they colour every three layer there) the planes shade like the cards: measured mean 0.02–0.04 of 255 (ambient), 0.16–0.20 (point), 0.11–0.14 (parallel), 0.14–0.16 (spot). With three's defaults (the right choice for glTF models and `MeshStandardMaterial`) the lights are close and not equal: mean 0.8–1.4 of 255. A physically based material answers the light the way it does in three, not the way a card does.
package/llms-full.txt CHANGED
@@ -6,7 +6,7 @@ Concatenation of the skill, cheatsheet, pitfalls, recipes and the DSL / API / me
6
6
 
7
7
  <!-- ===== skills/pixi-effects/SKILL.md ===== -->
8
8
 
9
- > Written for pixi-effects 0.40.0. Update this skill with `npx skills update`; the newest docs are at https://yjmtmtk.github.io/pixi-effects/
9
+ > Written for pixi-effects 0.41.0. Update this skill with `npx skills update`; the newest docs are at https://yjmtmtk.github.io/pixi-effects/
10
10
 
11
11
  # pixi-effects — write a video as data
12
12
 
@@ -34,7 +34,7 @@ You describe a video as a tree of plain objects; the library plays it in a canva
34
34
  **Read `reference/direction.md` before writing a composition for a product film, a company introduction, a launch or a data story.** It is renderer-neutral: write `brief.md` (the one sentence to remember, the REAL assets with paths, what must never be invented; if a needed asset is missing, stop and ask), `style-guide.md` (palette and type taken from the real source, a motion rule per class of object) and `shotlist.md` (a row per beat with entry and exit state) next to the page; then build, then review the rendered frames cold. What is specific to this library:
35
35
 
36
36
  - **Time and sound:** pick a tempo whose bar is a round number of seconds (96 bpm: 2.5 s; 120 bpm: 2 s), put every cut on a bar line and every sfx on its beat. `npx pixi-effects check` prints a `music` read-back (bars per track, what starts on which beat, the drum span): verify the sound with it.
37
- - **Review:** `check --at 3.5,title@end,50%` writes the contact sheet and single frames; look at mid-transition frames of the exported file too. Frames are seekable and deterministic here: render the same range twice and compare the frames if you doubt it.
37
+ - **Review:** `check --at 3.5,title@end,50% --pick 640,360` also says what is under that canvas point at each moment (the layers, top first; a three layer names the object) — a layout question you can answer without looking; `check --at 3.5,title@end,50%` writes the contact sheet and single frames; look at mid-transition frames of the exported file too. Frames are seekable and deterministic here: render the same range twice and compare the frames if you doubt it.
38
38
  - **Formats:** make the formats the human asked for, one if they did not say. When a vertical cut is wanted it is its own composition: one source, a layout function, `?f=9x16` (recipe `two-formats`); `check` and `render` take `--query f=9x16`.
39
39
  - Fit a picture into a rectangle with the `photo()` helper of that recipe (`scale: 'cover'` fits the PARENT only); designed pictures (posters, flyers, screenshots) are shown whole, never cropped.
40
40
 
@@ -301,6 +301,7 @@ await movie.contactSheet({ count: 6, as: 'dataURL' }) // ONE image of several
301
301
  await movie.snapshot(60, { as: 'dataURL' }) // one frame, canvas only (no player bar) — use it for detail; sheet tiles are small
302
302
  await movie.inspect(60, { layers: 'none' }) // issues only (default lists the visible layers); text off-canvas / cut off / empty / overlapping text. Name your layers so paths are readable
303
303
  await movie.onionSkin({ from: 1, to: 3, count: 8, as: 'dataURL' }) // frames overlaid into ONE picture of a movement (later = stronger): path and easing at a glance
304
+ movie.pick(x, y) // what is under a canvas point at the frame on screen: { name, path, type, kind: 'flat' | 'card' | 'three', local?, three?: { object, point, distance } } or null (pickAll: the whole stack, top first; { only, ignore }); in a click handler: `movie.pick(...movie.canvasPoint(event))`; to ask about another frame: `await movie.snapshot(f)` first
304
305
  movie.review({ at: 'title@end' }) // what `pixi-effects check` looks at, as data: { frames, problems (text cut off, off-canvas, no size), review (text overlaps: look at them), fonts, audio, at }; leaves the movie as it was. `strict: true` makes every issue a problem
305
306
  movie.resolveAt('3.5, 50%, f120, title@end') // moments → [{ label, frame }]; a mistake says what could not be read
306
307
  movie.inspectFonts() // { missing: [{ layer, family }] (no font of the list is installed), failed: [web fonts whose file did not load] }
@@ -1852,6 +1853,29 @@ return [
1852
1853
 
1853
1854
  A moving, shadow-casting model is held to "a function of the time" by `check`: place it from `t` in `update` (as above) and let `threeGltf` load it (it draws a skinned mesh always: three culls it by a bounding sphere that does not follow it).
1854
1855
 
1856
+ ## Click a layer: what is under the pointer (`movie.pick`)
1857
+
1858
+ `movie.pick(x, y)` answers "what is drawn under this point, at the frame on screen" with no hit-testing code of yours: a flat layer by its own shape, a `threeD` card by its projected quad, a `three` layer by a ray (the hit says which object). `movie.canvasPoint(event)` turns a pointer event into canvas pixels, whatever size the canvas is shown at. Name the layers you want to react to.
1859
+
1860
+ ```js
1861
+ // @docs-only pick-click
1862
+ // in the page, after movie.init(...): a click on the fox, on the title, or on the wall behind them
1863
+ const canvas = document.getElementById('stage');
1864
+ canvas.addEventListener('click', (event) => {
1865
+ const hit = movie.pick(...movie.canvasPoint(event)); // the layer on top of that point, or null
1866
+ if (!hit) return;
1867
+ if (hit.kind === 'three' && hit.three.object === 'fox') console.log('the fox, at distance', hit.three.distance); // a three layer: the object the ray met
1868
+ else if (hit.name === 'title') movie.play(); // a flat layer: by its name
1869
+ });
1870
+ canvas.addEventListener('pointermove', (event) => {
1871
+ const hit = movie.pick(...movie.canvasPoint(event), { ignore: ['background'] }); // { only } / { ignore }: layer names or paths
1872
+ canvas.style.cursor = hit ? 'pointer' : 'default';
1873
+ });
1874
+ // a test, or an AI checking its own page, asks about a chosen frame: await movie.snapshot(90); movie.pick(640, 360)
1875
+ ```
1876
+
1877
+ `pick` reads the frame as the last draw left it (it takes no time and has no clock), so a paused movie answers for the frame it shows. A transparent corner of a picture still counts as the picture; hover effects and dragging are yours to build on `pick`.
1878
+
1855
1879
  ## Subtitles from an SRT file
1856
1880
 
1857
1881
  Subtitles are just text layers. The function reads a `.srt` (numbers, `00:00:01,000 --> 00:00:03,500`, the words) and returns one layer per cue: it appears and disappears over 0.12 s, sits 90 px above the bottom edge, wraps at 1000 px (about 80 % of a 1280 px picture) and has a black outline so it reads on any picture. Two cues that overlap in time are drawn on top of each other: split a long line into two lines in the `.srt` rather than relying on wrapping. Check the result with `pixi-effects check`; it reports text that is cut off by the edge.
@@ -2964,7 +2988,7 @@ three({ type: 'three', name: 'world', followCamera: true, followLights: true,
2964
2988
  ```
2965
2989
 
2966
2990
  - **`followCamera`** puts the layer's `PerspectiveCamera` where the composition's active camera is, every frame: position, look-at point and vertical `fov` (also the `offset` props of a handheld shake). The scene is in **composition pixels with y flipped** (three's y runs up, the composition's down; +z is toward the viewer in both), so a flat layer and a three object at the same `(x, -y, z)` land on the same pixel (checked to 1e-6 px for several cameras, and in the real picture against the composition's own cards: mean 0.14–0.19 of 255, edges only). `near` is 1 and `far` 20000 (it is px: the default camera is about 740 away). The camera must be a `PerspectiveCamera` and the layer must have the composition's aspect ratio (the camera shows the whole composition): both are warned once. Your own `update(t, ctx)` runs after the camera is set, so it may nudge it.
2967
- - **`followLights`** makes the composition's `light` layers three lights in `ctx.scene`, one per light alive, moved every frame (a light that ended is switched off). `ambient` → `AmbientLight`, `point` → `PointLight`, `spot` → `SpotLight` (`coneAngle` / 2 is the angle, `coneFeather` the penumbra), `parallel` → `DirectionalLight` toward its look-at point; position `(x, -y, z)`, colour and `intensity` as written (three divides a diffuse surface by π, so the layer multiplies by π: intensity 1 is "as bright as the colour", like a card). `falloff: 'none'` is no attenuation; `'inverseSquare'` is decay 2 and full at `radius`; `'smooth'` is three's own cutoff at `radius + falloffDistance` (the same idea, not the same curve). **Shadows** follow the light: a light with `castsShadows: true` casts in three (the darkness is the shadow's intensity, `shadowDiffusion` softens its edge; the layer switches its renderer's shadow map on), and the layer's own meshes decide who casts and who receives (`mesh.castShadow = true`, `mesh.receiveShadow = true`; a plane needs `material.shadowSide = THREE.DoubleSide` to cast). The composition's `castsShadows` on a layer is not read (its layers are not in the scene). **Fog** is `followFog`. The layer's own lights stay as they are.
2991
+ - **`followLights`** makes the composition's `light` layers three lights in `ctx.scene`, one per light alive, moved every frame (a light that ended is switched off). `ambient` → `AmbientLight`, `point` → `PointLight`, `spot` → `SpotLight` (`coneAngle` / 2 is the angle, `coneFeather` the penumbra), `parallel` → `DirectionalLight` toward its look-at point; position `(x, -y, z)`, colour and `intensity` as written (three divides a diffuse surface by π, so the layer multiplies by π: intensity 1 is "as bright as the colour", like a card). `falloff: 'none'` is no attenuation. `'inverseSquare'` is decay 2 and full at `radius`: **outside the radius it matches the composition's** (measured mean 0.02–0.03 of 255), but inside it three keeps rising where the composition holds 1 (4× at half the radius): the layer warns once when an object is closer than 0.8 of the radius, and the way out is a smaller radius or `'smooth'`. `'smooth'` fits three's cut-off to the composition's curve (1 inside `radius`, a smoothstep to 0 at `radius + falloffDistance`): three's curve is gentler, so the fit halves the largest difference (about 0.09–0.17 of the light's strength for a fall that is not steep, mean 0.08–0.28 of 255 in the real picture; a fall that is steep against its radius, say `falloffDistance` 100 at `radius` 500, can differ by about 0.3). **Shadows** follow the light: a light with `castsShadows: true` casts in three (the darkness is the shadow's intensity, `shadowDiffusion` softens its edge; the layer switches its renderer's shadow map on), and the layer's own meshes decide who casts and who receives (`mesh.castShadow = true`, `mesh.receiveShadow = true`; a plane needs `material.shadowSide = THREE.DoubleSide` to cast). The composition's `castsShadows` on a layer is not read (its layers are not in the scene). **Fog** is `followFog`. The layer's own lights stay as they are.
2968
2992
  - **`followFog`** makes the composition camera's fog (`fogNear`, `fogFar`, `fogColor`) the scene's `Fog`, every frame (the `Fog` goes when the camera that wrote it is over; a `scene.fog` the layer made itself is never touched; `ctx.space.fog` has the numbers). It is **close, not equal**: three fades with `smoothstep` between `near` and `far` where the composition fades linearly, and three's Fog has no amount below 1 (`fogAmount` other than 1 warns once and the full amount is used). Measured against the composition's own cards: a mean difference of 0.5–1.8 of 255, where the fog itself changes the picture by 2–7. On `renderer: 'webgpu'` fog is blended before tone mapping, as for any three scene (see below).
2969
2993
  - **How close the shadow is to a card's.** A card in front of a wall under a spot light throws the same shadow on the wall as the composition's cards do (same place, size and darkness): mean difference 0.2–0.35 of 255, on WebGL and WebGPU; what differs is the edge of the shadow map (a hard shadow of a small card is a little jagged at the default 2048 map). Soft shadows (`shadowDiffusion`) are three's PCF blur, not the composition's 16-sample penumbra: similar in kind, not in shape.
2970
2994
  - **How close the light is to a card's.** The composition shades a card on sRGB values (`colour × (ambient + the lights)`); three lights in linear light. With `MeshLambertMaterial` and three's colour management off (`THREE.ColorManagement.enabled = false` and `ctx.renderer.outputColorSpace = THREE.LinearSRGBColorSpace` at the top of `setup`; **both are global to the page's three**, so they colour every three layer there) the planes shade like the cards: measured mean 0.02–0.04 of 255 (ambient), 0.16–0.20 (point), 0.11–0.14 (parallel), 0.14–0.16 (spot). With three's defaults (the right choice for glTF models and `MeshStandardMaterial`) the lights are close and not equal: mean 0.8–1.4 of 255. A physically based material answers the light the way it does in three, not the way a card does.
@@ -4137,6 +4161,23 @@ interface InspectReport {
4137
4161
  }
4138
4162
  ```
4139
4163
 
4164
+ ### `movie.pick(x, y, options?): PickHit | null`, `movie.pickAll(x, y, options?): PickHit[]`, `movie.canvasPoint(event): [x, y]`
4165
+
4166
+ What is under a point of the canvas, at the frame that is on screen: the layer on top (`pick`), or every layer under the point, the top first (`pickAll`). `x`, `y` are canvas pixels (the movie's own `width` × `height`); `canvasPoint(event)` makes them from a pointer event (`clientX` / `clientY`) when the canvas is shown larger or smaller than its own size: `movie.pick(...movie.canvasPoint(event))`. It reads the frame as the last draw left it, so after `await movie.snapshot(frame)` or any seek it answers for that frame; it takes no time and has no clock.
4167
+
4168
+ ```ts
4169
+ interface PickHit {
4170
+ name?: string; path: string; type: string; // path: as in inspect(), names or type#index joined by '/'
4171
+ kind: 'flat' | 'card' | 'three'; // a 2D layer, a threeD layer (its projected card), a three layer
4172
+ point: { x: number; y: number }; // the point asked about
4173
+ local?: { x: number; y: number }; // a flat layer: the point in the layer's own pixels
4174
+ three?: { object: string; point: [number, number, number]; distance: number; object3d: unknown }; // a three layer: what the ray met first
4175
+ }
4176
+ // options: { only?: string[], ignore?: string[] } layer names or paths
4177
+ ```
4178
+
4179
+ How a layer is asked: a flat layer by its own shape (a rotated one by its rotated rectangle, a shape by its outline: a circle is hit inside the circle, not at the corners of its box), text, images and video by their box; a `threeD` layer by its projected quad (the card seen from behind is hit too; a `threeD` composition is one card: what is inside it is not asked); a `three` layer by a ray through its camera (with `followCamera` the composition's camera), skipping invisible objects: `hit.three.object` is the name of the object it met (its own, or its nearest ancestor's that has one) and `object3d` the live three object. A layer not alive at the frame, at alpha 0, hidden by a parent, or outside its mask is not hit; a group (a nested composition without `threeD`) is not a target, the layers in it are. A transparent corner of a picture still counts as the picture (the box is what is asked). What is not here: hover and cursor, dragging, touch with several fingers.
4180
+
4140
4181
  ### `movie.inspectAudio(options?): AudioReport`
4141
4182
 
4142
4183
  The soundtrack as numbers — for checking sound without listening. Every sound is also measured on its own, so overlaps do not blur it. `options.window`: seconds per row of `windows` (default 0.1).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pixi-effects",
3
- "version": "0.40.0",
3
+ "version": "0.41.0",
4
4
  "description": "Declarative composition and video rendering for the web. Built on PixiJS v8.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -3,7 +3,7 @@ name: pixi-effects
3
3
  description: Use when asked to make, animate, preview or export a video, motion graphics, an animated title, a lower third, kinetic type, a promo, a slideshow with transitions, an animated chart or data story, a social clip, a 2.5D / depth scene, or music and sound for a video, written as code in JavaScript or HTML. pixi-effects is a JS library where a video is a plain-object composition (text, shape, image, video, audio and file-free sfx / music, camera, light and shader layers with keyframes) that plays in the browser, is checked by a tool the agent can run, and exports MP4 / WebM / MOV with no server. Not for a project that already uses another video tool (Remotion, Motion Canvas, ffmpeg); follow that tool instead.
4
4
  ---
5
5
 
6
- > Written for pixi-effects 0.40.0. Update this skill with `npx skills update`; the newest docs are at https://yjmtmtk.github.io/pixi-effects/
6
+ > Written for pixi-effects 0.41.0. Update this skill with `npx skills update`; the newest docs are at https://yjmtmtk.github.io/pixi-effects/
7
7
 
8
8
  # pixi-effects — write a video as data
9
9
 
@@ -31,7 +31,7 @@ You describe a video as a tree of plain objects; the library plays it in a canva
31
31
  **Read `reference/direction.md` before writing a composition for a product film, a company introduction, a launch or a data story.** It is renderer-neutral: write `brief.md` (the one sentence to remember, the REAL assets with paths, what must never be invented; if a needed asset is missing, stop and ask), `style-guide.md` (palette and type taken from the real source, a motion rule per class of object) and `shotlist.md` (a row per beat with entry and exit state) next to the page; then build, then review the rendered frames cold. What is specific to this library:
32
32
 
33
33
  - **Time and sound:** pick a tempo whose bar is a round number of seconds (96 bpm: 2.5 s; 120 bpm: 2 s), put every cut on a bar line and every sfx on its beat. `npx pixi-effects check` prints a `music` read-back (bars per track, what starts on which beat, the drum span): verify the sound with it.
34
- - **Review:** `check --at 3.5,title@end,50%` writes the contact sheet and single frames; look at mid-transition frames of the exported file too. Frames are seekable and deterministic here: render the same range twice and compare the frames if you doubt it.
34
+ - **Review:** `check --at 3.5,title@end,50% --pick 640,360` also says what is under that canvas point at each moment (the layers, top first; a three layer names the object) — a layout question you can answer without looking; `check --at 3.5,title@end,50%` writes the contact sheet and single frames; look at mid-transition frames of the exported file too. Frames are seekable and deterministic here: render the same range twice and compare the frames if you doubt it.
35
35
  - **Formats:** make the formats the human asked for, one if they did not say. When a vertical cut is wanted it is its own composition: one source, a layout function, `?f=9x16` (recipe `two-formats`); `check` and `render` take `--query f=9x16`.
36
36
  - Fit a picture into a rectangle with the `photo()` helper of that recipe (`scale: 'cover'` fits the PARENT only); designed pictures (posters, flyers, screenshots) are shown whole, never cropped.
37
37
 
@@ -180,6 +180,7 @@ await movie.contactSheet({ count: 6, as: 'dataURL' }) // ONE image of several
180
180
  await movie.snapshot(60, { as: 'dataURL' }) // one frame, canvas only (no player bar) — use it for detail; sheet tiles are small
181
181
  await movie.inspect(60, { layers: 'none' }) // issues only (default lists the visible layers); text off-canvas / cut off / empty / overlapping text. Name your layers so paths are readable
182
182
  await movie.onionSkin({ from: 1, to: 3, count: 8, as: 'dataURL' }) // frames overlaid into ONE picture of a movement (later = stronger): path and easing at a glance
183
+ movie.pick(x, y) // what is under a canvas point at the frame on screen: { name, path, type, kind: 'flat' | 'card' | 'three', local?, three?: { object, point, distance } } or null (pickAll: the whole stack, top first; { only, ignore }); in a click handler: `movie.pick(...movie.canvasPoint(event))`; to ask about another frame: `await movie.snapshot(f)` first
183
184
  movie.review({ at: 'title@end' }) // what `pixi-effects check` looks at, as data: { frames, problems (text cut off, off-canvas, no size), review (text overlaps: look at them), fonts, audio, at }; leaves the movie as it was. `strict: true` makes every issue a problem
184
185
  movie.resolveAt('3.5, 50%, f120, title@end') // moments → [{ label, frame }]; a mistake says what could not be read
185
186
  movie.inspectFonts() // { missing: [{ layer, family }] (no font of the list is installed), failed: [web fonts whose file did not load] }
@@ -1386,6 +1386,29 @@ return [
1386
1386
 
1387
1387
  A moving, shadow-casting model is held to "a function of the time" by `check`: place it from `t` in `update` (as above) and let `threeGltf` load it (it draws a skinned mesh always: three culls it by a bounding sphere that does not follow it).
1388
1388
 
1389
+ ## Click a layer: what is under the pointer (`movie.pick`)
1390
+
1391
+ `movie.pick(x, y)` answers "what is drawn under this point, at the frame on screen" with no hit-testing code of yours: a flat layer by its own shape, a `threeD` card by its projected quad, a `three` layer by a ray (the hit says which object). `movie.canvasPoint(event)` turns a pointer event into canvas pixels, whatever size the canvas is shown at. Name the layers you want to react to.
1392
+
1393
+ ```js
1394
+ // @docs-only pick-click
1395
+ // in the page, after movie.init(...): a click on the fox, on the title, or on the wall behind them
1396
+ const canvas = document.getElementById('stage');
1397
+ canvas.addEventListener('click', (event) => {
1398
+ const hit = movie.pick(...movie.canvasPoint(event)); // the layer on top of that point, or null
1399
+ if (!hit) return;
1400
+ if (hit.kind === 'three' && hit.three.object === 'fox') console.log('the fox, at distance', hit.three.distance); // a three layer: the object the ray met
1401
+ else if (hit.name === 'title') movie.play(); // a flat layer: by its name
1402
+ });
1403
+ canvas.addEventListener('pointermove', (event) => {
1404
+ const hit = movie.pick(...movie.canvasPoint(event), { ignore: ['background'] }); // { only } / { ignore }: layer names or paths
1405
+ canvas.style.cursor = hit ? 'pointer' : 'default';
1406
+ });
1407
+ // a test, or an AI checking its own page, asks about a chosen frame: await movie.snapshot(90); movie.pick(640, 360)
1408
+ ```
1409
+
1410
+ `pick` reads the frame as the last draw left it (it takes no time and has no clock), so a paused movie answers for the frame it shows. A transparent corner of a picture still counts as the picture; hover effects and dragging are yours to build on `pick`.
1411
+
1389
1412
  ## Subtitles from an SRT file
1390
1413
 
1391
1414
  Subtitles are just text layers. The function reads a `.srt` (numbers, `00:00:01,000 --> 00:00:03,500`, the words) and returns one layer per cue: it appears and disappears over 0.12 s, sits 90 px above the bottom edge, wraps at 1000 px (about 80 % of a 1280 px picture) and has a black outline so it reads on any picture. Two cues that overlap in time are drawn on top of each other: split a long line into two lines in the `.srt` rather than relying on wrapping. Check the result with `pixi-effects check`; it reports text that is cut off by the edge.