agentvfx 0.0.0-stage → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +8 -0
- package/GEMINI.md +1 -0
- package/LICENSE +172 -0
- package/README.md +236 -2
- package/package.json +35 -4
- package/skills/agentvfx/LICENSE +172 -0
- package/skills/agentvfx/NOTICE +44 -0
- package/skills/agentvfx/SKILL.md +90 -0
- package/skills/agentvfx/engine/core/constants.mjs +84 -0
- package/skills/agentvfx/engine/core/flash-constants.mjs +23 -0
- package/skills/agentvfx/engine/core/flash.mjs +240 -0
- package/skills/agentvfx/engine/core/mark.mjs +28 -0
- package/skills/agentvfx/engine/core/palettes.mjs +36 -0
- package/skills/agentvfx/engine/core/schedule.mjs +85 -0
- package/skills/agentvfx/engine/core/templates.mjs +43 -0
- package/skills/agentvfx/engine/core/util.mjs +167 -0
- package/skills/agentvfx/engine/core/validate.mjs +334 -0
- package/skills/agentvfx/engine/node/analysis.mjs +172 -0
- package/skills/agentvfx/engine/node/audio.mjs +621 -0
- package/skills/agentvfx/engine/node/board.mjs +24 -0
- package/skills/agentvfx/engine/node/chrome.mjs +349 -0
- package/skills/agentvfx/engine/node/encode.mjs +110 -0
- package/skills/agentvfx/engine/node/eye.mjs +77 -0
- package/skills/agentvfx/engine/node/footage.mjs +129 -0
- package/skills/agentvfx/engine/node/frame-worker.mjs +39 -0
- package/skills/agentvfx/engine/node/host.mjs +31 -0
- package/skills/agentvfx/engine/node/job.mjs +181 -0
- package/skills/agentvfx/engine/node/png.mjs +112 -0
- package/skills/agentvfx/engine/node/render.mjs +161 -0
- package/skills/agentvfx/engine/node/stage-capture.mjs +187 -0
- package/skills/agentvfx/engine/node/stage-serve.mjs +72 -0
- package/skills/agentvfx/engine/node/stills.mjs +100 -0
- package/skills/agentvfx/engine/node/ws-server.mjs +132 -0
- package/skills/agentvfx/engine/web/gl.mjs +319 -0
- package/skills/agentvfx/engine/web/glsl-common.mjs +78 -0
- package/skills/agentvfx/engine/web/init.js +23 -0
- package/skills/agentvfx/engine/web/prelude.mjs +150 -0
- package/skills/agentvfx/engine/web/render.html +11 -0
- package/skills/agentvfx/engine/web/render.mjs +388 -0
- package/skills/agentvfx/engine/web/scale.mjs +15 -0
- package/skills/agentvfx/engine/web/text.mjs +158 -0
- package/skills/agentvfx/plates/terminalcore/README.md +61 -0
- package/skills/agentvfx/plates/terminalcore/__pycache__/crt.cpython-313.pyc +0 -0
- package/skills/agentvfx/plates/terminalcore/__pycache__/font.cpython-313.pyc +0 -0
- package/skills/agentvfx/plates/terminalcore/__pycache__/gallery.cpython-313.pyc +0 -0
- package/skills/agentvfx/plates/terminalcore/__pycache__/gallery_mats.cpython-313.pyc +0 -0
- package/skills/agentvfx/plates/terminalcore/__pycache__/gallery_room.cpython-313.pyc +0 -0
- package/skills/agentvfx/plates/terminalcore/__pycache__/materials.cpython-313.pyc +0 -0
- package/skills/agentvfx/plates/terminalcore/__pycache__/nodekit.cpython-313.pyc +0 -0
- package/skills/agentvfx/plates/terminalcore/__pycache__/room.cpython-313.pyc +0 -0
- package/skills/agentvfx/plates/terminalcore/__pycache__/shots.cpython-313.pyc +0 -0
- package/skills/agentvfx/plates/terminalcore/__pycache__/textures.cpython-313.pyc +0 -0
- package/skills/agentvfx/plates/terminalcore/__pycache__/wall.cpython-313.pyc +0 -0
- package/skills/agentvfx/plates/terminalcore/crt.py +143 -0
- package/skills/agentvfx/plates/terminalcore/font.py +80 -0
- package/skills/agentvfx/plates/terminalcore/gallery.py +61 -0
- package/skills/agentvfx/plates/terminalcore/gallery_mats.py +144 -0
- package/skills/agentvfx/plates/terminalcore/gallery_room.py +126 -0
- package/skills/agentvfx/plates/terminalcore/materials.py +170 -0
- package/skills/agentvfx/plates/terminalcore/nodekit.py +87 -0
- package/skills/agentvfx/plates/terminalcore/room.py +82 -0
- package/skills/agentvfx/plates/terminalcore/scene.py +219 -0
- package/skills/agentvfx/plates/terminalcore/shots.py +48 -0
- package/skills/agentvfx/plates/terminalcore/textures.py +79 -0
- package/skills/agentvfx/plates/terminalcore/wall.py +103 -0
- package/skills/agentvfx/references/plates.md +22 -0
- package/skills/agentvfx/references/template-format.md +149 -0
- package/skills/agentvfx/references/web.md +63 -0
- package/skills/agentvfx/runtime/agentvfx.js +708 -0
- package/skills/agentvfx/schemas/fx-score.schema.json +98 -0
- package/skills/agentvfx/scripts/export-web.mjs +155 -0
- package/skills/agentvfx/scripts/loop.mjs +129 -0
- package/skills/agentvfx/scripts/make-beat.mjs +133 -0
- package/skills/agentvfx/scripts/plate.mjs +82 -0
- package/skills/agentvfx/scripts/vfx.mjs +173 -0
- package/skills/agentvfx/templates/_test/feedback-counter/fx.json +11 -0
- package/skills/agentvfx/templates/_test/feedback-counter/main.frag +4 -0
- package/skills/agentvfx/templates/_test/feedback-counter/pass0.frag +4 -0
- package/skills/agentvfx/templates/_test/gradient/fx.json +23 -0
- package/skills/agentvfx/templates/_test/gradient/main.frag +5 -0
- package/skills/agentvfx/templates/_test/identity/fx.json +10 -0
- package/skills/agentvfx/templates/_test/identity/main.frag +4 -0
- package/skills/agentvfx/templates/_test/strobe/fx.json +14 -0
- package/skills/agentvfx/templates/_test/strobe/main.frag +6 -0
- package/skills/agentvfx/templates/_test/text-probe/fx.json +15 -0
- package/skills/agentvfx/templates/_test/text-probe/main.frag +6 -0
- package/skills/agentvfx/templates/brutal/NOTES.md +14 -0
- package/skills/agentvfx/templates/brutal/_src/boot-log/def.mjs +57 -0
- package/skills/agentvfx/templates/brutal/_src/boot-log/main.src.frag +129 -0
- package/skills/agentvfx/templates/brutal/_src/build.mjs +33 -0
- package/skills/agentvfx/templates/brutal/_src/halftone-field/def.mjs +72 -0
- package/skills/agentvfx/templates/brutal/_src/halftone-field/main.src.frag +94 -0
- package/skills/agentvfx/templates/brutal/_src/hud-deck/deck-left.src.glsl +100 -0
- package/skills/agentvfx/templates/brutal/_src/hud-deck/deck-right.src.glsl +61 -0
- package/skills/agentvfx/templates/brutal/_src/hud-deck/deck-tiles.src.glsl +153 -0
- package/skills/agentvfx/templates/brutal/_src/hud-deck/def.mjs +82 -0
- package/skills/agentvfx/templates/brutal/_src/hud-deck/main.src.frag +110 -0
- package/skills/agentvfx/templates/brutal/_src/hud-deck/pass0.src.frag +38 -0
- package/skills/agentvfx/templates/brutal/_src/shared/defs.mjs +28 -0
- package/skills/agentvfx/templates/brutal/_src/shared/icons.glsl +72 -0
- package/skills/agentvfx/templates/brutal/_src/shared/lib.glsl +115 -0
- package/skills/agentvfx/templates/brutal/_src/shared/screen.glsl +43 -0
- package/skills/agentvfx/templates/brutal/boot-log/demo-acid.json +1 -0
- package/skills/agentvfx/templates/brutal/boot-log/demo-phosphor.json +1 -0
- package/skills/agentvfx/templates/brutal/boot-log/demo-ultramarine.json +1 -0
- package/skills/agentvfx/templates/brutal/boot-log/fx.json +257 -0
- package/skills/agentvfx/templates/brutal/boot-log/main.frag +242 -0
- package/skills/agentvfx/templates/brutal/collage/_src/00-lib.glsl +73 -0
- package/skills/agentvfx/templates/brutal/collage/_src/10-spectrum-scope.glsl +73 -0
- package/skills/agentvfx/templates/brutal/collage/_src/20-meter-readout-cross.glsl +87 -0
- package/skills/agentvfx/templates/brutal/collage/_src/30-footage-fillers.glsl +92 -0
- package/skills/agentvfx/templates/brutal/collage/_src/40-editorial.glsl +232 -0
- package/skills/agentvfx/templates/brutal/collage/_src/50-typefx.glsl +163 -0
- package/skills/agentvfx/templates/brutal/collage/_src/60-scene-lib.glsl +104 -0
- package/skills/agentvfx/templates/brutal/collage/_src/61-scene-specimen.glsl +71 -0
- package/skills/agentvfx/templates/brutal/collage/_src/62-scene-wiring.glsl +96 -0
- package/skills/agentvfx/templates/brutal/collage/_src/63-scene-fieldcut.glsl +119 -0
- package/skills/agentvfx/templates/brutal/collage/_src/64-scene-pattern.glsl +64 -0
- package/skills/agentvfx/templates/brutal/collage/_src/641-scene-anatomy.glsl +49 -0
- package/skills/agentvfx/templates/brutal/collage/_src/642-scene-deck.glsl +78 -0
- package/skills/agentvfx/templates/brutal/collage/_src/643-scene-bootlog.glsl +60 -0
- package/skills/agentvfx/templates/brutal/collage/_src/644-scene-tunnel.glsl +48 -0
- package/skills/agentvfx/templates/brutal/collage/_src/645-scene-runner.glsl +42 -0
- package/skills/agentvfx/templates/brutal/collage/_src/646-scene-ascii.glsl +66 -0
- package/skills/agentvfx/templates/brutal/collage/_src/647-scene-cubewall.glsl +80 -0
- package/skills/agentvfx/templates/brutal/collage/_src/648-scene-vortex.glsl +46 -0
- package/skills/agentvfx/templates/brutal/collage/_src/649-scene-sticker.glsl +72 -0
- package/skills/agentvfx/templates/brutal/collage/_src/65-scene-main.glsl +1 -0
- package/skills/agentvfx/templates/brutal/collage/_src/650-scene-ribbon.glsl +55 -0
- package/skills/agentvfx/templates/brutal/collage/_src/651-scene-slab.glsl +38 -0
- package/skills/agentvfx/templates/brutal/collage/_src/652-scene-framedial.glsl +79 -0
- package/skills/agentvfx/templates/brutal/collage/_src/653-scene-tilt.glsl +40 -0
- package/skills/agentvfx/templates/brutal/collage/_src/654-scene-marquee.glsl +45 -0
- package/skills/agentvfx/templates/brutal/collage/_src/655-scene-lens.glsl +57 -0
- package/skills/agentvfx/templates/brutal/collage/_src/656-scene-liquid.glsl +35 -0
- package/skills/agentvfx/templates/brutal/collage/_src/657-scene-panelgrid.glsl +75 -0
- package/skills/agentvfx/templates/brutal/collage/_src/658-scene-mirror.glsl +49 -0
- package/skills/agentvfx/templates/brutal/collage/_src/66-scene-main.glsl +27 -0
- package/skills/agentvfx/templates/brutal/collage/_src/90-main.glsl +120 -0
- package/skills/agentvfx/templates/brutal/collage/_src/build.mjs +24 -0
- package/skills/agentvfx/templates/brutal/collage/_src/sync-presets.mjs +16 -0
- package/skills/agentvfx/templates/brutal/collage/demo-bone-lime.json +1 -0
- package/skills/agentvfx/templates/brutal/collage/demo-lime-sparse.json +1 -0
- package/skills/agentvfx/templates/brutal/collage/demo-orange-dense.json +1 -0
- package/skills/agentvfx/templates/brutal/collage/demo-ultra-slow.json +1 -0
- package/skills/agentvfx/templates/brutal/collage/fx.json +4882 -0
- package/skills/agentvfx/templates/brutal/collage/layout.mjs +97 -0
- package/skills/agentvfx/templates/brutal/collage/layouts.json +366 -0
- package/skills/agentvfx/templates/brutal/collage/main.frag +2367 -0
- package/skills/agentvfx/templates/brutal/collage/pass0.frag +265 -0
- package/skills/agentvfx/templates/brutal/halftone-field/demo-acid.json +1 -0
- package/skills/agentvfx/templates/brutal/halftone-field/demo-ascii.json +1 -0
- package/skills/agentvfx/templates/brutal/halftone-field/demo-dither.json +1 -0
- package/skills/agentvfx/templates/brutal/halftone-field/demo-orange.json +1 -0
- package/skills/agentvfx/templates/brutal/halftone-field/demo-phosphor.json +1 -0
- package/skills/agentvfx/templates/brutal/halftone-field/demo-ultramarine.json +1 -0
- package/skills/agentvfx/templates/brutal/halftone-field/fx.json +474 -0
- package/skills/agentvfx/templates/brutal/halftone-field/main.frag +248 -0
- package/skills/agentvfx/templates/brutal/hud-deck/demo-acid.json +1 -0
- package/skills/agentvfx/templates/brutal/hud-deck/demo-night.json +1 -0
- package/skills/agentvfx/templates/brutal/hud-deck/demo-octagon.json +1 -0
- package/skills/agentvfx/templates/brutal/hud-deck/demo-ultramarine.json +1 -0
- package/skills/agentvfx/templates/brutal/hud-deck/fx.json +601 -0
- package/skills/agentvfx/templates/brutal/hud-deck/main.frag +645 -0
- package/skills/agentvfx/templates/brutal/hud-deck/pass0.frag +38 -0
- package/skills/agentvfx/templates/brutal/lattice/demo-cobalt-fine.json +1 -0
- package/skills/agentvfx/templates/brutal/lattice/demo-ink-yellow.json +1 -0
- package/skills/agentvfx/templates/brutal/lattice/demo-vermilion.json +1 -0
- package/skills/agentvfx/templates/brutal/lattice/demo-violet-slow.json +1 -0
- package/skills/agentvfx/templates/brutal/lattice/fx.json +130 -0
- package/skills/agentvfx/templates/brutal/lattice/main.frag +175 -0
- package/skills/agentvfx/templates/brutal/lattice/pass0.frag +29 -0
- package/skills/agentvfx/templates/glitch/block-glitch/demo-mosaic.json +1 -0
- package/skills/agentvfx/templates/glitch/block-glitch/demo-onset.json +1 -0
- package/skills/agentvfx/templates/glitch/block-glitch/demo-static.json +1 -0
- package/skills/agentvfx/templates/glitch/block-glitch/demo-tear.json +1 -0
- package/skills/agentvfx/templates/glitch/block-glitch/fx.json +54 -0
- package/skills/agentvfx/templates/glitch/block-glitch/main.frag +132 -0
- package/skills/agentvfx/templates/glitch/block-glitch/pass0.frag +12 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/NOTES.md +13 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/build-passes.mjs +162 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/demo-chunk.json +1 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/demo-hue.json +1 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/demo-kick.json +1 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/demo-streak.json +1 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/demo-vertical.json +1 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/fx.json +60 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/main.frag +83 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/pass0.frag +64 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/pass1.frag +66 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/pass2.frag +66 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/pass3.frag +66 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/pass4.frag +66 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/pass5.frag +66 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/pass6.frag +66 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/pass7.frag +66 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/pass8.frag +66 -0
- package/skills/agentvfx/templates/glitch/rgb-split/demo-diagonal-stutter.json +1 -0
- package/skills/agentvfx/templates/glitch/rgb-split/demo-hard.json +1 -0
- package/skills/agentvfx/templates/glitch/rgb-split/demo-kick.json +1 -0
- package/skills/agentvfx/templates/glitch/rgb-split/demo-radial.json +1 -0
- package/skills/agentvfx/templates/glitch/rgb-split/fx.json +46 -0
- package/skills/agentvfx/templates/glitch/rgb-split/main.frag +76 -0
- package/skills/agentvfx/templates/glitch/vhs/demo-clean.json +1 -0
- package/skills/agentvfx/templates/glitch/vhs/demo-crash.json +1 -0
- package/skills/agentvfx/templates/glitch/vhs/demo-tape.json +1 -0
- package/skills/agentvfx/templates/glitch/vhs/demo-worn.json +1 -0
- package/skills/agentvfx/templates/glitch/vhs/fx.json +46 -0
- package/skills/agentvfx/templates/glitch/vhs/main.frag +96 -0
- package/skills/agentvfx/templates/impact/impact-1bit/demo-onebit-bayer.json +1 -0
- package/skills/agentvfx/templates/impact/impact-1bit/fx.json +45 -0
- package/skills/agentvfx/templates/impact/impact-1bit/main.frag +64 -0
- package/skills/agentvfx/templates/impact/impact-invert/demo-invert-snap.json +1 -0
- package/skills/agentvfx/templates/impact/impact-invert/fx.json +37 -0
- package/skills/agentvfx/templates/impact/impact-invert/main.frag +44 -0
- package/skills/agentvfx/templates/impact/punch-shake/demo-punch-hard.json +1 -0
- package/skills/agentvfx/templates/impact/punch-shake/fx.json +36 -0
- package/skills/agentvfx/templates/impact/punch-shake/main.frag +62 -0
- package/skills/agentvfx/templates/impact/rgb-hit/demo-rgb-slam.json +1 -0
- package/skills/agentvfx/templates/impact/rgb-hit/fx.json +39 -0
- package/skills/agentvfx/templates/impact/rgb-hit/main.frag +62 -0
- package/skills/agentvfx/templates/impact/signal-cut/demo-lime-hold.json +1 -0
- package/skills/agentvfx/templates/impact/signal-cut/demo-lime.json +1 -0
- package/skills/agentvfx/templates/impact/signal-cut/demo-orange.json +1 -0
- package/skills/agentvfx/templates/impact/signal-cut/demo-ultramarine.json +1 -0
- package/skills/agentvfx/templates/impact/signal-cut/fx.json +83 -0
- package/skills/agentvfx/templates/impact/signal-cut/main.frag +101 -0
- package/skills/agentvfx/templates/impact/signal-cut/pass0.frag +68 -0
- package/skills/agentvfx/templates/impact/speedline-burst/demo-speed-white.json +1 -0
- package/skills/agentvfx/templates/impact/speedline-burst/fx.json +44 -0
- package/skills/agentvfx/templates/impact/speedline-burst/main.frag +68 -0
- package/skills/agentvfx/templates/impact/strobe-burst/demo-strobe-white-16.json +1 -0
- package/skills/agentvfx/templates/impact/strobe-burst/fx.json +42 -0
- package/skills/agentvfx/templates/impact/strobe-burst/main.frag +43 -0
- package/skills/agentvfx/templates/light/anamorphic-streak/demo-anamorphic-cinema.json +10 -0
- package/skills/agentvfx/templates/light/anamorphic-streak/demo-data.json +10 -0
- package/skills/agentvfx/templates/light/anamorphic-streak/fx.json +47 -0
- package/skills/agentvfx/templates/light/anamorphic-streak/main.frag +45 -0
- package/skills/agentvfx/templates/light/anamorphic-streak/pass0.frag +22 -0
- package/skills/agentvfx/templates/light/anamorphic-streak/pass1.frag +16 -0
- package/skills/agentvfx/templates/light/anamorphic-streak/pass2.frag +16 -0
- package/skills/agentvfx/templates/light/anamorphic-streak/pass3.frag +16 -0
- package/skills/agentvfx/templates/light/bloom-glow/demo-clip01-low.json +11 -0
- package/skills/agentvfx/templates/light/bloom-glow/demo-neon-night.json +10 -0
- package/skills/agentvfx/templates/light/bloom-glow/demo-phosphor.json +11 -0
- package/skills/agentvfx/templates/light/bloom-glow/fx.json +53 -0
- package/skills/agentvfx/templates/light/bloom-glow/main.frag +85 -0
- package/skills/agentvfx/templates/light/bloom-glow/pass0.frag +21 -0
- package/skills/agentvfx/templates/light/bloom-glow/pass1.frag +50 -0
- package/skills/agentvfx/templates/light/bloom-glow/pass2.frag +44 -0
- package/skills/agentvfx/templates/light/bloom-glow/pass3.frag +32 -0
- package/skills/agentvfx/templates/light/bloom-glow/pass4.frag +48 -0
- package/skills/agentvfx/templates/light/bloom-glow/pass5.frag +46 -0
- package/skills/agentvfx/templates/light/god-rays/demo-golden-hour.json +10 -0
- package/skills/agentvfx/templates/light/god-rays/demo-point-lamp.json +10 -0
- package/skills/agentvfx/templates/light/god-rays/fx.json +39 -0
- package/skills/agentvfx/templates/light/god-rays/main.frag +54 -0
- package/skills/agentvfx/templates/light/lens-flare/demo-clip01-bar.json +11 -0
- package/skills/agentvfx/templates/light/lens-flare/demo-eye-bar.json +10 -0
- package/skills/agentvfx/templates/light/lens-flare/demo-sun-ghosts.json +10 -0
- package/skills/agentvfx/templates/light/lens-flare/fx.json +49 -0
- package/skills/agentvfx/templates/light/lens-flare/main.frag +86 -0
- package/skills/agentvfx/templates/light/lens-flare/pass0.frag +24 -0
- package/skills/agentvfx/templates/light/light-leak/demo-slit.json +10 -0
- package/skills/agentvfx/templates/light/light-leak/demo-vintage-burn.json +10 -0
- package/skills/agentvfx/templates/light/light-leak/fx.json +40 -0
- package/skills/agentvfx/templates/light/light-leak/main.frag +46 -0
- package/skills/agentvfx/templates/light/light-stage/fx.json +29 -0
- package/skills/agentvfx/templates/light/light-stage/main.frag +56 -0
- package/skills/agentvfx/templates/light/light-sweep/demo-hard-bar.json +12 -0
- package/skills/agentvfx/templates/light/light-sweep/demo-logo-sweep.json +10 -0
- package/skills/agentvfx/templates/light/light-sweep/demo-onset.json +11 -0
- package/skills/agentvfx/templates/light/light-sweep/fx.json +45 -0
- package/skills/agentvfx/templates/light/light-sweep/main.frag +29 -0
- package/skills/agentvfx/templates/light/light-sweep/pass0.frag +17 -0
- package/skills/agentvfx/templates/light/light-sweep/pass1.frag +15 -0
- package/skills/agentvfx/templates/light/neon-saber/demo-hairline.json +10 -0
- package/skills/agentvfx/templates/light/neon-saber/demo-saber-laser.json +10 -0
- package/skills/agentvfx/templates/light/neon-saber/fx.json +48 -0
- package/skills/agentvfx/templates/light/neon-saber/main.frag +27 -0
- package/skills/agentvfx/templates/light/neon-saber/pass0.frag +46 -0
- package/skills/agentvfx/templates/light/neon-saber/pass1.frag +15 -0
- package/skills/agentvfx/templates/psychedelic/echo-flow/demo-trail.json +1 -0
- package/skills/agentvfx/templates/psychedelic/echo-flow/fx.json +38 -0
- package/skills/agentvfx/templates/psychedelic/echo-flow/main.frag +19 -0
- package/skills/agentvfx/templates/psychedelic/echo-flow/pass0.frag +16 -0
- package/skills/agentvfx/templates/psychedelic/echo-flow/pass1.frag +20 -0
- package/skills/agentvfx/templates/psychedelic/echo-flow/pass2.frag +11 -0
- package/skills/agentvfx/templates/psychedelic/echo-flow/pass3.frag +4 -0
- package/skills/agentvfx/templates/psychedelic/hologram-scan/demo-cyan.json +1 -0
- package/skills/agentvfx/templates/psychedelic/hologram-scan/fx.json +36 -0
- package/skills/agentvfx/templates/psychedelic/hologram-scan/main.frag +30 -0
- package/skills/agentvfx/templates/psychedelic/kaleido-fold/demo-six.json +1 -0
- package/skills/agentvfx/templates/psychedelic/kaleido-fold/fx.json +37 -0
- package/skills/agentvfx/templates/psychedelic/kaleido-fold/main.frag +10 -0
- package/skills/agentvfx/templates/psychedelic/kaleido-fold/pass0.frag +34 -0
- package/skills/agentvfx/templates/psychedelic/mosh-melt/demo-classic.json +1 -0
- package/skills/agentvfx/templates/psychedelic/mosh-melt/fx.json +38 -0
- package/skills/agentvfx/templates/psychedelic/mosh-melt/main.frag +20 -0
- package/skills/agentvfx/templates/psychedelic/mosh-melt/pass0.frag +22 -0
- package/skills/agentvfx/templates/psychedelic/sacred/NOTES.md +13 -0
- package/skills/agentvfx/templates/psychedelic/sacred/demo-classic.json +1 -0
- package/skills/agentvfx/templates/psychedelic/sacred/demo-halo.json +1 -0
- package/skills/agentvfx/templates/psychedelic/sacred/demo-slow-tide.json +1 -0
- package/skills/agentvfx/templates/psychedelic/sacred/demo-thermal.json +1 -0
- package/skills/agentvfx/templates/psychedelic/sacred/fx.json +263 -0
- package/skills/agentvfx/templates/psychedelic/sacred/main.frag +109 -0
- package/skills/agentvfx/templates/psychedelic/sacred/pass0.frag +25 -0
- package/skills/agentvfx/templates/psychedelic/sacred/pass1.frag +23 -0
- package/skills/agentvfx/templates/psychedelic/tidal-bands/demo-classic.json +1 -0
- package/skills/agentvfx/templates/psychedelic/tidal-bands/fx.json +37 -0
- package/skills/agentvfx/templates/psychedelic/tidal-bands/main.frag +54 -0
- package/skills/agentvfx/templates/scope/_chrome.glsl +242 -0
- package/skills/agentvfx/templates/scope/goniometer/demo-boot-green.json +1 -0
- package/skills/agentvfx/templates/scope/goniometer/demo-field-lime.json +1 -0
- package/skills/agentvfx/templates/scope/goniometer/demo-field-ultramarine.json +1 -0
- package/skills/agentvfx/templates/scope/goniometer/demo-glow-phosphor.json +1 -0
- package/skills/agentvfx/templates/scope/goniometer/demo-hud-black.json +1 -0
- package/skills/agentvfx/templates/scope/goniometer/fx.json +635 -0
- package/skills/agentvfx/templates/scope/goniometer/main.frag +33 -0
- package/skills/agentvfx/templates/scope/goniometer/pass0.frag +58 -0
- package/skills/agentvfx/templates/scope/goniometer/pass1.frag +43 -0
- package/skills/agentvfx/templates/scope/goniometer/pass2.frag +12 -0
- package/skills/agentvfx/templates/scope/goniometer/pass3.frag +12 -0
- package/skills/agentvfx/templates/scope/goniometer/pass4.frag +12 -0
- package/skills/agentvfx/templates/scope/goniometer/pass5.frag +12 -0
- package/skills/agentvfx/templates/scope/goniometer/pass6.frag +251 -0
- package/skills/agentvfx/templates/scope/scope-polar/demo-boot-green.json +1 -0
- package/skills/agentvfx/templates/scope/scope-polar/demo-field-lime.json +1 -0
- package/skills/agentvfx/templates/scope/scope-polar/demo-field-ultramarine.json +1 -0
- package/skills/agentvfx/templates/scope/scope-polar/demo-glow-phosphor.json +1 -0
- package/skills/agentvfx/templates/scope/scope-polar/demo-hud-black.json +1 -0
- package/skills/agentvfx/templates/scope/scope-polar/fx.json +686 -0
- package/skills/agentvfx/templates/scope/scope-polar/main.frag +39 -0
- package/skills/agentvfx/templates/scope/scope-polar/pass0.frag +84 -0
- package/skills/agentvfx/templates/scope/scope-polar/pass1.frag +49 -0
- package/skills/agentvfx/templates/scope/scope-polar/pass2.frag +12 -0
- package/skills/agentvfx/templates/scope/scope-polar/pass3.frag +12 -0
- package/skills/agentvfx/templates/scope/scope-polar/pass4.frag +12 -0
- package/skills/agentvfx/templates/scope/scope-polar/pass5.frag +12 -0
- package/skills/agentvfx/templates/scope/scope-polar/pass6.frag +251 -0
- package/skills/agentvfx/templates/scope/scope-triggered/demo-boot-green.json +1 -0
- package/skills/agentvfx/templates/scope/scope-triggered/demo-field-lime.json +1 -0
- package/skills/agentvfx/templates/scope/scope-triggered/demo-field-ultramarine.json +1 -0
- package/skills/agentvfx/templates/scope/scope-triggered/demo-glow-phosphor.json +1 -0
- package/skills/agentvfx/templates/scope/scope-triggered/demo-hud-black.json +1 -0
- package/skills/agentvfx/templates/scope/scope-triggered/fx.json +712 -0
- package/skills/agentvfx/templates/scope/scope-triggered/main.frag +36 -0
- package/skills/agentvfx/templates/scope/scope-triggered/pass0.frag +78 -0
- package/skills/agentvfx/templates/scope/scope-triggered/pass1.frag +50 -0
- package/skills/agentvfx/templates/scope/scope-triggered/pass2.frag +12 -0
- package/skills/agentvfx/templates/scope/scope-triggered/pass3.frag +12 -0
- package/skills/agentvfx/templates/scope/scope-triggered/pass4.frag +12 -0
- package/skills/agentvfx/templates/scope/scope-triggered/pass5.frag +12 -0
- package/skills/agentvfx/templates/scope/scope-triggered/pass6.frag +251 -0
- package/skills/agentvfx/templates/scope/spectrogram-scroll/demo-boot-green.json +1 -0
- package/skills/agentvfx/templates/scope/spectrogram-scroll/demo-field-lime.json +1 -0
- package/skills/agentvfx/templates/scope/spectrogram-scroll/demo-field-ultramarine.json +1 -0
- package/skills/agentvfx/templates/scope/spectrogram-scroll/demo-glow-phosphor.json +1 -0
- package/skills/agentvfx/templates/scope/spectrogram-scroll/demo-hud-black.json +1 -0
- package/skills/agentvfx/templates/scope/spectrogram-scroll/fx.json +595 -0
- package/skills/agentvfx/templates/scope/spectrogram-scroll/main.frag +83 -0
- package/skills/agentvfx/templates/scope/spectrogram-scroll/pass0.frag +52 -0
- package/skills/agentvfx/templates/scope/spectrogram-scroll/pass1.frag +251 -0
- package/skills/agentvfx/templates/scope/xy-phosphor/demo-boot-green.json +1 -0
- package/skills/agentvfx/templates/scope/xy-phosphor/demo-field-lime.json +1 -0
- package/skills/agentvfx/templates/scope/xy-phosphor/demo-field-ultramarine.json +1 -0
- package/skills/agentvfx/templates/scope/xy-phosphor/demo-glow-phosphor.json +1 -0
- package/skills/agentvfx/templates/scope/xy-phosphor/demo-hud-black.json +1 -0
- package/skills/agentvfx/templates/scope/xy-phosphor/fx.json +642 -0
- package/skills/agentvfx/templates/scope/xy-phosphor/main.frag +33 -0
- package/skills/agentvfx/templates/scope/xy-phosphor/pass0.frag +56 -0
- package/skills/agentvfx/templates/scope/xy-phosphor/pass1.frag +44 -0
- package/skills/agentvfx/templates/scope/xy-phosphor/pass2.frag +12 -0
- package/skills/agentvfx/templates/scope/xy-phosphor/pass3.frag +12 -0
- package/skills/agentvfx/templates/scope/xy-phosphor/pass4.frag +12 -0
- package/skills/agentvfx/templates/scope/xy-phosphor/pass5.frag +12 -0
- package/skills/agentvfx/templates/scope/xy-phosphor/pass6.frag +251 -0
- package/skills/agentvfx/templates/spectrum/_src/bars-linear/fx.src.json +61 -0
- package/skills/agentvfx/templates/spectrum/_src/bars-linear/main.src.frag +112 -0
- package/skills/agentvfx/templates/spectrum/_src/bars-linear/pass0.src.frag +2 -0
- package/skills/agentvfx/templates/spectrum/_src/bars-mirror/fx.src.json +51 -0
- package/skills/agentvfx/templates/spectrum/_src/bars-mirror/main.src.frag +72 -0
- package/skills/agentvfx/templates/spectrum/_src/bars-mirror/pass0.src.frag +2 -0
- package/skills/agentvfx/templates/spectrum/_src/bass-circle/fx.src.json +56 -0
- package/skills/agentvfx/templates/spectrum/_src/bass-circle/main.src.frag +136 -0
- package/skills/agentvfx/templates/spectrum/_src/bass-circle/pass0.src.frag +2 -0
- package/skills/agentvfx/templates/spectrum/_src/build.mjs +68 -0
- package/skills/agentvfx/templates/spectrum/_src/label-bars/fx.src.json +54 -0
- package/skills/agentvfx/templates/spectrum/_src/label-bars/main.src.frag +102 -0
- package/skills/agentvfx/templates/spectrum/_src/label-bars/pass0.src.frag +2 -0
- package/skills/agentvfx/templates/spectrum/_src/shared/bars-fn.glsl +64 -0
- package/skills/agentvfx/templates/spectrum/_src/shared/bars-pass.glsl +22 -0
- package/skills/agentvfx/templates/spectrum/_src/shared/clock.glsl +7 -0
- package/skills/agentvfx/templates/spectrum/_src/shared/hud.glsl +50 -0
- package/skills/agentvfx/templates/spectrum/_src/shared/stage.glsl +74 -0
- package/skills/agentvfx/templates/spectrum/_src/spectrum-particles/fx.src.json +58 -0
- package/skills/agentvfx/templates/spectrum/_src/spectrum-particles/main.src.frag +119 -0
- package/skills/agentvfx/templates/spectrum/_src/spectrum-particles/pass0.src.frag +33 -0
- package/skills/agentvfx/templates/spectrum/_src/spectrum-radial/fx.src.json +56 -0
- package/skills/agentvfx/templates/spectrum/_src/spectrum-radial/main.src.frag +95 -0
- package/skills/agentvfx/templates/spectrum/_src/spectrum-radial/pass0.src.frag +2 -0
- package/skills/agentvfx/templates/spectrum/_src/waveform-line/fx.src.json +60 -0
- package/skills/agentvfx/templates/spectrum/_src/waveform-line/main.src.frag +98 -0
- package/skills/agentvfx/templates/spectrum/_src/waveform-line/pass0.src.frag +43 -0
- package/skills/agentvfx/templates/spectrum/bars-linear/demo-graph-acid.json +1 -0
- package/skills/agentvfx/templates/spectrum/bars-linear/demo-graph-black.json +1 -0
- package/skills/agentvfx/templates/spectrum/bars-linear/fx.json +632 -0
- package/skills/agentvfx/templates/spectrum/bars-linear/main.frag +233 -0
- package/skills/agentvfx/templates/spectrum/bars-linear/pass0.frag +91 -0
- package/skills/agentvfx/templates/spectrum/bars-mirror/demo-field-acid.json +1 -0
- package/skills/agentvfx/templates/spectrum/bars-mirror/demo-field-ultramarine.json +1 -0
- package/skills/agentvfx/templates/spectrum/bars-mirror/fx.json +539 -0
- package/skills/agentvfx/templates/spectrum/bars-mirror/main.frag +193 -0
- package/skills/agentvfx/templates/spectrum/bars-mirror/pass0.frag +91 -0
- package/skills/agentvfx/templates/spectrum/bass-circle/demo-bracket-black.json +1 -0
- package/skills/agentvfx/templates/spectrum/bass-circle/demo-bracket-ultramarine.json +1 -0
- package/skills/agentvfx/templates/spectrum/bass-circle/fx.json +552 -0
- package/skills/agentvfx/templates/spectrum/bass-circle/main.frag +258 -0
- package/skills/agentvfx/templates/spectrum/bass-circle/pass0.frag +91 -0
- package/skills/agentvfx/templates/spectrum/label-bars/demo-deck-black.json +1 -0
- package/skills/agentvfx/templates/spectrum/label-bars/demo-deck-ultramarine.json +1 -0
- package/skills/agentvfx/templates/spectrum/label-bars/fx.json +552 -0
- package/skills/agentvfx/templates/spectrum/label-bars/main.frag +223 -0
- package/skills/agentvfx/templates/spectrum/label-bars/pass0.frag +91 -0
- package/skills/agentvfx/templates/spectrum/spectrum-particles/demo-cloud-black.json +1 -0
- package/skills/agentvfx/templates/spectrum/spectrum-particles/demo-cloud-ultramarine.json +1 -0
- package/skills/agentvfx/templates/spectrum/spectrum-particles/fx.json +584 -0
- package/skills/agentvfx/templates/spectrum/spectrum-particles/main.frag +240 -0
- package/skills/agentvfx/templates/spectrum/spectrum-particles/pass0.frag +101 -0
- package/skills/agentvfx/templates/spectrum/spectrum-radial/demo-starburst-black.json +1 -0
- package/skills/agentvfx/templates/spectrum/spectrum-radial/demo-starburst-ultramarine.json +1 -0
- package/skills/agentvfx/templates/spectrum/spectrum-radial/fx.json +566 -0
- package/skills/agentvfx/templates/spectrum/spectrum-radial/main.frag +217 -0
- package/skills/agentvfx/templates/spectrum/spectrum-radial/pass0.frag +91 -0
- package/skills/agentvfx/templates/spectrum/waveform-line/demo-strip-acid.json +1 -0
- package/skills/agentvfx/templates/spectrum/waveform-line/demo-strip-black.json +1 -0
- package/skills/agentvfx/templates/spectrum/waveform-line/fx.json +481 -0
- package/skills/agentvfx/templates/spectrum/waveform-line/main.frag +219 -0
- package/skills/agentvfx/templates/spectrum/waveform-line/pass0.frag +48 -0
- package/skills/agentvfx/templates/spectrum/waveform-line/pass1.frag +86 -0
- package/skills/agentvfx/test/_render_light.mjs +38 -0
- package/skills/agentvfx/test/audio-stereo.test.mjs +45 -0
- package/skills/agentvfx/test/audio.test.mjs +257 -0
- package/skills/agentvfx/test/brutal.test.mjs +190 -0
- package/skills/agentvfx/test/concept-collage-layout.test.mjs +236 -0
- package/skills/agentvfx/test/concept-collage-scenes.test.mjs +305 -0
- package/skills/agentvfx/test/concept-collage-typefx.test.mjs +153 -0
- package/skills/agentvfx/test/concept-collage.test.mjs +84 -0
- package/skills/agentvfx/test/concept-lattice.test.mjs +133 -0
- package/skills/agentvfx/test/concept-signal-cut.test.mjs +172 -0
- package/skills/agentvfx/test/credit-overlay.test.mjs +58 -0
- package/skills/agentvfx/test/credit.test.mjs +42 -0
- package/skills/agentvfx/test/doctor.test.mjs +31 -0
- package/skills/agentvfx/test/encode.test.mjs +22 -0
- package/skills/agentvfx/test/fixtures/r7-collage-LAYOUTS.json +5780 -0
- package/skills/agentvfx/test/fixtures/score-bad-duration.json +7 -0
- package/skills/agentvfx/test/fixtures/score-bad-safety.json +8 -0
- package/skills/agentvfx/test/fixtures/score-identity-footage.json +8 -0
- package/skills/agentvfx/test/fixtures/score-missing-template.json +7 -0
- package/skills/agentvfx/test/fixtures/score-ok.json +8 -0
- package/skills/agentvfx/test/fixtures/score-strobe-12hz.json +8 -0
- package/skills/agentvfx/test/fixtures/score-text-probe.json +1 -0
- package/skills/agentvfx/test/flash-audit.test.mjs +150 -0
- package/skills/agentvfx/test/flash.test.mjs +83 -0
- package/skills/agentvfx/test/footage.test.mjs +88 -0
- package/skills/agentvfx/test/glitch.test.mjs +272 -0
- package/skills/agentvfx/test/impact.test.mjs +231 -0
- package/skills/agentvfx/test/imports.test.mjs +39 -0
- package/skills/agentvfx/test/light.test.mjs +200 -0
- package/skills/agentvfx/test/loop.test.mjs +80 -0
- package/skills/agentvfx/test/psychedelic.test.mjs +99 -0
- package/skills/agentvfx/test/render.test.mjs +73 -0
- package/skills/agentvfx/test/sacred.test.mjs +175 -0
- package/skills/agentvfx/test/schema.test.mjs +103 -0
- package/skills/agentvfx/test/scope.test.mjs +306 -0
- package/skills/agentvfx/test/spectrum.test.mjs +165 -0
- package/skills/agentvfx/test/text.test.mjs +142 -0
- package/skills/agentvfx/test/web.test.mjs +397 -0
- package/skills/agentvfx/test-media/SOURCES.md +39 -0
- package/skills/agentvfx/test-media/beat-132.mp3 +0 -0
- package/skills/agentvfx/test-media/clip-01.mp4 +0 -0
- package/skills/agentvfx/test-media/clip-02.mp4 +0 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// pixel-sort (pass5 run5: run lengths to the left (r) and right (g), capped at 32). Idea: pixel sorting as in ASDFPixelSort by Kim Asendorf (concept only; code written fresh).
|
|
2
|
+
// Spans of cells whose luma lies in a threshold window are sorted along an axis. Span extents come from
|
|
3
|
+
// log2 run-length doubling (pass1..pass8); the sort itself ranks 32 strided samples of the span in the
|
|
4
|
+
// last pass (exact when a span has <= 32 cells, a quantile approximation above that).
|
|
5
|
+
uint pcg(uint v) {
|
|
6
|
+
uint s = v * 747796405u + 2891336453u;
|
|
7
|
+
uint w = ((s >> ((s >> 28u) + 4u)) ^ s) * 277803737u;
|
|
8
|
+
return (w >> 22u) ^ w;
|
|
9
|
+
}
|
|
10
|
+
float h1(uint a) { return float(pcg(a)) / 4294967295.0; }
|
|
11
|
+
float h2(uint a, uint b) { return h1(a * 2654435761u + pcg(b + 1013904223u)); }
|
|
12
|
+
|
|
13
|
+
// SEED is the score seed / 2^32, so small integer seeds are tiny floats; recover the integer.
|
|
14
|
+
uint seedU() { return uint(min(SEED * 4294967296.0 + 0.5, 4294967040.0)); }
|
|
15
|
+
|
|
16
|
+
// The sort works on cells of cellPx x cellPx pixels (1 cell = 1 "pixel" of the sort).
|
|
17
|
+
// Reading order: left to right for the horizontal axis, top to bottom for the vertical one.
|
|
18
|
+
float cellPx() { return max(1.0, floor(cellSize * RENDERSIZE.y / 1080.0 + 0.5)); }
|
|
19
|
+
vec2 axisDir() { return sortAxis == 0 ? vec2(1.0, 0.0) : vec2(0.0, -1.0); }
|
|
20
|
+
vec2 cellDims() { return ceil(RENDERSIZE / cellPx()); }
|
|
21
|
+
bool inCells(vec2 c) { vec2 d = cellDims(); return c.x >= 0.0 && c.y >= 0.0 && c.x < d.x && c.y < d.y; }
|
|
22
|
+
ivec2 cellTexel(vec2 c) { return ivec2(min(c * cellPx(), RENDERSIZE - 1.0)); }
|
|
23
|
+
float acrossOf(vec2 c) { return sortAxis == 0 ? c.y : c.x; }
|
|
24
|
+
float alongOf(vec2 c) { return sortAxis == 0 ? c.x : cellDims().y - 1.0 - c.y; }
|
|
25
|
+
|
|
26
|
+
// Span mask: a cell takes part when its row is gated in and its perceptual luma lies in [lo, hi].
|
|
27
|
+
bool maskOf(vec2 c) {
|
|
28
|
+
if (!inCells(c)) return false;
|
|
29
|
+
uint across = uint(acrossOf(c));
|
|
30
|
+
uint st = uint(floor(TIME * stutterHz));
|
|
31
|
+
uint sd = seedU();
|
|
32
|
+
float kick = clamp(audioKick, 0.0, 2.0);
|
|
33
|
+
if (h2(across + 7u, st * 977u + sd) > clamp(rowsFrac + 0.4 * kick, 0.0, 1.0)) return false;
|
|
34
|
+
float sw = sweep * sin(6.2832 * (TIME * sweepRate + h1(sd + 17u)));
|
|
35
|
+
float lo = threshLo + sw - 0.25 * kick + (h2(across, st + sd + 3u) - 0.5) * rowVar;
|
|
36
|
+
float hi = threshHi + sw + 0.2 * kick + (h2(across, st + sd + 5u) - 0.5) * rowVar;
|
|
37
|
+
float l = linearToSrgb(vec3(luma(texelFetch(keyBuf, cellTexel(c), 0).rgb))).r;
|
|
38
|
+
return l >= lo && l <= hi;
|
|
39
|
+
}
|
|
40
|
+
// Spans are cut at multiples of 256 cells; the cut grid is shifted per row so cuts do not line up.
|
|
41
|
+
float cutShift(vec2 c) { return floor(h2(uint(acrossOf(c)), seedU() + 99u) * 256.0) * cutJitter; }
|
|
42
|
+
|
|
43
|
+
void main() {
|
|
44
|
+
float cp = cellPx();
|
|
45
|
+
vec2 c = floor(vUv * RENDERSIZE / cp);
|
|
46
|
+
if (!maskOf(c)) { fragColor = vec4(0.0); return; }
|
|
47
|
+
vec2 dv = axisDir();
|
|
48
|
+
float posIn = mod(alongOf(c) + cutShift(c), 256.0);
|
|
49
|
+
float capL = posIn + 1.0;
|
|
50
|
+
float capR = 256.0 - posIn;
|
|
51
|
+
float kk = 16.0;
|
|
52
|
+
vec2 own = texelFetch(run4, cellTexel(c), 0).rg;
|
|
53
|
+
float L = own.x;
|
|
54
|
+
float R = own.y;
|
|
55
|
+
if (L >= kk) {
|
|
56
|
+
vec2 cn = c - dv * kk;
|
|
57
|
+
float ln = inCells(cn) ? texelFetch(run4, cellTexel(cn), 0).r : 0.0;
|
|
58
|
+
L = min(min(2.0 * kk, kk + ln), capL);
|
|
59
|
+
}
|
|
60
|
+
if (R >= kk) {
|
|
61
|
+
vec2 cn = c + dv * kk;
|
|
62
|
+
float rn = inCells(cn) ? texelFetch(run4, cellTexel(cn), 0).g : 0.0;
|
|
63
|
+
R = min(min(2.0 * kk, kk + rn), capR);
|
|
64
|
+
}
|
|
65
|
+
fragColor = vec4(L, R, 0.0, 1.0);
|
|
66
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// pixel-sort (pass6 run6: run lengths to the left (r) and right (g), capped at 64). Idea: pixel sorting as in ASDFPixelSort by Kim Asendorf (concept only; code written fresh).
|
|
2
|
+
// Spans of cells whose luma lies in a threshold window are sorted along an axis. Span extents come from
|
|
3
|
+
// log2 run-length doubling (pass1..pass8); the sort itself ranks 32 strided samples of the span in the
|
|
4
|
+
// last pass (exact when a span has <= 32 cells, a quantile approximation above that).
|
|
5
|
+
uint pcg(uint v) {
|
|
6
|
+
uint s = v * 747796405u + 2891336453u;
|
|
7
|
+
uint w = ((s >> ((s >> 28u) + 4u)) ^ s) * 277803737u;
|
|
8
|
+
return (w >> 22u) ^ w;
|
|
9
|
+
}
|
|
10
|
+
float h1(uint a) { return float(pcg(a)) / 4294967295.0; }
|
|
11
|
+
float h2(uint a, uint b) { return h1(a * 2654435761u + pcg(b + 1013904223u)); }
|
|
12
|
+
|
|
13
|
+
// SEED is the score seed / 2^32, so small integer seeds are tiny floats; recover the integer.
|
|
14
|
+
uint seedU() { return uint(min(SEED * 4294967296.0 + 0.5, 4294967040.0)); }
|
|
15
|
+
|
|
16
|
+
// The sort works on cells of cellPx x cellPx pixels (1 cell = 1 "pixel" of the sort).
|
|
17
|
+
// Reading order: left to right for the horizontal axis, top to bottom for the vertical one.
|
|
18
|
+
float cellPx() { return max(1.0, floor(cellSize * RENDERSIZE.y / 1080.0 + 0.5)); }
|
|
19
|
+
vec2 axisDir() { return sortAxis == 0 ? vec2(1.0, 0.0) : vec2(0.0, -1.0); }
|
|
20
|
+
vec2 cellDims() { return ceil(RENDERSIZE / cellPx()); }
|
|
21
|
+
bool inCells(vec2 c) { vec2 d = cellDims(); return c.x >= 0.0 && c.y >= 0.0 && c.x < d.x && c.y < d.y; }
|
|
22
|
+
ivec2 cellTexel(vec2 c) { return ivec2(min(c * cellPx(), RENDERSIZE - 1.0)); }
|
|
23
|
+
float acrossOf(vec2 c) { return sortAxis == 0 ? c.y : c.x; }
|
|
24
|
+
float alongOf(vec2 c) { return sortAxis == 0 ? c.x : cellDims().y - 1.0 - c.y; }
|
|
25
|
+
|
|
26
|
+
// Span mask: a cell takes part when its row is gated in and its perceptual luma lies in [lo, hi].
|
|
27
|
+
bool maskOf(vec2 c) {
|
|
28
|
+
if (!inCells(c)) return false;
|
|
29
|
+
uint across = uint(acrossOf(c));
|
|
30
|
+
uint st = uint(floor(TIME * stutterHz));
|
|
31
|
+
uint sd = seedU();
|
|
32
|
+
float kick = clamp(audioKick, 0.0, 2.0);
|
|
33
|
+
if (h2(across + 7u, st * 977u + sd) > clamp(rowsFrac + 0.4 * kick, 0.0, 1.0)) return false;
|
|
34
|
+
float sw = sweep * sin(6.2832 * (TIME * sweepRate + h1(sd + 17u)));
|
|
35
|
+
float lo = threshLo + sw - 0.25 * kick + (h2(across, st + sd + 3u) - 0.5) * rowVar;
|
|
36
|
+
float hi = threshHi + sw + 0.2 * kick + (h2(across, st + sd + 5u) - 0.5) * rowVar;
|
|
37
|
+
float l = linearToSrgb(vec3(luma(texelFetch(keyBuf, cellTexel(c), 0).rgb))).r;
|
|
38
|
+
return l >= lo && l <= hi;
|
|
39
|
+
}
|
|
40
|
+
// Spans are cut at multiples of 256 cells; the cut grid is shifted per row so cuts do not line up.
|
|
41
|
+
float cutShift(vec2 c) { return floor(h2(uint(acrossOf(c)), seedU() + 99u) * 256.0) * cutJitter; }
|
|
42
|
+
|
|
43
|
+
void main() {
|
|
44
|
+
float cp = cellPx();
|
|
45
|
+
vec2 c = floor(vUv * RENDERSIZE / cp);
|
|
46
|
+
if (!maskOf(c)) { fragColor = vec4(0.0); return; }
|
|
47
|
+
vec2 dv = axisDir();
|
|
48
|
+
float posIn = mod(alongOf(c) + cutShift(c), 256.0);
|
|
49
|
+
float capL = posIn + 1.0;
|
|
50
|
+
float capR = 256.0 - posIn;
|
|
51
|
+
float kk = 32.0;
|
|
52
|
+
vec2 own = texelFetch(run5, cellTexel(c), 0).rg;
|
|
53
|
+
float L = own.x;
|
|
54
|
+
float R = own.y;
|
|
55
|
+
if (L >= kk) {
|
|
56
|
+
vec2 cn = c - dv * kk;
|
|
57
|
+
float ln = inCells(cn) ? texelFetch(run5, cellTexel(cn), 0).r : 0.0;
|
|
58
|
+
L = min(min(2.0 * kk, kk + ln), capL);
|
|
59
|
+
}
|
|
60
|
+
if (R >= kk) {
|
|
61
|
+
vec2 cn = c + dv * kk;
|
|
62
|
+
float rn = inCells(cn) ? texelFetch(run5, cellTexel(cn), 0).g : 0.0;
|
|
63
|
+
R = min(min(2.0 * kk, kk + rn), capR);
|
|
64
|
+
}
|
|
65
|
+
fragColor = vec4(L, R, 0.0, 1.0);
|
|
66
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// pixel-sort (pass7 run7: run lengths to the left (r) and right (g), capped at 128). Idea: pixel sorting as in ASDFPixelSort by Kim Asendorf (concept only; code written fresh).
|
|
2
|
+
// Spans of cells whose luma lies in a threshold window are sorted along an axis. Span extents come from
|
|
3
|
+
// log2 run-length doubling (pass1..pass8); the sort itself ranks 32 strided samples of the span in the
|
|
4
|
+
// last pass (exact when a span has <= 32 cells, a quantile approximation above that).
|
|
5
|
+
uint pcg(uint v) {
|
|
6
|
+
uint s = v * 747796405u + 2891336453u;
|
|
7
|
+
uint w = ((s >> ((s >> 28u) + 4u)) ^ s) * 277803737u;
|
|
8
|
+
return (w >> 22u) ^ w;
|
|
9
|
+
}
|
|
10
|
+
float h1(uint a) { return float(pcg(a)) / 4294967295.0; }
|
|
11
|
+
float h2(uint a, uint b) { return h1(a * 2654435761u + pcg(b + 1013904223u)); }
|
|
12
|
+
|
|
13
|
+
// SEED is the score seed / 2^32, so small integer seeds are tiny floats; recover the integer.
|
|
14
|
+
uint seedU() { return uint(min(SEED * 4294967296.0 + 0.5, 4294967040.0)); }
|
|
15
|
+
|
|
16
|
+
// The sort works on cells of cellPx x cellPx pixels (1 cell = 1 "pixel" of the sort).
|
|
17
|
+
// Reading order: left to right for the horizontal axis, top to bottom for the vertical one.
|
|
18
|
+
float cellPx() { return max(1.0, floor(cellSize * RENDERSIZE.y / 1080.0 + 0.5)); }
|
|
19
|
+
vec2 axisDir() { return sortAxis == 0 ? vec2(1.0, 0.0) : vec2(0.0, -1.0); }
|
|
20
|
+
vec2 cellDims() { return ceil(RENDERSIZE / cellPx()); }
|
|
21
|
+
bool inCells(vec2 c) { vec2 d = cellDims(); return c.x >= 0.0 && c.y >= 0.0 && c.x < d.x && c.y < d.y; }
|
|
22
|
+
ivec2 cellTexel(vec2 c) { return ivec2(min(c * cellPx(), RENDERSIZE - 1.0)); }
|
|
23
|
+
float acrossOf(vec2 c) { return sortAxis == 0 ? c.y : c.x; }
|
|
24
|
+
float alongOf(vec2 c) { return sortAxis == 0 ? c.x : cellDims().y - 1.0 - c.y; }
|
|
25
|
+
|
|
26
|
+
// Span mask: a cell takes part when its row is gated in and its perceptual luma lies in [lo, hi].
|
|
27
|
+
bool maskOf(vec2 c) {
|
|
28
|
+
if (!inCells(c)) return false;
|
|
29
|
+
uint across = uint(acrossOf(c));
|
|
30
|
+
uint st = uint(floor(TIME * stutterHz));
|
|
31
|
+
uint sd = seedU();
|
|
32
|
+
float kick = clamp(audioKick, 0.0, 2.0);
|
|
33
|
+
if (h2(across + 7u, st * 977u + sd) > clamp(rowsFrac + 0.4 * kick, 0.0, 1.0)) return false;
|
|
34
|
+
float sw = sweep * sin(6.2832 * (TIME * sweepRate + h1(sd + 17u)));
|
|
35
|
+
float lo = threshLo + sw - 0.25 * kick + (h2(across, st + sd + 3u) - 0.5) * rowVar;
|
|
36
|
+
float hi = threshHi + sw + 0.2 * kick + (h2(across, st + sd + 5u) - 0.5) * rowVar;
|
|
37
|
+
float l = linearToSrgb(vec3(luma(texelFetch(keyBuf, cellTexel(c), 0).rgb))).r;
|
|
38
|
+
return l >= lo && l <= hi;
|
|
39
|
+
}
|
|
40
|
+
// Spans are cut at multiples of 256 cells; the cut grid is shifted per row so cuts do not line up.
|
|
41
|
+
float cutShift(vec2 c) { return floor(h2(uint(acrossOf(c)), seedU() + 99u) * 256.0) * cutJitter; }
|
|
42
|
+
|
|
43
|
+
void main() {
|
|
44
|
+
float cp = cellPx();
|
|
45
|
+
vec2 c = floor(vUv * RENDERSIZE / cp);
|
|
46
|
+
if (!maskOf(c)) { fragColor = vec4(0.0); return; }
|
|
47
|
+
vec2 dv = axisDir();
|
|
48
|
+
float posIn = mod(alongOf(c) + cutShift(c), 256.0);
|
|
49
|
+
float capL = posIn + 1.0;
|
|
50
|
+
float capR = 256.0 - posIn;
|
|
51
|
+
float kk = 64.0;
|
|
52
|
+
vec2 own = texelFetch(run6, cellTexel(c), 0).rg;
|
|
53
|
+
float L = own.x;
|
|
54
|
+
float R = own.y;
|
|
55
|
+
if (L >= kk) {
|
|
56
|
+
vec2 cn = c - dv * kk;
|
|
57
|
+
float ln = inCells(cn) ? texelFetch(run6, cellTexel(cn), 0).r : 0.0;
|
|
58
|
+
L = min(min(2.0 * kk, kk + ln), capL);
|
|
59
|
+
}
|
|
60
|
+
if (R >= kk) {
|
|
61
|
+
vec2 cn = c + dv * kk;
|
|
62
|
+
float rn = inCells(cn) ? texelFetch(run6, cellTexel(cn), 0).g : 0.0;
|
|
63
|
+
R = min(min(2.0 * kk, kk + rn), capR);
|
|
64
|
+
}
|
|
65
|
+
fragColor = vec4(L, R, 0.0, 1.0);
|
|
66
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// pixel-sort (pass8 run8: run lengths to the left (r) and right (g), capped at 256). Idea: pixel sorting as in ASDFPixelSort by Kim Asendorf (concept only; code written fresh).
|
|
2
|
+
// Spans of cells whose luma lies in a threshold window are sorted along an axis. Span extents come from
|
|
3
|
+
// log2 run-length doubling (pass1..pass8); the sort itself ranks 32 strided samples of the span in the
|
|
4
|
+
// last pass (exact when a span has <= 32 cells, a quantile approximation above that).
|
|
5
|
+
uint pcg(uint v) {
|
|
6
|
+
uint s = v * 747796405u + 2891336453u;
|
|
7
|
+
uint w = ((s >> ((s >> 28u) + 4u)) ^ s) * 277803737u;
|
|
8
|
+
return (w >> 22u) ^ w;
|
|
9
|
+
}
|
|
10
|
+
float h1(uint a) { return float(pcg(a)) / 4294967295.0; }
|
|
11
|
+
float h2(uint a, uint b) { return h1(a * 2654435761u + pcg(b + 1013904223u)); }
|
|
12
|
+
|
|
13
|
+
// SEED is the score seed / 2^32, so small integer seeds are tiny floats; recover the integer.
|
|
14
|
+
uint seedU() { return uint(min(SEED * 4294967296.0 + 0.5, 4294967040.0)); }
|
|
15
|
+
|
|
16
|
+
// The sort works on cells of cellPx x cellPx pixels (1 cell = 1 "pixel" of the sort).
|
|
17
|
+
// Reading order: left to right for the horizontal axis, top to bottom for the vertical one.
|
|
18
|
+
float cellPx() { return max(1.0, floor(cellSize * RENDERSIZE.y / 1080.0 + 0.5)); }
|
|
19
|
+
vec2 axisDir() { return sortAxis == 0 ? vec2(1.0, 0.0) : vec2(0.0, -1.0); }
|
|
20
|
+
vec2 cellDims() { return ceil(RENDERSIZE / cellPx()); }
|
|
21
|
+
bool inCells(vec2 c) { vec2 d = cellDims(); return c.x >= 0.0 && c.y >= 0.0 && c.x < d.x && c.y < d.y; }
|
|
22
|
+
ivec2 cellTexel(vec2 c) { return ivec2(min(c * cellPx(), RENDERSIZE - 1.0)); }
|
|
23
|
+
float acrossOf(vec2 c) { return sortAxis == 0 ? c.y : c.x; }
|
|
24
|
+
float alongOf(vec2 c) { return sortAxis == 0 ? c.x : cellDims().y - 1.0 - c.y; }
|
|
25
|
+
|
|
26
|
+
// Span mask: a cell takes part when its row is gated in and its perceptual luma lies in [lo, hi].
|
|
27
|
+
bool maskOf(vec2 c) {
|
|
28
|
+
if (!inCells(c)) return false;
|
|
29
|
+
uint across = uint(acrossOf(c));
|
|
30
|
+
uint st = uint(floor(TIME * stutterHz));
|
|
31
|
+
uint sd = seedU();
|
|
32
|
+
float kick = clamp(audioKick, 0.0, 2.0);
|
|
33
|
+
if (h2(across + 7u, st * 977u + sd) > clamp(rowsFrac + 0.4 * kick, 0.0, 1.0)) return false;
|
|
34
|
+
float sw = sweep * sin(6.2832 * (TIME * sweepRate + h1(sd + 17u)));
|
|
35
|
+
float lo = threshLo + sw - 0.25 * kick + (h2(across, st + sd + 3u) - 0.5) * rowVar;
|
|
36
|
+
float hi = threshHi + sw + 0.2 * kick + (h2(across, st + sd + 5u) - 0.5) * rowVar;
|
|
37
|
+
float l = linearToSrgb(vec3(luma(texelFetch(keyBuf, cellTexel(c), 0).rgb))).r;
|
|
38
|
+
return l >= lo && l <= hi;
|
|
39
|
+
}
|
|
40
|
+
// Spans are cut at multiples of 256 cells; the cut grid is shifted per row so cuts do not line up.
|
|
41
|
+
float cutShift(vec2 c) { return floor(h2(uint(acrossOf(c)), seedU() + 99u) * 256.0) * cutJitter; }
|
|
42
|
+
|
|
43
|
+
void main() {
|
|
44
|
+
float cp = cellPx();
|
|
45
|
+
vec2 c = floor(vUv * RENDERSIZE / cp);
|
|
46
|
+
if (!maskOf(c)) { fragColor = vec4(0.0); return; }
|
|
47
|
+
vec2 dv = axisDir();
|
|
48
|
+
float posIn = mod(alongOf(c) + cutShift(c), 256.0);
|
|
49
|
+
float capL = posIn + 1.0;
|
|
50
|
+
float capR = 256.0 - posIn;
|
|
51
|
+
float kk = 128.0;
|
|
52
|
+
vec2 own = texelFetch(run7, cellTexel(c), 0).rg;
|
|
53
|
+
float L = own.x;
|
|
54
|
+
float R = own.y;
|
|
55
|
+
if (L >= kk) {
|
|
56
|
+
vec2 cn = c - dv * kk;
|
|
57
|
+
float ln = inCells(cn) ? texelFetch(run7, cellTexel(cn), 0).r : 0.0;
|
|
58
|
+
L = min(min(2.0 * kk, kk + ln), capL);
|
|
59
|
+
}
|
|
60
|
+
if (R >= kk) {
|
|
61
|
+
vec2 cn = c + dv * kk;
|
|
62
|
+
float rn = inCells(cn) ? texelFetch(run7, cellTexel(cn), 0).g : 0.0;
|
|
63
|
+
R = min(min(2.0 * kk, kk + rn), capR);
|
|
64
|
+
}
|
|
65
|
+
fragColor = vec4(L, R, 0.0, 1.0);
|
|
66
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":1,"template":"rgb-split","preset":"rgb-split-diagonal-stutter","input":{"video":"test-media/clip-01.mp4"},"durationSec":4,"seed":23,"out":"rgb-split-diagonal-stutter"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":1,"template":"rgb-split","preset":"rgb-split-hard","input":{"video":"test-media/clip-01.mp4"},"durationSec":4,"seed":21,"out":"rgb-split-hard"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":1,"template":"rgb-split","preset":"rgb-split-kick","input":{"video":"test-media/clip-01.mp4","audio":"test-media/beat-132.mp3"},"bindings":[{"param":"audioKick","feature":"onset","gain":1.4,"offset":0,"attackMs":0,"releaseMs":240}],"durationSec":4,"seed":24,"out":"rgb-split-kick"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":1,"template":"rgb-split","preset":"rgb-split-radial","input":{"video":"test-media/clip-02.mp4"},"durationSec":4,"seed":22,"out":"rgb-split-radial"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"DESCRIPTION": "Spectral RGB split with seeded bursts, direction jitter and sideways row tears over footage",
|
|
3
|
+
"CREDIT": "agentvfx",
|
|
4
|
+
"ISFVSN": "2",
|
|
5
|
+
"CATEGORIES": ["glitch"],
|
|
6
|
+
"INPUTS": [
|
|
7
|
+
{ "NAME": "splitAmount", "TYPE": "float", "MIN": 0, "MAX": 200, "DEFAULT": 22 },
|
|
8
|
+
{ "NAME": "splitMode", "TYPE": "long", "MIN": 0, "MAX": 1, "VALUES": [0, 1], "LABELS": ["axis", "radial"], "DEFAULT": 0 },
|
|
9
|
+
{ "NAME": "splitAngle", "TYPE": "float", "MIN": -3.1416, "MAX": 3.1416, "DEFAULT": 0 },
|
|
10
|
+
{ "NAME": "center", "TYPE": "point2D", "DEFAULT": [0.5, 0.5] },
|
|
11
|
+
{ "NAME": "splitTaps", "TYPE": "long", "MIN": 3, "MAX": 12, "DEFAULT": 9 },
|
|
12
|
+
{ "NAME": "jitter", "TYPE": "float", "MIN": 0, "MAX": 1, "DEFAULT": 0.8 },
|
|
13
|
+
{ "NAME": "jitterRate", "TYPE": "float", "MIN": 1, "MAX": 60, "DEFAULT": 18 },
|
|
14
|
+
{ "NAME": "burstRate", "TYPE": "float", "MIN": 0.25, "MAX": 12, "DEFAULT": 2.4 },
|
|
15
|
+
{ "NAME": "burstProb", "TYPE": "float", "MIN": 0, "MAX": 1, "DEFAULT": 0.85 },
|
|
16
|
+
{ "NAME": "burstFrames", "TYPE": "long", "MIN": 1, "MAX": 60, "DEFAULT": 7 },
|
|
17
|
+
{ "NAME": "burstBoost", "TYPE": "float", "MIN": 0, "MAX": 8, "DEFAULT": 3.5 },
|
|
18
|
+
{ "NAME": "tear", "TYPE": "float", "MIN": 0, "MAX": 1, "DEFAULT": 0.8 },
|
|
19
|
+
{ "NAME": "audioKick", "TYPE": "float", "MIN": 0, "MAX": 2, "DEFAULT": 0 },
|
|
20
|
+
{ "NAME": "saturation", "TYPE": "float", "MIN": 0, "MAX": 3, "DEFAULT": 1.35 },
|
|
21
|
+
{ "NAME": "punch", "TYPE": "float", "MIN": 0.5, "MAX": 3, "DEFAULT": 1.25 },
|
|
22
|
+
{ "NAME": "scanlines", "TYPE": "float", "MIN": 0, "MAX": 1, "DEFAULT": 0.3 },
|
|
23
|
+
{ "NAME": "grain", "TYPE": "float", "MIN": 0, "MAX": 1, "DEFAULT": 0.12 }
|
|
24
|
+
],
|
|
25
|
+
"X_AGENTVFX": {
|
|
26
|
+
"id": "rgb-split",
|
|
27
|
+
"family": "glitch",
|
|
28
|
+
"input": "footage",
|
|
29
|
+
"spdx": "LicenseRef-agentvfx",
|
|
30
|
+
"flash": "possible",
|
|
31
|
+
"fps": 30,
|
|
32
|
+
"palette": false,
|
|
33
|
+
"presets": {
|
|
34
|
+
"rgb-split-hard": {},
|
|
35
|
+
"rgb-split-radial": { "splitMode": 1, "splitAmount": 30, "burstBoost": 4, "tear": 0.3, "jitter": 0.4, "burstRate": 2 },
|
|
36
|
+
"rgb-split-diagonal-stutter": { "splitAngle": 0.7854, "splitAmount": 34, "jitterRate": 30, "burstRate": 4, "burstFrames": 5, "burstBoost": 4.5, "tear": 1, "splitTaps": 5 },
|
|
37
|
+
"rgb-split-kick": { "splitAmount": 8, "burstProb": 0, "burstBoost": 6, "tear": 1, "audioKick": 0, "jitter": 1 }
|
|
38
|
+
},
|
|
39
|
+
"audioBind": { "audioKick": "onset" },
|
|
40
|
+
"safeSubstitute": { "params": { "burstRate": 0.5, "burstBoost": 0.6, "tear": 0, "jitter": 0.2, "grain": 0.05 } },
|
|
41
|
+
"credits": [
|
|
42
|
+
"Chromatic aberration as spectral tap accumulation, https://en.wikipedia.org/wiki/Chromatic_aberration",
|
|
43
|
+
"PCG integer hash, M. E. O'Neill, https://www.pcg-random.org/"
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// rgb-split: spectral channel split with burst gating, direction jitter and horizontal band tears.
|
|
2
|
+
// Idea: chromatic aberration as a smear of spectral taps along an offset path (taps = 3 is the classic
|
|
3
|
+
// three-copy split; more taps blend the copies into a rainbow smear). Written fresh for agentvfx.
|
|
4
|
+
// Bursts: every 1/burstRate seconds a burst may fire (seeded by SEED); during `burstFrames` frames the
|
|
5
|
+
// offset is multiplied by burstBoost, the direction jumps around and rows tear sideways.
|
|
6
|
+
uint pcg(uint v) {
|
|
7
|
+
uint s = v * 747796405u + 2891336453u;
|
|
8
|
+
uint w = ((s >> ((s >> 28u) + 4u)) ^ s) * 277803737u;
|
|
9
|
+
return (w >> 22u) ^ w;
|
|
10
|
+
}
|
|
11
|
+
float h1(uint a) { return float(pcg(a)) / 4294967295.0; }
|
|
12
|
+
float h2(uint a, uint b) { return h1(a * 2654435761u + pcg(b + 1013904223u)); }
|
|
13
|
+
// SEED is the score seed / 2^32, so small integer seeds are tiny floats; recover the integer.
|
|
14
|
+
uint seedU() { return uint(min(SEED * 4294967296.0 + 0.5, 4294967040.0)); }
|
|
15
|
+
|
|
16
|
+
void main() {
|
|
17
|
+
float u = RENDERSIZE.y / 1080.0;
|
|
18
|
+
float fps = 1.0 / TIMEDELTA;
|
|
19
|
+
uint sd = seedU();
|
|
20
|
+
vec2 px = vUv * RENDERSIZE;
|
|
21
|
+
|
|
22
|
+
// burst gate
|
|
23
|
+
float ph = TIME * burstRate;
|
|
24
|
+
uint bi = uint(floor(ph));
|
|
25
|
+
float age = fract(ph) / max(burstRate, 0.001) * fps;
|
|
26
|
+
float env = (h2(bi, sd) < burstProb && age < float(burstFrames)) ? 1.0 : 0.0;
|
|
27
|
+
float k = clamp(env + audioKick, 0.0, 1.6);
|
|
28
|
+
|
|
29
|
+
// jitter step: the offset direction and size re-roll jitterRate times per second
|
|
30
|
+
uint js = uint(floor(TIME * jitterRate));
|
|
31
|
+
float jr = h2(js, sd + 11u);
|
|
32
|
+
float jd = h2(js, sd + 29u);
|
|
33
|
+
float amt = splitAmount * u * (1.0 + burstBoost * k) * (1.0 + jitter * (jr * 2.0 - 1.0) * 0.6);
|
|
34
|
+
|
|
35
|
+
// sample position with optional band tear
|
|
36
|
+
vec2 pos = px;
|
|
37
|
+
if (tear > 0.0 && k > 0.0) {
|
|
38
|
+
float bandH = max(2.0, (10.0 + 90.0 * h2(js, sd + 3u))) * u;
|
|
39
|
+
uint band = uint(floor(px.y / bandH));
|
|
40
|
+
float on = step(h2(band, js * 31u + sd), 0.35 * min(k, 1.0));
|
|
41
|
+
pos.x += on * (h2(band, js + sd + 77u) * 2.0 - 1.0) * tear * 0.12 * RENDERSIZE.x * min(k, 1.0);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// direction of the split
|
|
45
|
+
vec2 dir;
|
|
46
|
+
float aspect = RENDERSIZE.x / RENDERSIZE.y;
|
|
47
|
+
if (splitMode == 1) {
|
|
48
|
+
vec2 p = (vUv - center) * vec2(aspect, 1.0);
|
|
49
|
+
float r = length(p);
|
|
50
|
+
dir = p / max(r, 1e-4) * (0.35 + 1.4 * r);
|
|
51
|
+
} else {
|
|
52
|
+
float ang = splitAngle + (jd - 0.5) * jitter * (3.1416 * 1.2 * k + 0.5);
|
|
53
|
+
dir = vec2(cos(ang), sin(ang));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
vec3 acc = vec3(0.0);
|
|
57
|
+
vec3 ws = vec3(0.0);
|
|
58
|
+
for (int i = 0; i < 12; i++) {
|
|
59
|
+
if (i >= splitTaps) break;
|
|
60
|
+
float t = splitTaps > 1 ? float(i) / float(splitTaps - 1) : 0.5;
|
|
61
|
+
vec3 w = vec3(max(0.0, 1.0 - 2.0 * t), 1.0 - abs(2.0 * t - 1.0), max(0.0, 2.0 * t - 1.0));
|
|
62
|
+
vec2 q = pos + dir * amt * (t - 0.5) * 2.0;
|
|
63
|
+
acc += w * texture(inputImage, q / RENDERSIZE).rgb;
|
|
64
|
+
ws += w;
|
|
65
|
+
}
|
|
66
|
+
vec3 col = acc / max(ws, vec3(1e-4));
|
|
67
|
+
|
|
68
|
+
// punch: saturation + contrast, scanlines, grain
|
|
69
|
+
float lm = luma(col);
|
|
70
|
+
col = mix(vec3(lm), col, saturation);
|
|
71
|
+
col = max((col - 0.18) * punch + 0.18, 0.0);
|
|
72
|
+
col *= 1.0 - scanlines * (0.5 + 0.5 * sin(px.y * 3.14159 / max(u, 0.25)));
|
|
73
|
+
float g = h2(uint(px.x) + uint(px.y) * 4099u, uint(FRAMEINDEX) + sd);
|
|
74
|
+
col += grain * (g - 0.5) * (0.4 + 0.6 * k);
|
|
75
|
+
fragColor = vec4(max(col, 0.0), 1.0);
|
|
76
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":1,"template":"vhs","preset":"vhs-clean","input":{"video":"test-media/clip-01.mp4"},"durationSec":4,"seed":44,"out":"vhs-clean"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":1,"template":"vhs","preset":"vhs-crash","input":{"video":"test-media/clip-01.mp4"},"durationSec":4,"seed":43,"out":"vhs-crash"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":1,"template":"vhs","preset":"vhs-tape","input":{"video":"test-media/clip-01.mp4"},"durationSec":4,"seed":41,"out":"vhs-tape"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":1,"template":"vhs","preset":"vhs-worn","input":{"video":"test-media/clip-02.mp4"},"durationSec":4,"seed":42,"out":"vhs-worn"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"DESCRIPTION": "Worn VHS tape over footage: chroma bleed, tracking-noise band, head-switching skew, scanlines, wobble and dropouts",
|
|
3
|
+
"CREDIT": "agentvfx",
|
|
4
|
+
"ISFVSN": "2",
|
|
5
|
+
"CATEGORIES": ["glitch", "retro"],
|
|
6
|
+
"INPUTS": [
|
|
7
|
+
{ "NAME": "chromaBleed", "TYPE": "float", "MIN": 0, "MAX": 80, "DEFAULT": 26 },
|
|
8
|
+
{ "NAME": "lumaBlur", "TYPE": "float", "MIN": 0, "MAX": 6, "DEFAULT": 1.6 },
|
|
9
|
+
{ "NAME": "ringing", "TYPE": "float", "MIN": 0, "MAX": 2, "DEFAULT": 0.6 },
|
|
10
|
+
{ "NAME": "wobble", "TYPE": "float", "MIN": 0, "MAX": 2, "DEFAULT": 0.8 },
|
|
11
|
+
{ "NAME": "trackAmount", "TYPE": "float", "MIN": 0, "MAX": 1, "DEFAULT": 0.85 },
|
|
12
|
+
{ "NAME": "trackSpeed", "TYPE": "float", "MIN": -1, "MAX": 1, "DEFAULT": 0.17 },
|
|
13
|
+
{ "NAME": "trackHeight", "TYPE": "float", "MIN": 0.02, "MAX": 0.5, "DEFAULT": 0.14 },
|
|
14
|
+
{ "NAME": "headSwitch", "TYPE": "float", "MIN": 0, "MAX": 1, "DEFAULT": 1 },
|
|
15
|
+
{ "NAME": "headHeight", "TYPE": "float", "MIN": 0.01, "MAX": 0.2, "DEFAULT": 0.06 },
|
|
16
|
+
{ "NAME": "scanlines", "TYPE": "float", "MIN": 0, "MAX": 1, "DEFAULT": 0.6 },
|
|
17
|
+
{ "NAME": "tapeNoise", "TYPE": "float", "MIN": 0, "MAX": 1, "DEFAULT": 0.35 },
|
|
18
|
+
{ "NAME": "dropouts", "TYPE": "float", "MIN": 0, "MAX": 2, "DEFAULT": 0.8 },
|
|
19
|
+
{ "NAME": "chromaNoise", "TYPE": "float", "MIN": 0, "MAX": 1, "DEFAULT": 0.5 },
|
|
20
|
+
{ "NAME": "saturation", "TYPE": "float", "MIN": 0, "MAX": 3, "DEFAULT": 1.4 },
|
|
21
|
+
{ "NAME": "contrast", "TYPE": "float", "MIN": 0.5, "MAX": 3, "DEFAULT": 1.2 },
|
|
22
|
+
{ "NAME": "flicker", "TYPE": "float", "MIN": 0, "MAX": 1, "DEFAULT": 0.5 },
|
|
23
|
+
{ "NAME": "audioKick", "TYPE": "float", "MIN": 0, "MAX": 2, "DEFAULT": 0 }
|
|
24
|
+
],
|
|
25
|
+
"X_AGENTVFX": {
|
|
26
|
+
"id": "vhs",
|
|
27
|
+
"family": "glitch",
|
|
28
|
+
"input": "footage",
|
|
29
|
+
"spdx": "LicenseRef-agentvfx",
|
|
30
|
+
"flash": "possible",
|
|
31
|
+
"fps": 30,
|
|
32
|
+
"palette": false,
|
|
33
|
+
"presets": {
|
|
34
|
+
"vhs-tape": {},
|
|
35
|
+
"vhs-worn": { "chromaBleed": 42, "dropouts": 1.6, "trackHeight": 0.22, "tapeNoise": 0.6, "scanlines": 0.75, "wobble": 1.2, "ringing": 0.9 },
|
|
36
|
+
"vhs-clean": { "chromaBleed": 12, "wobble": 0.3, "trackAmount": 0.35, "dropouts": 0.2, "tapeNoise": 0.15, "headSwitch": 0.6, "scanlines": 0.35, "flicker": 0.15, "saturation": 1.15 },
|
|
37
|
+
"vhs-crash": { "trackAmount": 1, "trackSpeed": 0.55, "trackHeight": 0.34, "wobble": 1.7, "chromaBleed": 64, "dropouts": 2, "tapeNoise": 0.75, "flicker": 0.9 }
|
|
38
|
+
},
|
|
39
|
+
"audioBind": { "audioKick": "onset" },
|
|
40
|
+
"safeSubstitute": { "params": { "flicker": 0, "dropouts": 0.2, "tapeNoise": 0.2, "trackAmount": 0.3 } },
|
|
41
|
+
"credits": [
|
|
42
|
+
"NTSC YIQ colour space, https://en.wikipedia.org/wiki/YIQ",
|
|
43
|
+
"PCG integer hash, M. E. O'Neill, https://www.pcg-random.org/"
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// vhs: analog tape. Luma/chroma separation in YIQ (chroma smears to the right and loses resolution),
|
|
2
|
+
// luma edge ringing, per-line wobble, a scrolling tracking-noise band of blocky static, bottom
|
|
3
|
+
// head-switching skew, scanlines, dropout streaks, flicker. Written fresh for agentvfx; the YIQ matrices
|
|
4
|
+
// are the standard NTSC ones (https://en.wikipedia.org/wiki/YIQ).
|
|
5
|
+
uint pcg(uint v) {
|
|
6
|
+
uint s = v * 747796405u + 2891336453u;
|
|
7
|
+
uint w = ((s >> ((s >> 28u) + 4u)) ^ s) * 277803737u;
|
|
8
|
+
return (w >> 22u) ^ w;
|
|
9
|
+
}
|
|
10
|
+
float h1(uint a) { return float(pcg(a)) / 4294967295.0; }
|
|
11
|
+
float h2(uint a, uint b) { return h1(a * 2654435761u + pcg(b + 1013904223u)); }
|
|
12
|
+
// SEED is the score seed / 2^32, so small integer seeds are tiny floats; recover the integer.
|
|
13
|
+
uint seedU() { return uint(min(SEED * 4294967296.0 + 0.5, 4294967040.0)); }
|
|
14
|
+
|
|
15
|
+
vec3 toYiq(vec3 c) {
|
|
16
|
+
return vec3(dot(c, vec3(0.299, 0.587, 0.114)), dot(c, vec3(0.596, -0.274, -0.322)), dot(c, vec3(0.211, -0.523, 0.312)));
|
|
17
|
+
}
|
|
18
|
+
vec3 fromYiq(vec3 q) {
|
|
19
|
+
return vec3(q.x + 0.956 * q.y + 0.621 * q.z, q.x - 0.272 * q.y - 0.647 * q.z, q.x - 1.106 * q.y + 1.703 * q.z);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
void main() {
|
|
23
|
+
float u = RENDERSIZE.y / 1080.0;
|
|
24
|
+
uint fr = uint(FRAMEINDEX);
|
|
25
|
+
uint sd = seedU();
|
|
26
|
+
vec2 px = vUv * RENDERSIZE;
|
|
27
|
+
float lineH = 3.0 * u;
|
|
28
|
+
uint line = uint(floor(px.y / lineH));
|
|
29
|
+
float kick = clamp(audioKick, 0.0, 2.0);
|
|
30
|
+
|
|
31
|
+
// tracking band: scrolls upward, wraps; kicks make it wider and harder
|
|
32
|
+
float yb = fract(trackSpeed * TIME + h1(sd + 5u));
|
|
33
|
+
float hw = trackHeight * (1.0 + 0.5 * kick) * 0.5;
|
|
34
|
+
float dd = abs(fract(vUv.y - yb + 0.5) - 0.5);
|
|
35
|
+
float inBand = (1.0 - smoothstep(hw * 0.55, hw, dd)) * clamp(trackAmount + 0.4 * kick, 0.0, 1.5);
|
|
36
|
+
|
|
37
|
+
// head switching: bottom rows skew sideways
|
|
38
|
+
float ht = clamp(1.0 - vUv.y / max(headHeight, 0.001), 0.0, 1.0);
|
|
39
|
+
|
|
40
|
+
float lineNoise = h2(line, fr + sd) - 0.5;
|
|
41
|
+
float dx = wobble * u * (6.0 * sin(px.y / (u * 40.0) + TIME * 2.3) + 3.0 * sin(px.y / (u * 9.0) - TIME * 5.0) + 5.0 * lineNoise);
|
|
42
|
+
dx += inBand * u * (140.0 * lineNoise + 50.0 * sin(px.y / (u * 7.0) + TIME * 9.0));
|
|
43
|
+
dx += headSwitch * (ht * ht * ht * 0.09 * RENDERSIZE.x + ht * u * 30.0 * lineNoise);
|
|
44
|
+
vec2 base = vec2(px.x + dx, px.y);
|
|
45
|
+
|
|
46
|
+
// luma: small blur + ringing (unsharp)
|
|
47
|
+
float lb = max(lumaBlur, 0.05) * u;
|
|
48
|
+
float y0 = 0.0;
|
|
49
|
+
float yw = 0.0;
|
|
50
|
+
float yWide = 0.0;
|
|
51
|
+
for (int i = -4; i <= 4; i++) {
|
|
52
|
+
float w = 1.0 - abs(float(i)) / 5.0;
|
|
53
|
+
vec3 s = texture(inputImage, (base + vec2(float(i) * lb, 0.0)) / RENDERSIZE).rgb;
|
|
54
|
+
float yy = toYiq(s).x;
|
|
55
|
+
y0 += w * yy;
|
|
56
|
+
yw += w;
|
|
57
|
+
yWide += yy / 9.0;
|
|
58
|
+
}
|
|
59
|
+
float Y = y0 / yw;
|
|
60
|
+
Y += ringing * (Y - yWide);
|
|
61
|
+
|
|
62
|
+
// chroma: exponential smear from the left, coarse
|
|
63
|
+
vec2 iq = vec2(0.0);
|
|
64
|
+
float cw = 0.0;
|
|
65
|
+
for (int i = 0; i < 12; i++) {
|
|
66
|
+
float w = exp(-float(i) * 0.3);
|
|
67
|
+
vec3 s = texture(inputImage, (base - vec2(float(i) * chromaBleed * u / 12.0, 0.0)) / RENDERSIZE).rgb;
|
|
68
|
+
iq += w * toYiq(s).yz;
|
|
69
|
+
cw += w;
|
|
70
|
+
}
|
|
71
|
+
iq /= cw;
|
|
72
|
+
iq *= saturation;
|
|
73
|
+
iq += chromaNoise * vec2(h2(line, fr + sd + 7u) - 0.5, h2(line, fr + sd + 13u) - 0.5) * 0.25;
|
|
74
|
+
|
|
75
|
+
vec3 col = fromYiq(vec3(Y, iq));
|
|
76
|
+
|
|
77
|
+
// static inside the tracking band, blocky cells; head-switch noise
|
|
78
|
+
float cell = 4.0 * u;
|
|
79
|
+
vec2 cid = floor(px / vec2(cell * 3.0, cell));
|
|
80
|
+
float sn = h2(uint(int(cid.x)) + uint(int(cid.y)) * 8209u, fr + sd);
|
|
81
|
+
col = mix(col, vec3(sn * 0.9), clamp(inBand * 0.55 + ht * headSwitch * 0.5, 0.0, 0.95));
|
|
82
|
+
col += inBand * 0.12 * step(0.985, h2(line, fr + sd + 3u));
|
|
83
|
+
|
|
84
|
+
// dropout streaks
|
|
85
|
+
uint chunk = uint(floor(px.x / (60.0 * u)));
|
|
86
|
+
float dr = h2(line * 131u + chunk, fr + sd + 41u);
|
|
87
|
+
col = mix(col, vec3(0.95), step(1.0 - dropouts * 0.008, dr) * 0.85);
|
|
88
|
+
|
|
89
|
+
// scanlines, grain, flicker, contrast
|
|
90
|
+
col *= 1.0 - scanlines * 0.5 * (0.5 + 0.5 * cos(6.2832 * px.y / lineH));
|
|
91
|
+
float g = h2(uint(px.x) + uint(px.y) * 4099u, fr + sd + 91u);
|
|
92
|
+
col += tapeNoise * (g - 0.5) * 0.45;
|
|
93
|
+
col *= 1.0 + flicker * (h1(fr + sd) - 0.5) * 0.25;
|
|
94
|
+
col = max((col - 0.18) * contrast + 0.18, 0.0);
|
|
95
|
+
fragColor = vec4(col, 1.0);
|
|
96
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":1,"template":"sacred","preset":"sacred-classic","params":{"blend":0},"input":{"video":"test-media/clip-01.mp4","audio":"test-media/beat-132.mp3"},"durationSec":4,"seed":11,"hits":[{"beat":0,"template":"impact-1bit","preset":"onebit-hard","durationFrames":2},{"beat":1,"template":"impact-1bit","preset":"onebit-bayer","durationFrames":3},{"beat":2,"template":"impact-1bit","preset":"onebit-flip","durationFrames":3},{"beat":3,"template":"impact-1bit","preset":"onebit-blood","durationFrames":3},{"beat":4,"template":"impact-1bit","preset":"onebit-bayer","durationFrames":3}],"out":"impact-1bit-bayer"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"DESCRIPTION": "Impact frame: the layer below crushes to hard black and white (or a two-colour duotone, optional ordered dither) for 1-3 frames, then dissolves back in chunky blocks",
|
|
3
|
+
"CREDIT": "agentvfx",
|
|
4
|
+
"ISFVSN": "2",
|
|
5
|
+
"CATEGORIES": ["impact"],
|
|
6
|
+
"INPUTS": [
|
|
7
|
+
{ "NAME": "hitFrames", "TYPE": "long", "MIN": 1, "MAX": 12, "DEFAULT": 3 },
|
|
8
|
+
{ "NAME": "holdFrames", "TYPE": "long", "MIN": 0, "MAX": 6, "DEFAULT": 2 },
|
|
9
|
+
{ "NAME": "decayCurve", "TYPE": "float", "MIN": 0.3, "MAX": 4, "DEFAULT": 1 },
|
|
10
|
+
{ "NAME": "threshold", "TYPE": "float", "MIN": 0, "MAX": 1, "DEFAULT": 0.48 },
|
|
11
|
+
{ "NAME": "preContrast", "TYPE": "float", "MIN": 0.5, "MAX": 5, "DEFAULT": 1.6 },
|
|
12
|
+
{ "NAME": "adapt", "TYPE": "float", "MIN": 0, "MAX": 1, "DEFAULT": 0.5 },
|
|
13
|
+
{ "NAME": "adaptRadius", "TYPE": "float", "MIN": 1, "MAX": 40, "DEFAULT": 14 },
|
|
14
|
+
{ "NAME": "dither", "TYPE": "long", "MIN": 0, "MAX": 2, "VALUES": [0, 1, 2], "LABELS": ["hard", "bayer 8x8", "noise"], "DEFAULT": 0 },
|
|
15
|
+
{ "NAME": "ditherAmount", "TYPE": "float", "MIN": 0, "MAX": 1, "DEFAULT": 0.35 },
|
|
16
|
+
{ "NAME": "ditherPx", "TYPE": "float", "MIN": 1, "MAX": 12, "DEFAULT": 3 },
|
|
17
|
+
{ "NAME": "inkColor", "TYPE": "color", "DEFAULT": [0, 0, 0, 1] },
|
|
18
|
+
{ "NAME": "paperColor", "TYPE": "color", "DEFAULT": [1, 1, 1, 1] },
|
|
19
|
+
{ "NAME": "useScorePalette", "TYPE": "bool", "DEFAULT": false },
|
|
20
|
+
{ "NAME": "flip", "TYPE": "bool", "DEFAULT": false },
|
|
21
|
+
{ "NAME": "blockPx", "TYPE": "float", "MIN": 2, "MAX": 160, "DEFAULT": 40 }
|
|
22
|
+
],
|
|
23
|
+
"X_AGENTVFX": {
|
|
24
|
+
"id": "impact-1bit",
|
|
25
|
+
"family": "impact",
|
|
26
|
+
"input": "either",
|
|
27
|
+
"spdx": "LicenseRef-agentvfx",
|
|
28
|
+
"flash": "possible",
|
|
29
|
+
"fps": 30,
|
|
30
|
+
"palette": true,
|
|
31
|
+
"presets": {
|
|
32
|
+
"onebit-hard": { "hitFrames": 2, "holdFrames": 2, "threshold": 0.48, "preContrast": 1.8 },
|
|
33
|
+
"onebit-bayer": { "hitFrames": 3, "holdFrames": 2, "dither": 1, "ditherAmount": 0.45, "ditherPx": 3, "adapt": 0.25 },
|
|
34
|
+
"onebit-flip": { "hitFrames": 3, "holdFrames": 2, "flip": true, "adapt": 0.7, "preContrast": 2.2 },
|
|
35
|
+
"onebit-duotone": { "hitFrames": 4, "holdFrames": 2, "useScorePalette": true, "dither": 1, "ditherAmount": 0.3 },
|
|
36
|
+
"onebit-blood": { "hitFrames": 3, "holdFrames": 2, "inkColor": [0.02, 0, 0, 1], "paperColor": [0.9, 0.02, 0.02, 1], "adapt": 0.6 }
|
|
37
|
+
},
|
|
38
|
+
"safeSubstitute": { "template": "punch-shake" },
|
|
39
|
+
"credits": [
|
|
40
|
+
"Impact-frame grammar (1-bit black/white on contact), Roblox DevForum VFX notes and sakugabooru wiki",
|
|
41
|
+
"Bayer ordered dither, https://en.wikipedia.org/wiki/Ordered_dithering",
|
|
42
|
+
"Local-mean adaptive threshold, https://en.wikipedia.org/wiki/Thresholding_(image_processing)"
|
|
43
|
+
]
|
|
44
|
+
}
|
|
45
|
+
}
|