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.
Files changed (483) hide show
  1. package/AGENTS.md +8 -0
  2. package/GEMINI.md +1 -0
  3. package/LICENSE +172 -0
  4. package/README.md +236 -2
  5. package/package.json +35 -4
  6. package/skills/agentvfx/LICENSE +172 -0
  7. package/skills/agentvfx/NOTICE +44 -0
  8. package/skills/agentvfx/SKILL.md +90 -0
  9. package/skills/agentvfx/engine/core/constants.mjs +84 -0
  10. package/skills/agentvfx/engine/core/flash-constants.mjs +23 -0
  11. package/skills/agentvfx/engine/core/flash.mjs +240 -0
  12. package/skills/agentvfx/engine/core/mark.mjs +28 -0
  13. package/skills/agentvfx/engine/core/palettes.mjs +36 -0
  14. package/skills/agentvfx/engine/core/schedule.mjs +85 -0
  15. package/skills/agentvfx/engine/core/templates.mjs +43 -0
  16. package/skills/agentvfx/engine/core/util.mjs +167 -0
  17. package/skills/agentvfx/engine/core/validate.mjs +334 -0
  18. package/skills/agentvfx/engine/node/analysis.mjs +172 -0
  19. package/skills/agentvfx/engine/node/audio.mjs +621 -0
  20. package/skills/agentvfx/engine/node/board.mjs +24 -0
  21. package/skills/agentvfx/engine/node/chrome.mjs +349 -0
  22. package/skills/agentvfx/engine/node/encode.mjs +110 -0
  23. package/skills/agentvfx/engine/node/eye.mjs +77 -0
  24. package/skills/agentvfx/engine/node/footage.mjs +129 -0
  25. package/skills/agentvfx/engine/node/frame-worker.mjs +39 -0
  26. package/skills/agentvfx/engine/node/host.mjs +31 -0
  27. package/skills/agentvfx/engine/node/job.mjs +181 -0
  28. package/skills/agentvfx/engine/node/png.mjs +112 -0
  29. package/skills/agentvfx/engine/node/render.mjs +161 -0
  30. package/skills/agentvfx/engine/node/stage-capture.mjs +187 -0
  31. package/skills/agentvfx/engine/node/stage-serve.mjs +72 -0
  32. package/skills/agentvfx/engine/node/stills.mjs +100 -0
  33. package/skills/agentvfx/engine/node/ws-server.mjs +132 -0
  34. package/skills/agentvfx/engine/web/gl.mjs +319 -0
  35. package/skills/agentvfx/engine/web/glsl-common.mjs +78 -0
  36. package/skills/agentvfx/engine/web/init.js +23 -0
  37. package/skills/agentvfx/engine/web/prelude.mjs +150 -0
  38. package/skills/agentvfx/engine/web/render.html +11 -0
  39. package/skills/agentvfx/engine/web/render.mjs +388 -0
  40. package/skills/agentvfx/engine/web/scale.mjs +15 -0
  41. package/skills/agentvfx/engine/web/text.mjs +158 -0
  42. package/skills/agentvfx/plates/terminalcore/README.md +61 -0
  43. package/skills/agentvfx/plates/terminalcore/__pycache__/crt.cpython-313.pyc +0 -0
  44. package/skills/agentvfx/plates/terminalcore/__pycache__/font.cpython-313.pyc +0 -0
  45. package/skills/agentvfx/plates/terminalcore/__pycache__/gallery.cpython-313.pyc +0 -0
  46. package/skills/agentvfx/plates/terminalcore/__pycache__/gallery_mats.cpython-313.pyc +0 -0
  47. package/skills/agentvfx/plates/terminalcore/__pycache__/gallery_room.cpython-313.pyc +0 -0
  48. package/skills/agentvfx/plates/terminalcore/__pycache__/materials.cpython-313.pyc +0 -0
  49. package/skills/agentvfx/plates/terminalcore/__pycache__/nodekit.cpython-313.pyc +0 -0
  50. package/skills/agentvfx/plates/terminalcore/__pycache__/room.cpython-313.pyc +0 -0
  51. package/skills/agentvfx/plates/terminalcore/__pycache__/shots.cpython-313.pyc +0 -0
  52. package/skills/agentvfx/plates/terminalcore/__pycache__/textures.cpython-313.pyc +0 -0
  53. package/skills/agentvfx/plates/terminalcore/__pycache__/wall.cpython-313.pyc +0 -0
  54. package/skills/agentvfx/plates/terminalcore/crt.py +143 -0
  55. package/skills/agentvfx/plates/terminalcore/font.py +80 -0
  56. package/skills/agentvfx/plates/terminalcore/gallery.py +61 -0
  57. package/skills/agentvfx/plates/terminalcore/gallery_mats.py +144 -0
  58. package/skills/agentvfx/plates/terminalcore/gallery_room.py +126 -0
  59. package/skills/agentvfx/plates/terminalcore/materials.py +170 -0
  60. package/skills/agentvfx/plates/terminalcore/nodekit.py +87 -0
  61. package/skills/agentvfx/plates/terminalcore/room.py +82 -0
  62. package/skills/agentvfx/plates/terminalcore/scene.py +219 -0
  63. package/skills/agentvfx/plates/terminalcore/shots.py +48 -0
  64. package/skills/agentvfx/plates/terminalcore/textures.py +79 -0
  65. package/skills/agentvfx/plates/terminalcore/wall.py +103 -0
  66. package/skills/agentvfx/references/plates.md +22 -0
  67. package/skills/agentvfx/references/template-format.md +149 -0
  68. package/skills/agentvfx/references/web.md +63 -0
  69. package/skills/agentvfx/runtime/agentvfx.js +708 -0
  70. package/skills/agentvfx/schemas/fx-score.schema.json +98 -0
  71. package/skills/agentvfx/scripts/export-web.mjs +155 -0
  72. package/skills/agentvfx/scripts/loop.mjs +129 -0
  73. package/skills/agentvfx/scripts/make-beat.mjs +133 -0
  74. package/skills/agentvfx/scripts/plate.mjs +82 -0
  75. package/skills/agentvfx/scripts/vfx.mjs +173 -0
  76. package/skills/agentvfx/templates/_test/feedback-counter/fx.json +11 -0
  77. package/skills/agentvfx/templates/_test/feedback-counter/main.frag +4 -0
  78. package/skills/agentvfx/templates/_test/feedback-counter/pass0.frag +4 -0
  79. package/skills/agentvfx/templates/_test/gradient/fx.json +23 -0
  80. package/skills/agentvfx/templates/_test/gradient/main.frag +5 -0
  81. package/skills/agentvfx/templates/_test/identity/fx.json +10 -0
  82. package/skills/agentvfx/templates/_test/identity/main.frag +4 -0
  83. package/skills/agentvfx/templates/_test/strobe/fx.json +14 -0
  84. package/skills/agentvfx/templates/_test/strobe/main.frag +6 -0
  85. package/skills/agentvfx/templates/_test/text-probe/fx.json +15 -0
  86. package/skills/agentvfx/templates/_test/text-probe/main.frag +6 -0
  87. package/skills/agentvfx/templates/brutal/NOTES.md +14 -0
  88. package/skills/agentvfx/templates/brutal/_src/boot-log/def.mjs +57 -0
  89. package/skills/agentvfx/templates/brutal/_src/boot-log/main.src.frag +129 -0
  90. package/skills/agentvfx/templates/brutal/_src/build.mjs +33 -0
  91. package/skills/agentvfx/templates/brutal/_src/halftone-field/def.mjs +72 -0
  92. package/skills/agentvfx/templates/brutal/_src/halftone-field/main.src.frag +94 -0
  93. package/skills/agentvfx/templates/brutal/_src/hud-deck/deck-left.src.glsl +100 -0
  94. package/skills/agentvfx/templates/brutal/_src/hud-deck/deck-right.src.glsl +61 -0
  95. package/skills/agentvfx/templates/brutal/_src/hud-deck/deck-tiles.src.glsl +153 -0
  96. package/skills/agentvfx/templates/brutal/_src/hud-deck/def.mjs +82 -0
  97. package/skills/agentvfx/templates/brutal/_src/hud-deck/main.src.frag +110 -0
  98. package/skills/agentvfx/templates/brutal/_src/hud-deck/pass0.src.frag +38 -0
  99. package/skills/agentvfx/templates/brutal/_src/shared/defs.mjs +28 -0
  100. package/skills/agentvfx/templates/brutal/_src/shared/icons.glsl +72 -0
  101. package/skills/agentvfx/templates/brutal/_src/shared/lib.glsl +115 -0
  102. package/skills/agentvfx/templates/brutal/_src/shared/screen.glsl +43 -0
  103. package/skills/agentvfx/templates/brutal/boot-log/demo-acid.json +1 -0
  104. package/skills/agentvfx/templates/brutal/boot-log/demo-phosphor.json +1 -0
  105. package/skills/agentvfx/templates/brutal/boot-log/demo-ultramarine.json +1 -0
  106. package/skills/agentvfx/templates/brutal/boot-log/fx.json +257 -0
  107. package/skills/agentvfx/templates/brutal/boot-log/main.frag +242 -0
  108. package/skills/agentvfx/templates/brutal/collage/_src/00-lib.glsl +73 -0
  109. package/skills/agentvfx/templates/brutal/collage/_src/10-spectrum-scope.glsl +73 -0
  110. package/skills/agentvfx/templates/brutal/collage/_src/20-meter-readout-cross.glsl +87 -0
  111. package/skills/agentvfx/templates/brutal/collage/_src/30-footage-fillers.glsl +92 -0
  112. package/skills/agentvfx/templates/brutal/collage/_src/40-editorial.glsl +232 -0
  113. package/skills/agentvfx/templates/brutal/collage/_src/50-typefx.glsl +163 -0
  114. package/skills/agentvfx/templates/brutal/collage/_src/60-scene-lib.glsl +104 -0
  115. package/skills/agentvfx/templates/brutal/collage/_src/61-scene-specimen.glsl +71 -0
  116. package/skills/agentvfx/templates/brutal/collage/_src/62-scene-wiring.glsl +96 -0
  117. package/skills/agentvfx/templates/brutal/collage/_src/63-scene-fieldcut.glsl +119 -0
  118. package/skills/agentvfx/templates/brutal/collage/_src/64-scene-pattern.glsl +64 -0
  119. package/skills/agentvfx/templates/brutal/collage/_src/641-scene-anatomy.glsl +49 -0
  120. package/skills/agentvfx/templates/brutal/collage/_src/642-scene-deck.glsl +78 -0
  121. package/skills/agentvfx/templates/brutal/collage/_src/643-scene-bootlog.glsl +60 -0
  122. package/skills/agentvfx/templates/brutal/collage/_src/644-scene-tunnel.glsl +48 -0
  123. package/skills/agentvfx/templates/brutal/collage/_src/645-scene-runner.glsl +42 -0
  124. package/skills/agentvfx/templates/brutal/collage/_src/646-scene-ascii.glsl +66 -0
  125. package/skills/agentvfx/templates/brutal/collage/_src/647-scene-cubewall.glsl +80 -0
  126. package/skills/agentvfx/templates/brutal/collage/_src/648-scene-vortex.glsl +46 -0
  127. package/skills/agentvfx/templates/brutal/collage/_src/649-scene-sticker.glsl +72 -0
  128. package/skills/agentvfx/templates/brutal/collage/_src/65-scene-main.glsl +1 -0
  129. package/skills/agentvfx/templates/brutal/collage/_src/650-scene-ribbon.glsl +55 -0
  130. package/skills/agentvfx/templates/brutal/collage/_src/651-scene-slab.glsl +38 -0
  131. package/skills/agentvfx/templates/brutal/collage/_src/652-scene-framedial.glsl +79 -0
  132. package/skills/agentvfx/templates/brutal/collage/_src/653-scene-tilt.glsl +40 -0
  133. package/skills/agentvfx/templates/brutal/collage/_src/654-scene-marquee.glsl +45 -0
  134. package/skills/agentvfx/templates/brutal/collage/_src/655-scene-lens.glsl +57 -0
  135. package/skills/agentvfx/templates/brutal/collage/_src/656-scene-liquid.glsl +35 -0
  136. package/skills/agentvfx/templates/brutal/collage/_src/657-scene-panelgrid.glsl +75 -0
  137. package/skills/agentvfx/templates/brutal/collage/_src/658-scene-mirror.glsl +49 -0
  138. package/skills/agentvfx/templates/brutal/collage/_src/66-scene-main.glsl +27 -0
  139. package/skills/agentvfx/templates/brutal/collage/_src/90-main.glsl +120 -0
  140. package/skills/agentvfx/templates/brutal/collage/_src/build.mjs +24 -0
  141. package/skills/agentvfx/templates/brutal/collage/_src/sync-presets.mjs +16 -0
  142. package/skills/agentvfx/templates/brutal/collage/demo-bone-lime.json +1 -0
  143. package/skills/agentvfx/templates/brutal/collage/demo-lime-sparse.json +1 -0
  144. package/skills/agentvfx/templates/brutal/collage/demo-orange-dense.json +1 -0
  145. package/skills/agentvfx/templates/brutal/collage/demo-ultra-slow.json +1 -0
  146. package/skills/agentvfx/templates/brutal/collage/fx.json +4882 -0
  147. package/skills/agentvfx/templates/brutal/collage/layout.mjs +97 -0
  148. package/skills/agentvfx/templates/brutal/collage/layouts.json +366 -0
  149. package/skills/agentvfx/templates/brutal/collage/main.frag +2367 -0
  150. package/skills/agentvfx/templates/brutal/collage/pass0.frag +265 -0
  151. package/skills/agentvfx/templates/brutal/halftone-field/demo-acid.json +1 -0
  152. package/skills/agentvfx/templates/brutal/halftone-field/demo-ascii.json +1 -0
  153. package/skills/agentvfx/templates/brutal/halftone-field/demo-dither.json +1 -0
  154. package/skills/agentvfx/templates/brutal/halftone-field/demo-orange.json +1 -0
  155. package/skills/agentvfx/templates/brutal/halftone-field/demo-phosphor.json +1 -0
  156. package/skills/agentvfx/templates/brutal/halftone-field/demo-ultramarine.json +1 -0
  157. package/skills/agentvfx/templates/brutal/halftone-field/fx.json +474 -0
  158. package/skills/agentvfx/templates/brutal/halftone-field/main.frag +248 -0
  159. package/skills/agentvfx/templates/brutal/hud-deck/demo-acid.json +1 -0
  160. package/skills/agentvfx/templates/brutal/hud-deck/demo-night.json +1 -0
  161. package/skills/agentvfx/templates/brutal/hud-deck/demo-octagon.json +1 -0
  162. package/skills/agentvfx/templates/brutal/hud-deck/demo-ultramarine.json +1 -0
  163. package/skills/agentvfx/templates/brutal/hud-deck/fx.json +601 -0
  164. package/skills/agentvfx/templates/brutal/hud-deck/main.frag +645 -0
  165. package/skills/agentvfx/templates/brutal/hud-deck/pass0.frag +38 -0
  166. package/skills/agentvfx/templates/brutal/lattice/demo-cobalt-fine.json +1 -0
  167. package/skills/agentvfx/templates/brutal/lattice/demo-ink-yellow.json +1 -0
  168. package/skills/agentvfx/templates/brutal/lattice/demo-vermilion.json +1 -0
  169. package/skills/agentvfx/templates/brutal/lattice/demo-violet-slow.json +1 -0
  170. package/skills/agentvfx/templates/brutal/lattice/fx.json +130 -0
  171. package/skills/agentvfx/templates/brutal/lattice/main.frag +175 -0
  172. package/skills/agentvfx/templates/brutal/lattice/pass0.frag +29 -0
  173. package/skills/agentvfx/templates/glitch/block-glitch/demo-mosaic.json +1 -0
  174. package/skills/agentvfx/templates/glitch/block-glitch/demo-onset.json +1 -0
  175. package/skills/agentvfx/templates/glitch/block-glitch/demo-static.json +1 -0
  176. package/skills/agentvfx/templates/glitch/block-glitch/demo-tear.json +1 -0
  177. package/skills/agentvfx/templates/glitch/block-glitch/fx.json +54 -0
  178. package/skills/agentvfx/templates/glitch/block-glitch/main.frag +132 -0
  179. package/skills/agentvfx/templates/glitch/block-glitch/pass0.frag +12 -0
  180. package/skills/agentvfx/templates/glitch/pixel-sort/NOTES.md +13 -0
  181. package/skills/agentvfx/templates/glitch/pixel-sort/build-passes.mjs +162 -0
  182. package/skills/agentvfx/templates/glitch/pixel-sort/demo-chunk.json +1 -0
  183. package/skills/agentvfx/templates/glitch/pixel-sort/demo-hue.json +1 -0
  184. package/skills/agentvfx/templates/glitch/pixel-sort/demo-kick.json +1 -0
  185. package/skills/agentvfx/templates/glitch/pixel-sort/demo-streak.json +1 -0
  186. package/skills/agentvfx/templates/glitch/pixel-sort/demo-vertical.json +1 -0
  187. package/skills/agentvfx/templates/glitch/pixel-sort/fx.json +60 -0
  188. package/skills/agentvfx/templates/glitch/pixel-sort/main.frag +83 -0
  189. package/skills/agentvfx/templates/glitch/pixel-sort/pass0.frag +64 -0
  190. package/skills/agentvfx/templates/glitch/pixel-sort/pass1.frag +66 -0
  191. package/skills/agentvfx/templates/glitch/pixel-sort/pass2.frag +66 -0
  192. package/skills/agentvfx/templates/glitch/pixel-sort/pass3.frag +66 -0
  193. package/skills/agentvfx/templates/glitch/pixel-sort/pass4.frag +66 -0
  194. package/skills/agentvfx/templates/glitch/pixel-sort/pass5.frag +66 -0
  195. package/skills/agentvfx/templates/glitch/pixel-sort/pass6.frag +66 -0
  196. package/skills/agentvfx/templates/glitch/pixel-sort/pass7.frag +66 -0
  197. package/skills/agentvfx/templates/glitch/pixel-sort/pass8.frag +66 -0
  198. package/skills/agentvfx/templates/glitch/rgb-split/demo-diagonal-stutter.json +1 -0
  199. package/skills/agentvfx/templates/glitch/rgb-split/demo-hard.json +1 -0
  200. package/skills/agentvfx/templates/glitch/rgb-split/demo-kick.json +1 -0
  201. package/skills/agentvfx/templates/glitch/rgb-split/demo-radial.json +1 -0
  202. package/skills/agentvfx/templates/glitch/rgb-split/fx.json +46 -0
  203. package/skills/agentvfx/templates/glitch/rgb-split/main.frag +76 -0
  204. package/skills/agentvfx/templates/glitch/vhs/demo-clean.json +1 -0
  205. package/skills/agentvfx/templates/glitch/vhs/demo-crash.json +1 -0
  206. package/skills/agentvfx/templates/glitch/vhs/demo-tape.json +1 -0
  207. package/skills/agentvfx/templates/glitch/vhs/demo-worn.json +1 -0
  208. package/skills/agentvfx/templates/glitch/vhs/fx.json +46 -0
  209. package/skills/agentvfx/templates/glitch/vhs/main.frag +96 -0
  210. package/skills/agentvfx/templates/impact/impact-1bit/demo-onebit-bayer.json +1 -0
  211. package/skills/agentvfx/templates/impact/impact-1bit/fx.json +45 -0
  212. package/skills/agentvfx/templates/impact/impact-1bit/main.frag +64 -0
  213. package/skills/agentvfx/templates/impact/impact-invert/demo-invert-snap.json +1 -0
  214. package/skills/agentvfx/templates/impact/impact-invert/fx.json +37 -0
  215. package/skills/agentvfx/templates/impact/impact-invert/main.frag +44 -0
  216. package/skills/agentvfx/templates/impact/punch-shake/demo-punch-hard.json +1 -0
  217. package/skills/agentvfx/templates/impact/punch-shake/fx.json +36 -0
  218. package/skills/agentvfx/templates/impact/punch-shake/main.frag +62 -0
  219. package/skills/agentvfx/templates/impact/rgb-hit/demo-rgb-slam.json +1 -0
  220. package/skills/agentvfx/templates/impact/rgb-hit/fx.json +39 -0
  221. package/skills/agentvfx/templates/impact/rgb-hit/main.frag +62 -0
  222. package/skills/agentvfx/templates/impact/signal-cut/demo-lime-hold.json +1 -0
  223. package/skills/agentvfx/templates/impact/signal-cut/demo-lime.json +1 -0
  224. package/skills/agentvfx/templates/impact/signal-cut/demo-orange.json +1 -0
  225. package/skills/agentvfx/templates/impact/signal-cut/demo-ultramarine.json +1 -0
  226. package/skills/agentvfx/templates/impact/signal-cut/fx.json +83 -0
  227. package/skills/agentvfx/templates/impact/signal-cut/main.frag +101 -0
  228. package/skills/agentvfx/templates/impact/signal-cut/pass0.frag +68 -0
  229. package/skills/agentvfx/templates/impact/speedline-burst/demo-speed-white.json +1 -0
  230. package/skills/agentvfx/templates/impact/speedline-burst/fx.json +44 -0
  231. package/skills/agentvfx/templates/impact/speedline-burst/main.frag +68 -0
  232. package/skills/agentvfx/templates/impact/strobe-burst/demo-strobe-white-16.json +1 -0
  233. package/skills/agentvfx/templates/impact/strobe-burst/fx.json +42 -0
  234. package/skills/agentvfx/templates/impact/strobe-burst/main.frag +43 -0
  235. package/skills/agentvfx/templates/light/anamorphic-streak/demo-anamorphic-cinema.json +10 -0
  236. package/skills/agentvfx/templates/light/anamorphic-streak/demo-data.json +10 -0
  237. package/skills/agentvfx/templates/light/anamorphic-streak/fx.json +47 -0
  238. package/skills/agentvfx/templates/light/anamorphic-streak/main.frag +45 -0
  239. package/skills/agentvfx/templates/light/anamorphic-streak/pass0.frag +22 -0
  240. package/skills/agentvfx/templates/light/anamorphic-streak/pass1.frag +16 -0
  241. package/skills/agentvfx/templates/light/anamorphic-streak/pass2.frag +16 -0
  242. package/skills/agentvfx/templates/light/anamorphic-streak/pass3.frag +16 -0
  243. package/skills/agentvfx/templates/light/bloom-glow/demo-clip01-low.json +11 -0
  244. package/skills/agentvfx/templates/light/bloom-glow/demo-neon-night.json +10 -0
  245. package/skills/agentvfx/templates/light/bloom-glow/demo-phosphor.json +11 -0
  246. package/skills/agentvfx/templates/light/bloom-glow/fx.json +53 -0
  247. package/skills/agentvfx/templates/light/bloom-glow/main.frag +85 -0
  248. package/skills/agentvfx/templates/light/bloom-glow/pass0.frag +21 -0
  249. package/skills/agentvfx/templates/light/bloom-glow/pass1.frag +50 -0
  250. package/skills/agentvfx/templates/light/bloom-glow/pass2.frag +44 -0
  251. package/skills/agentvfx/templates/light/bloom-glow/pass3.frag +32 -0
  252. package/skills/agentvfx/templates/light/bloom-glow/pass4.frag +48 -0
  253. package/skills/agentvfx/templates/light/bloom-glow/pass5.frag +46 -0
  254. package/skills/agentvfx/templates/light/god-rays/demo-golden-hour.json +10 -0
  255. package/skills/agentvfx/templates/light/god-rays/demo-point-lamp.json +10 -0
  256. package/skills/agentvfx/templates/light/god-rays/fx.json +39 -0
  257. package/skills/agentvfx/templates/light/god-rays/main.frag +54 -0
  258. package/skills/agentvfx/templates/light/lens-flare/demo-clip01-bar.json +11 -0
  259. package/skills/agentvfx/templates/light/lens-flare/demo-eye-bar.json +10 -0
  260. package/skills/agentvfx/templates/light/lens-flare/demo-sun-ghosts.json +10 -0
  261. package/skills/agentvfx/templates/light/lens-flare/fx.json +49 -0
  262. package/skills/agentvfx/templates/light/lens-flare/main.frag +86 -0
  263. package/skills/agentvfx/templates/light/lens-flare/pass0.frag +24 -0
  264. package/skills/agentvfx/templates/light/light-leak/demo-slit.json +10 -0
  265. package/skills/agentvfx/templates/light/light-leak/demo-vintage-burn.json +10 -0
  266. package/skills/agentvfx/templates/light/light-leak/fx.json +40 -0
  267. package/skills/agentvfx/templates/light/light-leak/main.frag +46 -0
  268. package/skills/agentvfx/templates/light/light-stage/fx.json +29 -0
  269. package/skills/agentvfx/templates/light/light-stage/main.frag +56 -0
  270. package/skills/agentvfx/templates/light/light-sweep/demo-hard-bar.json +12 -0
  271. package/skills/agentvfx/templates/light/light-sweep/demo-logo-sweep.json +10 -0
  272. package/skills/agentvfx/templates/light/light-sweep/demo-onset.json +11 -0
  273. package/skills/agentvfx/templates/light/light-sweep/fx.json +45 -0
  274. package/skills/agentvfx/templates/light/light-sweep/main.frag +29 -0
  275. package/skills/agentvfx/templates/light/light-sweep/pass0.frag +17 -0
  276. package/skills/agentvfx/templates/light/light-sweep/pass1.frag +15 -0
  277. package/skills/agentvfx/templates/light/neon-saber/demo-hairline.json +10 -0
  278. package/skills/agentvfx/templates/light/neon-saber/demo-saber-laser.json +10 -0
  279. package/skills/agentvfx/templates/light/neon-saber/fx.json +48 -0
  280. package/skills/agentvfx/templates/light/neon-saber/main.frag +27 -0
  281. package/skills/agentvfx/templates/light/neon-saber/pass0.frag +46 -0
  282. package/skills/agentvfx/templates/light/neon-saber/pass1.frag +15 -0
  283. package/skills/agentvfx/templates/psychedelic/echo-flow/demo-trail.json +1 -0
  284. package/skills/agentvfx/templates/psychedelic/echo-flow/fx.json +38 -0
  285. package/skills/agentvfx/templates/psychedelic/echo-flow/main.frag +19 -0
  286. package/skills/agentvfx/templates/psychedelic/echo-flow/pass0.frag +16 -0
  287. package/skills/agentvfx/templates/psychedelic/echo-flow/pass1.frag +20 -0
  288. package/skills/agentvfx/templates/psychedelic/echo-flow/pass2.frag +11 -0
  289. package/skills/agentvfx/templates/psychedelic/echo-flow/pass3.frag +4 -0
  290. package/skills/agentvfx/templates/psychedelic/hologram-scan/demo-cyan.json +1 -0
  291. package/skills/agentvfx/templates/psychedelic/hologram-scan/fx.json +36 -0
  292. package/skills/agentvfx/templates/psychedelic/hologram-scan/main.frag +30 -0
  293. package/skills/agentvfx/templates/psychedelic/kaleido-fold/demo-six.json +1 -0
  294. package/skills/agentvfx/templates/psychedelic/kaleido-fold/fx.json +37 -0
  295. package/skills/agentvfx/templates/psychedelic/kaleido-fold/main.frag +10 -0
  296. package/skills/agentvfx/templates/psychedelic/kaleido-fold/pass0.frag +34 -0
  297. package/skills/agentvfx/templates/psychedelic/mosh-melt/demo-classic.json +1 -0
  298. package/skills/agentvfx/templates/psychedelic/mosh-melt/fx.json +38 -0
  299. package/skills/agentvfx/templates/psychedelic/mosh-melt/main.frag +20 -0
  300. package/skills/agentvfx/templates/psychedelic/mosh-melt/pass0.frag +22 -0
  301. package/skills/agentvfx/templates/psychedelic/sacred/NOTES.md +13 -0
  302. package/skills/agentvfx/templates/psychedelic/sacred/demo-classic.json +1 -0
  303. package/skills/agentvfx/templates/psychedelic/sacred/demo-halo.json +1 -0
  304. package/skills/agentvfx/templates/psychedelic/sacred/demo-slow-tide.json +1 -0
  305. package/skills/agentvfx/templates/psychedelic/sacred/demo-thermal.json +1 -0
  306. package/skills/agentvfx/templates/psychedelic/sacred/fx.json +263 -0
  307. package/skills/agentvfx/templates/psychedelic/sacred/main.frag +109 -0
  308. package/skills/agentvfx/templates/psychedelic/sacred/pass0.frag +25 -0
  309. package/skills/agentvfx/templates/psychedelic/sacred/pass1.frag +23 -0
  310. package/skills/agentvfx/templates/psychedelic/tidal-bands/demo-classic.json +1 -0
  311. package/skills/agentvfx/templates/psychedelic/tidal-bands/fx.json +37 -0
  312. package/skills/agentvfx/templates/psychedelic/tidal-bands/main.frag +54 -0
  313. package/skills/agentvfx/templates/scope/_chrome.glsl +242 -0
  314. package/skills/agentvfx/templates/scope/goniometer/demo-boot-green.json +1 -0
  315. package/skills/agentvfx/templates/scope/goniometer/demo-field-lime.json +1 -0
  316. package/skills/agentvfx/templates/scope/goniometer/demo-field-ultramarine.json +1 -0
  317. package/skills/agentvfx/templates/scope/goniometer/demo-glow-phosphor.json +1 -0
  318. package/skills/agentvfx/templates/scope/goniometer/demo-hud-black.json +1 -0
  319. package/skills/agentvfx/templates/scope/goniometer/fx.json +635 -0
  320. package/skills/agentvfx/templates/scope/goniometer/main.frag +33 -0
  321. package/skills/agentvfx/templates/scope/goniometer/pass0.frag +58 -0
  322. package/skills/agentvfx/templates/scope/goniometer/pass1.frag +43 -0
  323. package/skills/agentvfx/templates/scope/goniometer/pass2.frag +12 -0
  324. package/skills/agentvfx/templates/scope/goniometer/pass3.frag +12 -0
  325. package/skills/agentvfx/templates/scope/goniometer/pass4.frag +12 -0
  326. package/skills/agentvfx/templates/scope/goniometer/pass5.frag +12 -0
  327. package/skills/agentvfx/templates/scope/goniometer/pass6.frag +251 -0
  328. package/skills/agentvfx/templates/scope/scope-polar/demo-boot-green.json +1 -0
  329. package/skills/agentvfx/templates/scope/scope-polar/demo-field-lime.json +1 -0
  330. package/skills/agentvfx/templates/scope/scope-polar/demo-field-ultramarine.json +1 -0
  331. package/skills/agentvfx/templates/scope/scope-polar/demo-glow-phosphor.json +1 -0
  332. package/skills/agentvfx/templates/scope/scope-polar/demo-hud-black.json +1 -0
  333. package/skills/agentvfx/templates/scope/scope-polar/fx.json +686 -0
  334. package/skills/agentvfx/templates/scope/scope-polar/main.frag +39 -0
  335. package/skills/agentvfx/templates/scope/scope-polar/pass0.frag +84 -0
  336. package/skills/agentvfx/templates/scope/scope-polar/pass1.frag +49 -0
  337. package/skills/agentvfx/templates/scope/scope-polar/pass2.frag +12 -0
  338. package/skills/agentvfx/templates/scope/scope-polar/pass3.frag +12 -0
  339. package/skills/agentvfx/templates/scope/scope-polar/pass4.frag +12 -0
  340. package/skills/agentvfx/templates/scope/scope-polar/pass5.frag +12 -0
  341. package/skills/agentvfx/templates/scope/scope-polar/pass6.frag +251 -0
  342. package/skills/agentvfx/templates/scope/scope-triggered/demo-boot-green.json +1 -0
  343. package/skills/agentvfx/templates/scope/scope-triggered/demo-field-lime.json +1 -0
  344. package/skills/agentvfx/templates/scope/scope-triggered/demo-field-ultramarine.json +1 -0
  345. package/skills/agentvfx/templates/scope/scope-triggered/demo-glow-phosphor.json +1 -0
  346. package/skills/agentvfx/templates/scope/scope-triggered/demo-hud-black.json +1 -0
  347. package/skills/agentvfx/templates/scope/scope-triggered/fx.json +712 -0
  348. package/skills/agentvfx/templates/scope/scope-triggered/main.frag +36 -0
  349. package/skills/agentvfx/templates/scope/scope-triggered/pass0.frag +78 -0
  350. package/skills/agentvfx/templates/scope/scope-triggered/pass1.frag +50 -0
  351. package/skills/agentvfx/templates/scope/scope-triggered/pass2.frag +12 -0
  352. package/skills/agentvfx/templates/scope/scope-triggered/pass3.frag +12 -0
  353. package/skills/agentvfx/templates/scope/scope-triggered/pass4.frag +12 -0
  354. package/skills/agentvfx/templates/scope/scope-triggered/pass5.frag +12 -0
  355. package/skills/agentvfx/templates/scope/scope-triggered/pass6.frag +251 -0
  356. package/skills/agentvfx/templates/scope/spectrogram-scroll/demo-boot-green.json +1 -0
  357. package/skills/agentvfx/templates/scope/spectrogram-scroll/demo-field-lime.json +1 -0
  358. package/skills/agentvfx/templates/scope/spectrogram-scroll/demo-field-ultramarine.json +1 -0
  359. package/skills/agentvfx/templates/scope/spectrogram-scroll/demo-glow-phosphor.json +1 -0
  360. package/skills/agentvfx/templates/scope/spectrogram-scroll/demo-hud-black.json +1 -0
  361. package/skills/agentvfx/templates/scope/spectrogram-scroll/fx.json +595 -0
  362. package/skills/agentvfx/templates/scope/spectrogram-scroll/main.frag +83 -0
  363. package/skills/agentvfx/templates/scope/spectrogram-scroll/pass0.frag +52 -0
  364. package/skills/agentvfx/templates/scope/spectrogram-scroll/pass1.frag +251 -0
  365. package/skills/agentvfx/templates/scope/xy-phosphor/demo-boot-green.json +1 -0
  366. package/skills/agentvfx/templates/scope/xy-phosphor/demo-field-lime.json +1 -0
  367. package/skills/agentvfx/templates/scope/xy-phosphor/demo-field-ultramarine.json +1 -0
  368. package/skills/agentvfx/templates/scope/xy-phosphor/demo-glow-phosphor.json +1 -0
  369. package/skills/agentvfx/templates/scope/xy-phosphor/demo-hud-black.json +1 -0
  370. package/skills/agentvfx/templates/scope/xy-phosphor/fx.json +642 -0
  371. package/skills/agentvfx/templates/scope/xy-phosphor/main.frag +33 -0
  372. package/skills/agentvfx/templates/scope/xy-phosphor/pass0.frag +56 -0
  373. package/skills/agentvfx/templates/scope/xy-phosphor/pass1.frag +44 -0
  374. package/skills/agentvfx/templates/scope/xy-phosphor/pass2.frag +12 -0
  375. package/skills/agentvfx/templates/scope/xy-phosphor/pass3.frag +12 -0
  376. package/skills/agentvfx/templates/scope/xy-phosphor/pass4.frag +12 -0
  377. package/skills/agentvfx/templates/scope/xy-phosphor/pass5.frag +12 -0
  378. package/skills/agentvfx/templates/scope/xy-phosphor/pass6.frag +251 -0
  379. package/skills/agentvfx/templates/spectrum/_src/bars-linear/fx.src.json +61 -0
  380. package/skills/agentvfx/templates/spectrum/_src/bars-linear/main.src.frag +112 -0
  381. package/skills/agentvfx/templates/spectrum/_src/bars-linear/pass0.src.frag +2 -0
  382. package/skills/agentvfx/templates/spectrum/_src/bars-mirror/fx.src.json +51 -0
  383. package/skills/agentvfx/templates/spectrum/_src/bars-mirror/main.src.frag +72 -0
  384. package/skills/agentvfx/templates/spectrum/_src/bars-mirror/pass0.src.frag +2 -0
  385. package/skills/agentvfx/templates/spectrum/_src/bass-circle/fx.src.json +56 -0
  386. package/skills/agentvfx/templates/spectrum/_src/bass-circle/main.src.frag +136 -0
  387. package/skills/agentvfx/templates/spectrum/_src/bass-circle/pass0.src.frag +2 -0
  388. package/skills/agentvfx/templates/spectrum/_src/build.mjs +68 -0
  389. package/skills/agentvfx/templates/spectrum/_src/label-bars/fx.src.json +54 -0
  390. package/skills/agentvfx/templates/spectrum/_src/label-bars/main.src.frag +102 -0
  391. package/skills/agentvfx/templates/spectrum/_src/label-bars/pass0.src.frag +2 -0
  392. package/skills/agentvfx/templates/spectrum/_src/shared/bars-fn.glsl +64 -0
  393. package/skills/agentvfx/templates/spectrum/_src/shared/bars-pass.glsl +22 -0
  394. package/skills/agentvfx/templates/spectrum/_src/shared/clock.glsl +7 -0
  395. package/skills/agentvfx/templates/spectrum/_src/shared/hud.glsl +50 -0
  396. package/skills/agentvfx/templates/spectrum/_src/shared/stage.glsl +74 -0
  397. package/skills/agentvfx/templates/spectrum/_src/spectrum-particles/fx.src.json +58 -0
  398. package/skills/agentvfx/templates/spectrum/_src/spectrum-particles/main.src.frag +119 -0
  399. package/skills/agentvfx/templates/spectrum/_src/spectrum-particles/pass0.src.frag +33 -0
  400. package/skills/agentvfx/templates/spectrum/_src/spectrum-radial/fx.src.json +56 -0
  401. package/skills/agentvfx/templates/spectrum/_src/spectrum-radial/main.src.frag +95 -0
  402. package/skills/agentvfx/templates/spectrum/_src/spectrum-radial/pass0.src.frag +2 -0
  403. package/skills/agentvfx/templates/spectrum/_src/waveform-line/fx.src.json +60 -0
  404. package/skills/agentvfx/templates/spectrum/_src/waveform-line/main.src.frag +98 -0
  405. package/skills/agentvfx/templates/spectrum/_src/waveform-line/pass0.src.frag +43 -0
  406. package/skills/agentvfx/templates/spectrum/bars-linear/demo-graph-acid.json +1 -0
  407. package/skills/agentvfx/templates/spectrum/bars-linear/demo-graph-black.json +1 -0
  408. package/skills/agentvfx/templates/spectrum/bars-linear/fx.json +632 -0
  409. package/skills/agentvfx/templates/spectrum/bars-linear/main.frag +233 -0
  410. package/skills/agentvfx/templates/spectrum/bars-linear/pass0.frag +91 -0
  411. package/skills/agentvfx/templates/spectrum/bars-mirror/demo-field-acid.json +1 -0
  412. package/skills/agentvfx/templates/spectrum/bars-mirror/demo-field-ultramarine.json +1 -0
  413. package/skills/agentvfx/templates/spectrum/bars-mirror/fx.json +539 -0
  414. package/skills/agentvfx/templates/spectrum/bars-mirror/main.frag +193 -0
  415. package/skills/agentvfx/templates/spectrum/bars-mirror/pass0.frag +91 -0
  416. package/skills/agentvfx/templates/spectrum/bass-circle/demo-bracket-black.json +1 -0
  417. package/skills/agentvfx/templates/spectrum/bass-circle/demo-bracket-ultramarine.json +1 -0
  418. package/skills/agentvfx/templates/spectrum/bass-circle/fx.json +552 -0
  419. package/skills/agentvfx/templates/spectrum/bass-circle/main.frag +258 -0
  420. package/skills/agentvfx/templates/spectrum/bass-circle/pass0.frag +91 -0
  421. package/skills/agentvfx/templates/spectrum/label-bars/demo-deck-black.json +1 -0
  422. package/skills/agentvfx/templates/spectrum/label-bars/demo-deck-ultramarine.json +1 -0
  423. package/skills/agentvfx/templates/spectrum/label-bars/fx.json +552 -0
  424. package/skills/agentvfx/templates/spectrum/label-bars/main.frag +223 -0
  425. package/skills/agentvfx/templates/spectrum/label-bars/pass0.frag +91 -0
  426. package/skills/agentvfx/templates/spectrum/spectrum-particles/demo-cloud-black.json +1 -0
  427. package/skills/agentvfx/templates/spectrum/spectrum-particles/demo-cloud-ultramarine.json +1 -0
  428. package/skills/agentvfx/templates/spectrum/spectrum-particles/fx.json +584 -0
  429. package/skills/agentvfx/templates/spectrum/spectrum-particles/main.frag +240 -0
  430. package/skills/agentvfx/templates/spectrum/spectrum-particles/pass0.frag +101 -0
  431. package/skills/agentvfx/templates/spectrum/spectrum-radial/demo-starburst-black.json +1 -0
  432. package/skills/agentvfx/templates/spectrum/spectrum-radial/demo-starburst-ultramarine.json +1 -0
  433. package/skills/agentvfx/templates/spectrum/spectrum-radial/fx.json +566 -0
  434. package/skills/agentvfx/templates/spectrum/spectrum-radial/main.frag +217 -0
  435. package/skills/agentvfx/templates/spectrum/spectrum-radial/pass0.frag +91 -0
  436. package/skills/agentvfx/templates/spectrum/waveform-line/demo-strip-acid.json +1 -0
  437. package/skills/agentvfx/templates/spectrum/waveform-line/demo-strip-black.json +1 -0
  438. package/skills/agentvfx/templates/spectrum/waveform-line/fx.json +481 -0
  439. package/skills/agentvfx/templates/spectrum/waveform-line/main.frag +219 -0
  440. package/skills/agentvfx/templates/spectrum/waveform-line/pass0.frag +48 -0
  441. package/skills/agentvfx/templates/spectrum/waveform-line/pass1.frag +86 -0
  442. package/skills/agentvfx/test/_render_light.mjs +38 -0
  443. package/skills/agentvfx/test/audio-stereo.test.mjs +45 -0
  444. package/skills/agentvfx/test/audio.test.mjs +257 -0
  445. package/skills/agentvfx/test/brutal.test.mjs +190 -0
  446. package/skills/agentvfx/test/concept-collage-layout.test.mjs +236 -0
  447. package/skills/agentvfx/test/concept-collage-scenes.test.mjs +305 -0
  448. package/skills/agentvfx/test/concept-collage-typefx.test.mjs +153 -0
  449. package/skills/agentvfx/test/concept-collage.test.mjs +84 -0
  450. package/skills/agentvfx/test/concept-lattice.test.mjs +133 -0
  451. package/skills/agentvfx/test/concept-signal-cut.test.mjs +172 -0
  452. package/skills/agentvfx/test/credit-overlay.test.mjs +58 -0
  453. package/skills/agentvfx/test/credit.test.mjs +42 -0
  454. package/skills/agentvfx/test/doctor.test.mjs +31 -0
  455. package/skills/agentvfx/test/encode.test.mjs +22 -0
  456. package/skills/agentvfx/test/fixtures/r7-collage-LAYOUTS.json +5780 -0
  457. package/skills/agentvfx/test/fixtures/score-bad-duration.json +7 -0
  458. package/skills/agentvfx/test/fixtures/score-bad-safety.json +8 -0
  459. package/skills/agentvfx/test/fixtures/score-identity-footage.json +8 -0
  460. package/skills/agentvfx/test/fixtures/score-missing-template.json +7 -0
  461. package/skills/agentvfx/test/fixtures/score-ok.json +8 -0
  462. package/skills/agentvfx/test/fixtures/score-strobe-12hz.json +8 -0
  463. package/skills/agentvfx/test/fixtures/score-text-probe.json +1 -0
  464. package/skills/agentvfx/test/flash-audit.test.mjs +150 -0
  465. package/skills/agentvfx/test/flash.test.mjs +83 -0
  466. package/skills/agentvfx/test/footage.test.mjs +88 -0
  467. package/skills/agentvfx/test/glitch.test.mjs +272 -0
  468. package/skills/agentvfx/test/impact.test.mjs +231 -0
  469. package/skills/agentvfx/test/imports.test.mjs +39 -0
  470. package/skills/agentvfx/test/light.test.mjs +200 -0
  471. package/skills/agentvfx/test/loop.test.mjs +80 -0
  472. package/skills/agentvfx/test/psychedelic.test.mjs +99 -0
  473. package/skills/agentvfx/test/render.test.mjs +73 -0
  474. package/skills/agentvfx/test/sacred.test.mjs +175 -0
  475. package/skills/agentvfx/test/schema.test.mjs +103 -0
  476. package/skills/agentvfx/test/scope.test.mjs +306 -0
  477. package/skills/agentvfx/test/spectrum.test.mjs +165 -0
  478. package/skills/agentvfx/test/text.test.mjs +142 -0
  479. package/skills/agentvfx/test/web.test.mjs +397 -0
  480. package/skills/agentvfx/test-media/SOURCES.md +39 -0
  481. package/skills/agentvfx/test-media/beat-132.mp3 +0 -0
  482. package/skills/agentvfx/test-media/clip-01.mp4 +0 -0
  483. package/skills/agentvfx/test-media/clip-02.mp4 +0 -0
@@ -0,0 +1,72 @@
1
+ // bars-mirror main: the full-frame FIELD version. One saturated field colour (acid lime / ultramarine /
2
+ // signal orange / phosphor green on black) with black or white ink: a four-way mirrored spectrum of tiny
3
+ // hairline bars growing up and down from a centre slit (low frequencies meet in the middle), tip dots,
4
+ // a dashed centre axis with a tick ruler and numerals, an inset frame with corner brackets and + marks,
5
+ // and engine-text labels. mirrorMode 0 = four-way, 1 = full-width mirrored top / bottom, 2 = centre-out
6
+ // growing up from the floor. A strong onset (hitFlux) swaps field and ink for ~3 frames: the hard cut.
7
+ //@include stage.glsl
8
+ //@include hud.glsl
9
+
10
+ vec4 barAt(int i) { return texelFetch(barState, ivec2(clamp(i, 0, bandCount - 1), 0), 0); }
11
+
12
+ void main() {
13
+ vec2 res = RENDERSIZE;
14
+ float U = hudU();
15
+ vec4 clk = texelFetch(barState, ivec2(0, 1), 0);
16
+ vec2 sp = vUv * res;
17
+ vec2 uv = stageUv(clk, vUv);
18
+ vec2 px = uv * res;
19
+ float n = float(bandCount);
20
+ float cx = res.x * 0.5;
21
+ float halfW = res.x * 0.42;
22
+ float pitch = mirrorMode == 1 ? res.x * 0.84 / n : halfW / n;
23
+ float coordX = mirrorMode == 1 ? px.x - res.x * 0.08 : abs(px.x - cx) - centreGap * res.x;
24
+ float fi = floor(coordX / pitch);
25
+ int i = int(clamp(fi, 0.0, n - 1.0));
26
+ float span = introSpan();
27
+ bool inSpan = fi >= 0.0 && fi < n && abs(uv.x - 0.5) * 2.0 < span * 0.86 + 0.001;
28
+ float lx = coordX - (fi + 0.5) * pitch;
29
+ float hwBar = max(hudW() * 0.5, pitch * thickness * 0.5);
30
+ float baseY = mirrorMode == 2 ? 0.1 * res.y : 0.5 * res.y;
31
+ float dy = mirrorMode == 2 ? px.y - baseY : abs(px.y - baseY) - 1.5 * U;
32
+ float extent = res.y * (mirrorMode == 2 ? 0.74 : 0.36) * maxHeight * introK();
33
+ vec4 bar = barAt(i);
34
+ float hj = bar.r * extent + floorHeight * U;
35
+ float body = inSpan ? cov(abs(lx) - hwBar) * step(-0.5, dy) * cov(dy - hj) : 0.0;
36
+ float tipY = hj + 3.5 * U;
37
+ float tip = inSpan && tipDots ? cov(length(vec2(lx, dy - tipY)) - 1.5 * U) * step(0.012, bar.r) : 0.0;
38
+ float capY = bar.g * extent + 6.0 * U;
39
+ float cap = inSpan && bar.g * extent > hj + 8.0 * U ? cov(abs(dy - capY) - 0.7 * U) * cov(abs(lx) - hwBar * 1.8) : 0.0;
40
+
41
+ float axis = mirrorMode == 2 ? 0.0 : hair(px.y - baseY) * dashes(px.x, 10.0, 0.5) * step(abs(uv.x - 0.5) * 2.0, span * 0.92);
42
+ float tickX = abs(fract(coordX / (pitch * 4.0) + 0.5) - 0.5) * pitch * 4.0;
43
+ float tl = (mod(fi, 16.0) < 0.5 ? 14.0 : 6.0) * U;
44
+ float rd = mirrorMode == 2 ? 14.0 * U - px.y : abs(px.y - baseY) - extent * 1.06 - 6.0 * U;
45
+ float rtick = inSpan && rd > 0.0 && rd < tl && tickX < hudW() * 0.6 ? 1.0 : 0.0;
46
+
47
+ float rowsG = 0.0;
48
+ for (int r = 1; r <= 3; r++) {
49
+ float yr = baseY + float(r) * extent / 3.0;
50
+ float yr2 = baseY - float(r) * extent / 3.0;
51
+ rowsG = max(rowsG, max(hair(px.y - yr), mirrorMode == 2 ? 0.0 : hair(px.y - yr2)));
52
+ }
53
+ rowsG *= dashes(px.x, 8.0, 0.25) * step(abs(uv.x - 0.5) * 2.0, span * 0.92) * 0.55;
54
+
55
+ vec2 flo = vec2(0.035 * res.x, 0.05 * res.y);
56
+ vec2 fhi = vec2(0.965 * res.x, 0.95 * res.y);
57
+ float frame = boxLine(sp, flo, fhi) * 0.8 + brackets(sp, flo - 8.0 * U, fhi + 8.0 * U, 26.0 * U);
58
+ vec2 qc = abs(sp - res * 0.5);
59
+ float plus = max(hair(qc.y) * step(qc.x, 12.0 * U), hair(qc.x) * step(qc.y, 12.0 * U));
60
+
61
+ float m = max(max(body, tip), max(cap, max(axis * 0.9, rtick * 0.9)));
62
+ m = max(m, rowsG * gridAmount);
63
+ m = max(m, max(frame * gridAmount, plus * float(marks)));
64
+ m = max(m, textInk());
65
+ vec3 gnd = stageBackground(vUv, inkColor.rgb, kickEnv(clk));
66
+ float hit = step(0.5, hitEnv(clk, max(flashDecayMs * 0.001, 0.001))) * step(0.5, clk.x) * invertHit;
67
+ vec3 ink = inkColor.rgb;
68
+ vec3 straight = mix(gnd, mix(ink, accentAt((fi + 0.5) / n), min(cap + tip, 1.0)), m);
69
+ vec3 swapped = mix(ink, gnd, m);
70
+ vec3 col = mix(straight, swapped, hit);
71
+ fragColor = vec4(stageFinish(col, vUv), 1.0);
72
+ }
@@ -0,0 +1,2 @@
1
+ // bars-mirror pass 0: pro-motion bar state (see the shared block below), persistent in barState.
2
+ //@include bars-pass.glsl
@@ -0,0 +1,56 @@
1
+ {
2
+ "DESCRIPTION": "Thin-line bracketed bass instrument: up to eight nested hairline outlines (delayed, exponent-stepped) around a halftone emblem disc, hatch fill, tick ring and corner brackets",
3
+ "CREDIT": "agentvfx",
4
+ "ISFVSN": "2",
5
+ "CATEGORIES": ["spectrum", "audio", "hud"],
6
+ "INPUTS": [
7
+ { "NAME": "bandCount", "TYPE": "long", "MIN": 8, "MAX": 64, "DEFAULT": 26 },
8
+ { "NAME": "layerCount", "TYPE": "long", "MIN": 1, "MAX": 8, "DEFAULT": 8 },
9
+ { "NAME": "layerDelay", "TYPE": "long", "MIN": 1, "MAX": 3, "DEFAULT": 2 },
10
+ { "NAME": "emblemRadius", "TYPE": "float", "MIN": 0.06, "MAX": 0.3, "DEFAULT": 0.15 },
11
+ { "NAME": "emblemBounce", "TYPE": "float", "MIN": 0, "MAX": 0.5, "DEFAULT": 0.1 },
12
+ { "NAME": "emblemShake", "TYPE": "float", "MIN": 0, "MAX": 24, "DEFAULT": 0 },
13
+ { "NAME": "maxRadius", "TYPE": "float", "MIN": 0.05, "MAX": 0.45, "DEFAULT": 0.15 },
14
+ { "NAME": "bandGap", "TYPE": "float", "MIN": 0, "MAX": 0.03, "DEFAULT": 0.009 },
15
+ { "NAME": "hatchAmount", "TYPE": "float", "MIN": 0, "MAX": 1, "DEFAULT": 0.55 },
16
+ { "NAME": "spin", "TYPE": "float", "MIN": -3, "MAX": 3, "DEFAULT": 0.1 },
17
+ { "NAME": "snapDeg", "TYPE": "float", "MIN": 0, "MAX": 90, "DEFAULT": 10 },
18
+ { "NAME": "coneAmount", "TYPE": "float", "MIN": 0, "MAX": 1, "DEFAULT": 0.8 },
19
+ { "NAME": "coneCount", "TYPE": "long", "MIN": 0, "MAX": 160, "DEFAULT": 90 },
20
+ { "NAME": "coneSpeed", "TYPE": "float", "MIN": 0.05, "MAX": 2, "DEFAULT": 0.25 }
21
+ ],
22
+ "use": ["pro", "stage", "hud"],
23
+ "defaults": { "startFreq": 30, "endFreq": 300, "freqCurve": 1, "floorLevel": 0.34, "ceilLevel": 0.6, "expLow": 1.5, "expHigh": 1.5, "headBars": 0, "monsterSmooth": 1.2, "attackMs": 10, "releaseMs": 110, "bassHold": 0, "kickBass": 1.4, "glowRadius": 0.02 },
24
+ "PASSES": [
25
+ { "TARGET": "barState", "PERSISTENT": true, "FLOAT": true },
26
+ {}
27
+ ],
28
+ "X_AGENTVFX": {
29
+ "id": "bass-circle",
30
+ "family": "spectrum",
31
+ "input": "either",
32
+ "spdx": "LicenseRef-agentvfx",
33
+ "flash": "none",
34
+ "fps": 30,
35
+ "palette": true,
36
+ "presets": {
37
+ "bracket-black": {},
38
+ "bracket-ultramarine": { "$field": "ultramarine" },
39
+ "bracket-orange": { "$field": "orange", "layerCount": 6 },
40
+ "bracket-acid": { "$field": "acid", "hatchAmount": 0.8 },
41
+ "rainbow-glow": { "colorMode": 1, "glow": 1.6, "lineWidth": 2.6, "hatchAmount": 0.2 }
42
+ },
43
+ "audioBind": { "emblemBounce": "bass" },
44
+ "safeSubstitute": { "params": { "kickZoom": 0, "shake": 0, "emblemShake": 0, "snapDeg": 0 } },
45
+ "text": [
46
+ { "key": "title", "default": "BASS 30-300HZ", "x": 0.03, "y": 0.06, "size": 0.07, "font": "display", "style": "outline", "box": "tab" },
47
+ { "key": "node", "default": "NODE 7G-75", "x": 0.97, "y": 0.045, "size": 0.085, "font": "tall", "align": "right" },
48
+ { "key": "log", "default": "KICK GATE 1.4\nLAYERS 8 DELAY 2F\nCACHE OK", "x": 0.03, "y": 0.8, "size": 0.017, "font": "mono", "reveal": "type", "revealStart": 0.2, "revealDur": 1.5 },
49
+ { "key": "num", "default": "KX 7G2 R4 D9\n41A TQP 118 3", "x": 0.97, "y": 0.9, "size": 0.016, "font": "mono", "align": "right" }
50
+ ],
51
+ "credits": [
52
+ "Thin-line bracketed radial instrument: original drawing, no marks, fonts or text from other works",
53
+ "Layer delays, exponents and smoothing margins follow the parameters published in the open caseif/js.nation recreation (MIT; values described, no code used)"
54
+ ]
55
+ }
56
+ }
@@ -0,0 +1,136 @@
1
+ // bass-circle main: a thin-line bracketed bass instrument. Only the bass band (startFreq..endFreq, 30..300
2
+ // Hz by default) is analysed, so the shape moves on real kicks only. Up to eight nested hairline outlines
3
+ // are drawn: outline s shows the bass spectrum delayed by s * layerDelay frames, raised to its own exponent
4
+ // [1, 1.12, 1.14, 1.30, 1.33, 1.36, 1.50, 1.52] and smoothed with a triangular kernel of its own width
5
+ // [0, 2, 2, 3, 3, 3, 5, 5]; radii are kept nested (bandGap) and older outlines are dimmer. The shape is
6
+ // mirrored left / right about an axis that snaps on every kick. Between the inner disc and the newest
7
+ // outline a radial dash hatch (hatchAmount) fills the shape. The centre disc is a hairline circle holding
8
+ // the input as a one-tone halftone (or, without footage, a ring + cross mark) that bounces and shakes with
9
+ // the bass. Around it: a square bracket frame that breathes with the kick, + marks at the cardinal points,
10
+ // a tick ring and a ring of fine dots (the particle cone as one-pixel dots streaming outward).
11
+ //@include stage.glsl
12
+ //@include hud.glsl
13
+ const float TAU = 6.28318530718;
14
+ const float EXP[8] = float[8](1.0, 1.12, 1.14, 1.30, 1.33, 1.36, 1.50, 1.52);
15
+
16
+ float histAt(int i, int d) { return texelFetch(barState, ivec2(clamp(i, 0, bandCount - 1), d == 0 ? 0 : 3 + d), 0).r; }
17
+
18
+ float sampleAt(float fx, int d) {
19
+ float x = clamp(fx, 0.0, float(bandCount - 1));
20
+ int i0 = int(floor(x));
21
+ float t = x - float(i0);
22
+ return mix(histAt(i0, d), histAt(i0 + 1, d), t * t * (3.0 - 2.0 * t));
23
+ }
24
+
25
+ float layerHeight(float fx, int d, int mg) {
26
+ float s = 0.0;
27
+ float ws = 0.0;
28
+ for (int k = -5; k <= 5; k++) {
29
+ if (abs(k) > mg) { continue; }
30
+ float w = float(mg + 1 - abs(k));
31
+ s += w * sampleAt(fx + float(k), d);
32
+ ws += w;
33
+ }
34
+ return s / ws;
35
+ }
36
+
37
+ void main() {
38
+ vec2 res = RENDERSIZE;
39
+ float U = hudU();
40
+ float px1 = 1.0 / res.y;
41
+ float u1 = 1.0 / 1080.0;
42
+ vec4 clk = texelFetch(barState, ivec2(0, 1), 0);
43
+ vec2 sp = vUv * res;
44
+ vec2 uv = stageUv(clk, vUv);
45
+ float ke = kickEnv(clk);
46
+ float since = stageSince(clk.z, clk.w);
47
+ vec2 p = (uv * res - res * 0.5) * px1;
48
+ vec2 sh = (hash22(vec2(clk.z, 9.1)) - 0.5) * 2.0 * emblemShake * ke * u1;
49
+ vec2 pe = p - sh;
50
+ float r = length(p);
51
+ float rot = TIME * spin + (clk.z > 0.5 ? radians(snapDeg) * (clk.z - exp(-since / 0.07)) : 0.0);
52
+ float a = atan(p.x, p.y) - rot;
53
+ a = mod(a + 3.14159265, TAU) - 3.14159265;
54
+ float fm = abs(a) / 3.14159265 * float(bandCount - 1);
55
+ float grow = introK();
56
+ float Re = emblemRadius * (1.0 + emblemBounce * ke) * (0.3 + 0.7 * introSpan());
57
+ float R0 = Re * 1.06 + 0.006;
58
+ float wU = hudW() * px1;
59
+
60
+ float radii[8];
61
+ float prevR = R0;
62
+ for (int s = 0; s < 8; s++) {
63
+ if (s >= layerCount) { break; }
64
+ int mg = s == 0 ? 0 : (s < 3 ? 2 : (s < 6 ? 3 : 5));
65
+ float A = layerHeight(fm, s * layerDelay, mg);
66
+ float rs = R0 + max(maxRadius * pow(A, EXP[s]), 0.0) * grow;
67
+ rs = max(rs, prevR + (s == 0 ? 0.0 : bandGap * grow));
68
+ radii[s] = rs;
69
+ prevR = rs;
70
+ }
71
+ float outlines = 0.0;
72
+ for (int s = 7; s >= 0; s--) {
73
+ if (s >= layerCount) { continue; }
74
+ float al = s == 0 ? 1.0 : max(0.62 - 0.08 * float(s), 0.18);
75
+ outlines = max(outlines, hair((r - radii[s]) / px1) * al);
76
+ }
77
+ float newest = radii[0];
78
+ float hatch = step(R0, r) * step(r, newest) * step(0.5, fract(a / TAU * 180.0 * (1.0 + 0.0))) * step(0.5, fract(r / (7.0 * u1))) * hatchAmount;
79
+
80
+ float de = length(pe) - Re;
81
+ float disc = hair(de / px1);
82
+ float emblem;
83
+ if (HAS_INPUT) {
84
+ float c = cos(rot * 0.5);
85
+ float sn = sin(rot * 0.5);
86
+ vec2 q = vec2(0.5) + (mat2(c, -sn, sn, c) * pe / Re) * 0.275 * vec2(res.y / res.x, 1.0);
87
+ float cell = max(halftoneSize * 0.7 * U, 2.0);
88
+ vec2 g = (q * res) / cell;
89
+ vec2 fr = fract(g) - 0.5;
90
+ float L = luma(texture(inputImage, (floor(g) + 0.5) * cell / res).rgb);
91
+ emblem = cov((length(fr) - 0.6 * sqrt(clamp(L * 1.2, 0.0, 1.0))) * cell) * step(de, 0.0);
92
+ } else {
93
+ float lr = length(pe) / Re;
94
+ float ca = cos(rot);
95
+ float sa = sin(rot);
96
+ vec2 qq = mat2(ca, -sa, sa, ca) * pe / Re;
97
+ float crossA = max(hair(qq.y * Re / px1) * step(abs(qq.x), 0.5), hair(qq.x * Re / px1) * step(abs(qq.y), 0.5));
98
+ emblem = max(hair((lr - 0.6) * Re / px1) * 0.8, crossA) * step(de, 0.0);
99
+ }
100
+
101
+ float half0 = 0.44 * (1.0 + 0.03 * ke);
102
+ vec2 flo = res * 0.5 - half0 * res.y;
103
+ vec2 fhi = res * 0.5 + half0 * res.y;
104
+ float brk = brackets(sp, flo, fhi, 34.0 * U) * gridAmount;
105
+ float plus = 0.0;
106
+ for (int c = 0; c < 4; c++) {
107
+ vec2 dir = c == 0 ? vec2(1.0, 0.0) : (c == 1 ? vec2(-1.0, 0.0) : (c == 2 ? vec2(0.0, 1.0) : vec2(0.0, -1.0)));
108
+ plus = max(plus, plusAt(sp, res * 0.5 + dir * (half0 + 0.025) * res.y, 7.0 * U));
109
+ }
110
+ float tickCnt = 90.0;
111
+ float tkd = abs(fract(a / TAU * tickCnt) - 0.5) * (TAU * 0.46 / tickCnt);
112
+ float ticks = step(abs(r - 0.46), 0.007 * (mod(floor(a / TAU * tickCnt), 5.0) < 0.5 ? 1.5 : 1.0)) * cov((tkd - wU * 0.5) / px1) * gridAmount;
113
+ float outerDash = hair((r - 0.43) / px1) * dashes(a * 0.43 / px1, 8.0, 0.4) * gridAmount;
114
+
115
+ float cone = 0.0;
116
+ for (int k = 0; k < 160; k++) {
117
+ if (k >= coneCount) { break; }
118
+ vec3 h = vec3(hash12(vec2(float(k), 1.7)), hash12(vec2(float(k), 4.3)), hash12(vec2(float(k), 8.9)));
119
+ float z = fract(TIME * coneSpeed * (1.0 + 0.8 * ke) * (0.5 + h.y) + h.z);
120
+ vec2 pos = vec2(cos(h.x * TAU), sin(h.x * TAU)) * (prevR + 0.02 + z * z * 0.5);
121
+ cone = max(cone, cov((length(p - pos) - (0.7 + 1.6 * z) * u1) / px1) * smoothstep(0.0, 0.1, z) * smoothstep(1.0, 0.7, z));
122
+ }
123
+
124
+ float mk = max(max(outlines, hatch), max(disc, emblem));
125
+ mk = max(mk, max(brk, max(plus * float(marks), max(ticks * 0.8, outerDash * 0.6))));
126
+ mk = max(mk, cone * coneAmount);
127
+ mk = max(mk, textInk());
128
+ vec3 ink = inkColor.rgb;
129
+ vec3 gnd = stageBackground(vUv, ink, ke);
130
+ vec3 col = mix(gnd, ink, mk);
131
+ float hot = hair((r - radii[0]) / px1);
132
+ vec3 acc = colorMode == 1 ? paletteCycle(clamp(a / TAU + 0.5, 0.0, 1.0) + paletteShift) : accentColor.rgb;
133
+ col = mix(col, acc, hot * 0.9);
134
+ col += acc * exp(-max(r - prevR, 0.0) / max(glowRadius, px1)) * glow * 0.3 * step(R0, r);
135
+ fragColor = vec4(stageFinish(col, vUv), 1.0);
136
+ }
@@ -0,0 +1,2 @@
1
+ // bass-circle pass 0: bass-band pro-motion bars plus a shift register of past bar rows (one delayed copy per layer).
2
+ //@include bars-pass.glsl
@@ -0,0 +1,68 @@
1
+ // Spectrum family build: templates share one GLSL "pro motion" stage and one "label stage" (camera,
2
+ // background, particle field, finish), and GLSL has no #include, so the sources live in _src/ and
3
+ // this script writes the standalone template folders. Run: node templates/spectrum/_src/build.mjs
4
+ // (the folder name starts with "_", so the template loader never treats _src as a template).
5
+ import { mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
6
+ import path from "node:path";
7
+ import { fileURLToPath } from "node:url";
8
+
9
+ const SRC = path.dirname(fileURLToPath(import.meta.url));
10
+ const OUT = path.resolve(SRC, "..");
11
+ const f = (NAME, MIN, MAX, DEFAULT) => ({ NAME, TYPE: "float", MIN, MAX, DEFAULT });
12
+
13
+ /** Pro motion stage: bin mapping, peak-preserving smoothing, per-bar exponent, head margin, attack / release, caps. */
14
+ const PRO = [
15
+ f("startFreq", 10, 2000, 40), f("endFreq", 100, 20000, 14000), f("freqCurve", 1, 4, 2.2),
16
+ f("floorLevel", 0, 0.6, 0.2), f("ceilLevel", 0.2, 1, 0.62), f("expLow", 0.5, 8, 2.1), f("expHigh", 0.5, 8, 1.3),
17
+ f("monsterSmooth", 1.05, 3, 1.55), f("headBars", 0, 0.4, 0.12), f("headMin", 0, 1, 0.7), f("tilt", 0, 0.1, 0.02),
18
+ f("attackMs", 1, 300, 14), f("releaseMs", 20, 1500, 150), f("bassHold", 0, 3, 0.8),
19
+ f("capGravity", 0.1, 8, 2.2), f("capHoldMs", 0, 600, 90),
20
+ ];
21
+ /** Stage: kick zoom, shake, background mode, flecks, vignette, grain, intro, hit thresholds. */
22
+ const STAGE = [
23
+ f("kickZoom", 0, 0.15, 0), f("kickDecayMs", 30, 600, 120), f("kickBass", 0, 6, 1.6), f("shake", 0, 24, 0),
24
+ { NAME: "bgMode", TYPE: "long", MIN: 0, MAX: 2, VALUES: [0, 1, 2], LABELS: ["flat", "blurred-footage", "halftone-footage"], DEFAULT: 2 },
25
+ f("bgDim", 0, 1, 0.16), f("halftoneSize", 3, 24, 7), f("fieldAmount", 0, 1, 0), f("fieldSpeed", 0, 4, 1),
26
+ f("vignette", 0, 1, 0), f("grain", 0, 0.12, 0.02), f("introMs", 0, 2000, 500), f("hitFlux", 0, 2, 0.9),
27
+ ];
28
+ /** HUD ground / ink / accent, hairline width, optional palette accent and glow. */
29
+ const HUD = [
30
+ { NAME: "groundColor", TYPE: "color", DEFAULT: [0.043, 0.043, 0.047, 1] },
31
+ { NAME: "inkColor", TYPE: "color", DEFAULT: [0.914, 0.914, 0.894, 1] },
32
+ { NAME: "accentColor", TYPE: "color", DEFAULT: [0.784, 1, 0, 1] },
33
+ f("lineWidth", 0.8, 4, 1.5), f("gridAmount", 0, 1, 1),
34
+ { NAME: "colorMode", TYPE: "long", MIN: 0, MAX: 1, VALUES: [0, 1], LABELS: ["accent", "palette-by-frequency"], DEFAULT: 0 },
35
+ f("paletteShift", 0, 1, 0), f("glow", 0, 3, 0), f("glowRadius", 0.002, 0.1, 0.012),
36
+ { NAME: "marks", TYPE: "bool", DEFAULT: true },
37
+ ];
38
+
39
+ const SHARED = { pro: PRO, stage: STAGE, hud: HUD };
40
+ /** Full-frame field looks, merged into any preset that names one with "$field". */
41
+ const dark = [0.04, 0.04, 0.04, 1];
42
+ const FIELDS = {
43
+ acid: { groundColor: [0.784, 1, 0, 1], inkColor: dark, accentColor: dark },
44
+ ultramarine: { groundColor: [0.078, 0.078, 1, 1], inkColor: [0.95, 0.95, 0.92, 1], accentColor: [1, 1, 1, 1] },
45
+ orange: { groundColor: [1, 0.235, 0, 1], inkColor: dark, accentColor: dark },
46
+ phosphor: { groundColor: [0.02, 0.03, 0.02, 1], inkColor: [0.224, 1, 0.078, 1], accentColor: [0.224, 1, 0.078, 1] },
47
+ };
48
+ const resolvePresets = (presets) => Object.fromEntries(Object.entries(presets).map(([name, { $field, ...rest }]) => [name, $field ? { ...FIELDS[$field], ...rest } : rest]));
49
+ const include = (text) => text.replace(/^\/\/@include (\S+)\s*$/gmu, (_, name) => include(readFileSync(path.join(SRC, "shared", name), "utf8").trimEnd()));
50
+
51
+ for (const id of readdirSync(SRC)) {
52
+ const dir = path.join(SRC, id);
53
+ let src;
54
+ try {
55
+ src = JSON.parse(readFileSync(path.join(dir, "fx.src.json"), "utf8"));
56
+ } catch {
57
+ continue;
58
+ }
59
+ const { use = [], defaults = {}, ...fx } = src;
60
+ fx.INPUTS = [...fx.INPUTS, ...use.flatMap((k) => SHARED[k])].map((input) => (input.NAME in defaults ? { ...input, DEFAULT: defaults[input.NAME] } : input));
61
+ fx.X_AGENTVFX.presets = resolvePresets(fx.X_AGENTVFX.presets);
62
+ const out = path.join(OUT, id);
63
+ mkdirSync(out, { recursive: true });
64
+ writeFileSync(path.join(out, "fx.json"), `${JSON.stringify(fx, null, 2)}\n`);
65
+ for (const file of readdirSync(dir).filter((n) => n.endsWith(".src.frag"))) {
66
+ writeFileSync(path.join(out, file.replace(".src.frag", ".frag")), include(readFileSync(path.join(dir, file), "utf8")));
67
+ }
68
+ }
@@ -0,0 +1,54 @@
1
+ {
2
+ "DESCRIPTION": "Deck layout: outlined tab-box labels, icon row and starburst on the left, a framed panel of 63 hairline bars on a ruler baseline, tall title, halftone footage backdrop",
3
+ "CREDIT": "agentvfx",
4
+ "ISFVSN": "2",
5
+ "CATEGORIES": ["spectrum", "audio", "hud"],
6
+ "INPUTS": [
7
+ { "NAME": "bandCount", "TYPE": "long", "MIN": 16, "MAX": 96, "DEFAULT": 63 },
8
+ { "NAME": "maxHeight", "TYPE": "float", "MIN": 0.1, "MAX": 1, "DEFAULT": 1 },
9
+ { "NAME": "thickness", "TYPE": "float", "MIN": 0.05, "MAX": 1, "DEFAULT": 0.34 },
10
+ { "NAME": "floorHeight", "TYPE": "float", "MIN": 0, "MAX": 10, "DEFAULT": 2 }
11
+ ],
12
+ "use": ["pro", "stage", "hud"],
13
+ "defaults": { "freqCurve": 2.5, "expLow": 2.4, "expHigh": 1.4, "monsterSmooth": 1.5, "releaseMs": 170, "bgDim": 0.2, "halftoneSize": 8 },
14
+ "PASSES": [
15
+ { "TARGET": "barState", "PERSISTENT": true, "FLOAT": true },
16
+ {}
17
+ ],
18
+ "X_AGENTVFX": {
19
+ "id": "label-bars",
20
+ "family": "spectrum",
21
+ "input": "either",
22
+ "spdx": "LicenseRef-agentvfx",
23
+ "flash": "none",
24
+ "fps": 30,
25
+ "palette": true,
26
+ "presets": {
27
+ "deck-black": {},
28
+ "deck-ultramarine": { "$field": "ultramarine", "thickness": 0.45 },
29
+ "deck-acid": { "$field": "acid" },
30
+ "deck-orange": { "$field": "orange", "bandCount": 48 },
31
+ "rainbow-glow": { "colorMode": 1, "glow": 1.2, "lineWidth": 2.4 }
32
+ },
33
+ "audioBind": { "thickness": "bass" },
34
+ "safeSubstitute": { "params": { "kickZoom": 0, "shake": 0 } },
35
+ "text": [
36
+ { "key": "artist", "default": "AGENT//VFX", "x": 0.03, "y": 0.07, "size": 0.062, "font": "display", "style": "outline", "box": "tab" },
37
+ { "key": "track", "default": "SIGNAL 04", "x": 0.03, "y": 0.21, "size": 0.062, "font": "display", "style": "outline", "box": "tab" },
38
+ { "key": "title", "default": "NODE 7G-75", "x": 0.97, "y": 0.04, "size": 0.085, "font": "tall", "align": "right" },
39
+ { "key": "n0", "default": "0", "x": 0.269, "y": 0.83, "size": 0.015, "font": "mono", "align": "center" },
40
+ { "key": "n1", "default": "8", "x": 0.354, "y": 0.83, "size": 0.015, "font": "mono", "align": "center" },
41
+ { "key": "n2", "default": "16", "x": 0.44, "y": 0.83, "size": 0.015, "font": "mono", "align": "center" },
42
+ { "key": "n3", "default": "24", "x": 0.525, "y": 0.83, "size": 0.015, "font": "mono", "align": "center" },
43
+ { "key": "n4", "default": "32", "x": 0.61, "y": 0.83, "size": 0.015, "font": "mono", "align": "center" },
44
+ { "key": "n5", "default": "40", "x": 0.695, "y": 0.83, "size": 0.015, "font": "mono", "align": "center" },
45
+ { "key": "n6", "default": "48", "x": 0.781, "y": 0.83, "size": 0.015, "font": "mono", "align": "center" },
46
+ { "key": "n7", "default": "56", "x": 0.866, "y": 0.83, "size": 0.015, "font": "mono", "align": "center" },
47
+ { "key": "log", "default": "KX 7G2 R4 D9 41A TQP 118\nBARS 63 20-12000HZ CACHE OK", "x": 0.03, "y": 0.9, "size": 0.015, "font": "mono", "reveal": "type", "revealStart": 0.3, "revealDur": 1.6 }
48
+ ],
49
+ "credits": [
50
+ "Index-card outlined labels, level meter and framed instrument panels: original drawing, no marks, fonts or text from other works",
51
+ "Power-curve bin mapping (exponent 2.5), peak-preserving neighbour smoothing, per-bar exponent ramp and head margin as described for the open caseif/vis.js recreation (MIT; algorithm described, no code used)"
52
+ ]
53
+ }
54
+ }
@@ -0,0 +1,102 @@
1
+ // label-bars main: the deck layout. A left column of outlined tab-box labels (artist, track, from the text
2
+ // layer; font display, style outline, box tab) over a four-cell level meter and a small
3
+ // starburst; a framed main panel holding 63 thin bars on a ruler baseline (major tick every 8 bars with
4
+ // numerals) with tip dots; a tall title top-right. The media window of the deck is the stage background:
5
+ // footage as one-tone halftone dots (bgMode 2) when there is an input. A strong onset thickens the bars
6
+ // and the emblem starburst for ~3 frames; a kick zooms the panel (both optional). All ink is hairline; a
7
+ // field colour (groundColor / inkColor presets) turns the whole deck acid, ultramarine or orange.
8
+ //@include stage.glsl
9
+ //@include hud.glsl
10
+
11
+ vec4 barAt(int i) { return texelFetch(barState, ivec2(clamp(i, 0, bandCount - 1), 0), 0); }
12
+
13
+ float starburst(vec2 p, float R, float spokes, float wpx) {
14
+ float r = length(p);
15
+ float a = atan(p.y, p.x);
16
+ float k = abs(fract(a / 6.2831853 * spokes) - 0.5) * 6.2831853 / spokes * r;
17
+ return cov(k - wpx * 0.5) * step(R * 0.18, r) * step(r, R) + cov(r - R * 0.1);
18
+ }
19
+
20
+ void main() {
21
+ vec2 res = RENDERSIZE;
22
+ float U = hudU();
23
+ vec4 clk = texelFetch(barState, ivec2(0, 1), 0);
24
+ vec2 sp = vUv * res;
25
+ vec2 px = stageUv(clk, vUv) * res;
26
+ vec2 lo = vec2(0.24 * res.x, 0.12 * res.y);
27
+ vec2 hi = vec2(0.97 * res.x, 0.78 * res.y);
28
+ float W = hi.x - lo.x;
29
+ float H = hi.y - lo.y;
30
+ float n = float(bandCount);
31
+ float span = introSpan();
32
+ float pitch = W * 0.92 / n;
33
+ float x0 = lo.x + W * 0.04;
34
+ float baseY = lo.y + 0.12 * H;
35
+ float extent = 0.8 * H * maxHeight * introK();
36
+ float hitOn = step(0.5, hitEnv(clk, 0.1)) * step(0.5, clk.x);
37
+
38
+ float fi = floor((px.x - x0) / pitch);
39
+ int i = int(clamp(fi, 0.0, n - 1.0));
40
+ float bc = x0 + (fi + 0.5) * pitch;
41
+ bool inSpan = fi >= 0.0 && fi < n && abs(px.x / res.x - 0.5) * 2.0 < span * 0.95 + 0.001;
42
+ vec4 bar = barAt(i);
43
+ float hw = max(hudW() * 0.5, pitch * thickness * 0.5 * (1.0 + 0.5 * hitOn));
44
+ float hP = bar.r * extent + floorHeight * U;
45
+ float dy = px.y - baseY;
46
+ float body = inSpan ? cov(abs(px.x - bc) - hw) * step(-0.5, dy) * cov(dy - hP) : 0.0;
47
+ float tip = inSpan ? cov(length(vec2(px.x - bc, dy - hP - 4.0 * U)) - 1.5 * U) * step(0.012, bar.r) : 0.0;
48
+ float cap = inSpan && bar.g * extent > hP + 8.0 * U ? cov(abs(dy - bar.g * extent - 6.0 * U) - 0.7 * U) * cov(abs(px.x - bc) - hw * 1.5) : 0.0;
49
+
50
+ float baseLine = hair(dy) * step(x0, px.x) * step(px.x, x0 + pitch * n) * span;
51
+ float tickX = abs(fract((px.x - x0) / pitch + 0.5) - 0.5) * pitch;
52
+ float td = baseY - px.y;
53
+ float major = mod(fi, 8.0) < 0.5 ? 1.0 : 0.0;
54
+ float tick = inSpan && td > 3.0 * U && td < (3.0 + (major > 0.5 ? 14.0 : 6.0)) * U && tickX < hudW() * 0.5 ? 1.0 : 0.0;
55
+ float gridH = 0.0;
56
+ for (int r = 1; r <= 4; r++) {
57
+ gridH = max(gridH, hair(px.y - (baseY + float(r) * extent / 4.0)));
58
+ }
59
+ gridH *= dashes(px.x, 8.0, 0.25) * inRect(px, vec2(x0, lo.y), vec2(x0 + pitch * n, hi.y)) * 0.45 * gridAmount;
60
+
61
+ float frame = boxLine(sp, lo, hi) * gridAmount;
62
+ float brk = brackets(sp, lo - 10.0 * U, hi + 10.0 * U, 24.0 * U) * gridAmount;
63
+
64
+ // left column furniture: a four-cell level meter (low, low-mid, high-mid, high bands) and a framed sub-panel
65
+ float icons = 0.0;
66
+ for (int k = 0; k < 4; k++) {
67
+ vec2 lo2 = vec2((0.03 + 0.04 * float(k)) * res.x, 0.62 * res.y);
68
+ vec2 hi2 = lo2 + vec2(0.032 * res.x, 0.04 * res.y);
69
+ float lvl = clamp(barAt(4 + k * 14).r, 0.0, 1.0);
70
+ float fillTop = hi2.y - lvl * (hi2.y - lo2.y);
71
+ icons = max(icons, max(boxLine(sp, lo2, hi2), inRect(sp, vec2(lo2.x + 3.0 * U, fillTop), hi2 - 3.0 * U)));
72
+ }
73
+ vec2 slo = vec2(0.03 * res.x, 0.4 * res.y);
74
+ vec2 shi = vec2(0.19 * res.x, 0.58 * res.y);
75
+ float sub = boxLine(sp, slo, shi) * gridAmount;
76
+ float subTicks = 0.0;
77
+ for (int r = 0; r < 12; r++) {
78
+ float yr = slo.y + (float(r) + 0.5) * (shi.y - slo.y) / 12.0;
79
+ float ln = (2.0 + 6.0 * hash12(vec2(float(r), 3.0))) * 0.012 * res.x * (0.4 + 0.6 * barAt(r * 5).r);
80
+ subTicks = max(subTicks, hair(sp.y - yr) * step(slo.x + 6.0 * U, sp.x) * step(sp.x, slo.x + 6.0 * U + ln));
81
+ }
82
+ vec2 eblo = vec2(0.03 * res.x, 0.12 * res.y);
83
+ vec2 ebhi = vec2(0.19 * res.x, 0.12 * res.y + 0.16 * res.x);
84
+ float emblem = max(boxLine(sp, eblo, ebhi) * gridAmount, starburst(sp - (eblo + ebhi) * 0.5, 0.07 * res.x, 32.0, hudW() * (1.0 + hitOn)));
85
+ float plus = 0.0;
86
+ for (int c = 0; c < 4; c++) {
87
+ vec2 centre = vec2((c & 1) == 0 ? 0.015 * res.x : 0.985 * res.x, (c & 2) == 0 ? 0.04 * res.y : 0.96 * res.y);
88
+ plus = max(plus, plusAt(sp, centre, 7.0 * U));
89
+ }
90
+
91
+ float mk = max(max(body, tip), max(cap, max(baseLine * 0.9, tick * 0.9)));
92
+ mk = max(mk, max(gridH, max(frame, brk)));
93
+ mk = max(mk, max(icons * gridAmount, max(sub, subTicks * 0.8)));
94
+ mk = max(mk, max(emblem, plus * float(marks)));
95
+ vec3 ink = inkColor.rgb;
96
+ vec3 gnd = stageBackground(vUv, ink, kickEnv(clk));
97
+ vec3 acc = accentAt((fi + 0.5) / n);
98
+ vec3 col = mix(gnd, ink, mk);
99
+ col = mix(col, acc, min(tip + cap, 1.0));
100
+ col = mix(col, ink, textInk());
101
+ fragColor = vec4(stageFinish(col, vUv), 1.0);
102
+ }
@@ -0,0 +1,2 @@
1
+ // label-bars pass 0: pro-motion bar state (63 bars by default), persistent in barState.
2
+ //@include bars-pass.glsl
@@ -0,0 +1,64 @@
1
+ // ---- pro motion stage: spectrum -> bar values (shared by the spectrum family) ----
2
+ // Bin mapping: bar i covers startFreq + (endFreq - startFreq) * (i / n)^freqCurve, a power curve that
3
+ // gives the lows more bars (common bar visualisers use exponent 2.5). Each bar takes the
4
+ // maximum of four taps of the 512-bin audioFFT texture (bin s is centred near 29.3 + 46.875 * s Hz).
5
+ // The dB tilt (+tilt per octave above 200 Hz) offsets the 1/f slope of music. The value is windowed
6
+ // by floorLevel / ceilLevel, raised to a per-bar exponent (expLow for the lows ramping to expHigh for
7
+ // the highs, so quiet bars collapse and loud peaks pop), and the first headBars of the bars are weighted
8
+ // down to headMin so the sub-bass edge does not dominate. Peak-preserving neighbour smoothing keeps
9
+ // local maxima and lets each bar lift its neighbours by value / monsterSmooth^distance.
10
+ float specAt(float hz) {
11
+ float s = (hz - 29.3) / 46.875;
12
+ return texture(audioFFT, vec2(clamp((s + 0.5) / 512.0, 0.0, 1.0), 0.5)).r;
13
+ }
14
+
15
+ float binValue(int i, int n) {
16
+ float t0 = float(i) / float(n);
17
+ float f0 = startFreq + (endFreq - startFreq) * pow(t0, freqCurve);
18
+ float f1 = startFreq + (endFreq - startFreq) * pow(float(i + 1) / float(n), freqCurve);
19
+ float v = 0.0;
20
+ for (int k = 0; k < 4; k++) {
21
+ float fq = mix(f0, f1, (float(k) + 0.5) / 4.0);
22
+ float a = specAt(fq);
23
+ v = max(v, a > 0.001 ? a + tilt * log2(max(fq, 20.0) / 200.0) : 0.0);
24
+ }
25
+ float x = clamp((v - floorLevel) / max(ceilLevel - floorLevel, 0.01), 0.0, 1.0);
26
+ x = pow(x, mix(expHigh, expLow, 1.0 - t0 * t0));
27
+ float hb = headBars * float(n);
28
+ return hb > 0.5 && float(i) < hb ? x * mix(headMin, 1.0, float(i) / hb) : x;
29
+ }
30
+
31
+ float smoothedBar(int i, int n) {
32
+ float v = binValue(i, n);
33
+ for (int d = 1; d <= 6; d++) {
34
+ float w = 1.0 / pow(monsterSmooth, float(d));
35
+ if (i - d >= 0) { v = max(v, binValue(i - d, n) * w); }
36
+ if (i + d < n) { v = max(v, binValue(i + d, n) * w); }
37
+ }
38
+ return v;
39
+ }
40
+
41
+ // state texel of bar i: r = height, g = cap, b = cap fall speed, a = cap hold timer
42
+ vec4 barStep(vec4 prev, int i, int n) {
43
+ float t0 = float(i) / float(n);
44
+ float raw = smoothedBar(i, n);
45
+ float rel = releaseMs * (1.0 + bassHold * (1.0 - t0));
46
+ float k = 1.0 - exp(-TIMEDELTA / max((raw > prev.r ? attackMs : rel) * 0.001, 0.0005));
47
+ float h = prev.r + (raw - prev.r) * k;
48
+ float cap = prev.g;
49
+ float vel = prev.b;
50
+ float hold = prev.a;
51
+ if (h >= cap) {
52
+ cap = h;
53
+ vel = 0.0;
54
+ hold = capHoldMs * 0.001;
55
+ } else if (hold > 0.0) {
56
+ hold -= TIMEDELTA;
57
+ } else {
58
+ vel += capGravity * TIMEDELTA;
59
+ cap = max(h, cap - vel * TIMEDELTA);
60
+ }
61
+ return vec4(h, cap, vel, hold);
62
+ }
63
+
64
+ //@include clock.glsl
@@ -0,0 +1,22 @@
1
+ //@include bars-fn.glsl
2
+
3
+ // state pass: bars in row 0 of barState, clock in texel (0, 1), history rows 4..27 where row 3 + d
4
+ // holds the bars as they were d frames ago (a shift register: each row copies the row below it from the
5
+ // previous frame), so templates can draw delayed echoes.
6
+ void main() {
7
+ ivec2 px = ivec2(gl_FragCoord.xy);
8
+ vec4 prev = texelFetch(barState, px, 0);
9
+ if (px.y == 0 && px.x < bandCount) {
10
+ fragColor = barStep(prev, px.x, bandCount);
11
+ return;
12
+ }
13
+ if (px.y == 1 && px.x == 0) {
14
+ fragColor = clockStep(prev);
15
+ return;
16
+ }
17
+ if (px.y >= 4 && px.y <= 27 && px.x < bandCount) {
18
+ fragColor = texelFetch(barState, ivec2(px.x, px.y == 4 ? 0 : px.y - 1), 0);
19
+ return;
20
+ }
21
+ fragColor = vec4(0.0);
22
+ }
@@ -0,0 +1,7 @@
1
+ // clock texel: (hit count, last hit frame, kick count, last kick frame). A hit is an onset whose spectral
2
+ // flux reaches hitFlux; a kick is an onset whose bass ratio reaches kickBass.
3
+ vec4 clockStep(vec4 ev) {
4
+ if (AUDIO_ONSET > 0.5 && AUDIO_FLUX >= hitFlux) { ev.x += 1.0; ev.y = float(FRAMEINDEX); }
5
+ if (AUDIO_ONSET > 0.5 && AUDIO_BASS >= kickBass) { ev.z += 1.0; ev.w = float(FRAMEINDEX); }
6
+ return ev;
7
+ }