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,645 @@
1
+ // hud-deck: central media window (rect / rounded / chamfered octagon) with instrument columns drawn
2
+ // in GLSL hairlines, plus engine text for labels. Pass 0 (specState) holds the smoothed spectrum.
3
+ // brutal family shared GLSL (written fresh). Layout units are "design pixels" of a 1920x1080 frame:
4
+ // U real pixels per design unit, D the fragment position in design units (origin top-left, y down).
5
+ // Distance functions after the standard analytic forms (circle, box, segment, ellipse, equilateral
6
+ // triangle: Inigo Quilez, https://iquilezles.org/articles/distfunctions2d/); the 3x5 digit font, the
7
+ // dot screen, the Bayer matrix and the glyph icons are original.
8
+ float U;
9
+ vec2 D;
10
+ const float TAU = 6.28318530718;
11
+
12
+ void initDesign() {
13
+ U = RENDERSIZE.y / 1080.0;
14
+ D = vec2(gl_FragCoord.x, RENDERSIZE.y - gl_FragCoord.y) / U;
15
+ }
16
+ float designWidth() { return RENDERSIZE.x / U; }
17
+
18
+ float fillAA(float d) { return clamp(0.5 - d * U, 0.0, 1.0); }
19
+ float strokeAA(float d, float w) { return clamp((0.5 * w - abs(d)) * U + 0.5, 0.0, 1.0); }
20
+ float sdBox(vec2 p, vec2 h) { vec2 q = abs(p) - h; return length(max(q, 0.0)) + min(max(q.x, q.y), 0.0); }
21
+ float sdRound(vec2 p, vec2 h, float r) { return sdBox(p, h - r) - r; }
22
+ // chamfered (octagon) rectangle: box cut by a diamond; c is the leg of each 45 degree corner cut
23
+ float sdChamfer(vec2 p, vec2 h, float c, float r) {
24
+ vec2 hh = h - r;
25
+ return max(sdBox(p, hh), (abs(p.x) + abs(p.y) - (hh.x + hh.y - c)) * 0.70710678) - r;
26
+ }
27
+ float sdSeg(vec2 p, vec2 a, vec2 b) {
28
+ vec2 pa = p - a;
29
+ vec2 ba = b - a;
30
+ return length(pa - ba * clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0));
31
+ }
32
+ float sdEll(vec2 p, vec2 r) {
33
+ float k0 = length(p / r);
34
+ float k1 = length(p / (r * r));
35
+ return k0 * (k0 - 1.0) / max(k1, 1e-4);
36
+ }
37
+ float sdTri(vec2 p, float r) {
38
+ const float k = 1.7320508;
39
+ p.x = abs(p.x) - r;
40
+ p.y = p.y + r / k;
41
+ if (p.x + k * p.y > 0.0) p = vec2(p.x - k * p.y, -k * p.x - p.y) / 2.0;
42
+ p.x -= clamp(p.x, -2.0 * r, 0.0);
43
+ return -length(p) * sign(p.y);
44
+ }
45
+ float sdRhomb(vec2 p, vec2 h) { return (abs(p.x) / h.x + abs(p.y) / h.y - 1.0) * min(h.x, h.y) * 0.9; }
46
+
47
+ float plusMark(vec2 p, float arm) {
48
+ return max(strokeAA(sdSeg(p, vec2(-arm, 0.0), vec2(arm, 0.0)), 1.5), strokeAA(sdSeg(p, vec2(0.0, -arm), vec2(0.0, arm)), 1.5));
49
+ }
50
+ // radial lines between r0 and r1, n of them; spin rotates the whole burst, twist curls them
51
+ float burst(vec2 p, float r0, float r1, float n, float w, float spin, float twist) {
52
+ float r = length(p);
53
+ float a = atan(p.y, p.x) + spin + twist * r / max(r1, 1.0);
54
+ float sec = TAU / n;
55
+ float da = mod(a + 0.5 * sec, sec) - 0.5 * sec;
56
+ return strokeAA(r * sin(da), w) * step(r0, r) * step(r, r1);
57
+ }
58
+
59
+ // pixel-snapped origin, so the pixel fonts stay crisp
60
+ vec2 snapPx(vec2 o) { return floor(o * U + 0.5) / U; }
61
+ float cellPx(float cell) { return max(1.0, floor(cell * U + 0.5)) / U; }
62
+
63
+ // 3x5 digit font: 0-9, '-' (10), '.' (11); rows top to bottom, 3 bits per row
64
+ const int F3[12] = int[12](0x7B6F, 0x2C97, 0x73E7, 0x73CF, 0x5BC9, 0x79CF, 0x79EF, 0x7292, 0x7BEF, 0x7BCF, 0x01C0, 0x0002);
65
+ float glyph3(vec2 p, int g, float cell) {
66
+ ivec2 c = ivec2(floor(p / cell));
67
+ if (c.x < 0 || c.x > 2 || c.y < 0 || c.y > 4) return 0.0;
68
+ return float((F3[g] >> ((4 - c.y) * 3 + (2 - c.x))) & 1);
69
+ }
70
+ int digitOf(float a, int power) { return int(mod(floor(a * pow(10.0, -float(power))), 10.0)); }
71
+ // fixed-width number: sign slot, nInt integer digits, then '.' and nDec decimals; p from the top-left
72
+ float printNum(vec2 p, float v, int nInt, int nDec, float cell) {
73
+ float adv = 4.0 * cell;
74
+ int total = 1 + nInt + (nDec > 0 ? 1 + nDec : 0);
75
+ if (p.x < 0.0 || p.x >= float(total) * adv || p.y < 0.0 || p.y >= 5.0 * cell) return 0.0;
76
+ int idx = int(floor(p.x / adv));
77
+ vec2 q = vec2(p.x - float(idx) * adv, p.y);
78
+ int g = 11;
79
+ if (idx == 0) {
80
+ if (v >= 0.0) return 0.0;
81
+ g = 10;
82
+ } else if (idx <= nInt) {
83
+ g = digitOf(abs(v), nInt - idx);
84
+ } else if (idx > nInt + 1) {
85
+ g = digitOf(abs(v), -(idx - nInt - 1));
86
+ }
87
+ return glyph3(q, g, cell);
88
+ }
89
+ float numWidth(int nInt, int nDec, float cell) { return float(1 + nInt + (nDec > 0 ? 1 + nDec : 0)) * 4.0 * cell; }
90
+
91
+ // 8x8 Bayer threshold 0..1 for an integer pixel cell
92
+ float bayer8(vec2 cell) {
93
+ ivec2 i = ivec2(mod(floor(cell), 8.0));
94
+ int x = i.x;
95
+ int xy = i.x ^ i.y;
96
+ int v = ((xy & 1) << 5) | ((x & 1) << 4) | ((xy & 2) << 2) | ((x & 2) << 1) | ((xy & 4) >> 1) | ((x & 4) >> 2);
97
+ return (float(v) + 0.5) / 64.0;
98
+ }
99
+
100
+ float beatPulse(float rate) { return AUDIO_BPM > 1.0 ? exp(-AUDIO_BEATPHASE * rate) : 0.0; }
101
+
102
+ // cover-fit UV into inputImage for a design-space point p inside a box (centre c, full size s)
103
+ vec2 coverUV(vec2 p, vec2 c, vec2 s) {
104
+ vec2 tex = IMG_SIZE(inputImage);
105
+ float ta = tex.x / tex.y;
106
+ float wa = s.x / s.y;
107
+ vec2 q = (p - c) / s;
108
+ q.y = -q.y;
109
+ vec2 vis = wa > ta ? vec2(1.0, ta / wa) : vec2(wa / ta, 1.0);
110
+ return 0.5 + q * vis;
111
+ }
112
+ vec3 mediaRaw(vec2 uv) {
113
+ if (HAS_INPUT) return texture(inputImage, uv).rgb;
114
+ float n = fbm(uv * 3.6 + vec2(TIME * 0.06, 0.0), 4);
115
+ float m = fbm(uv * 7.0 - vec2(0.0, TIME * 0.05) + 3.1, 3);
116
+ return vec3(smoothstep(0.3, 0.75, n) * (0.35 + 0.65 * m)) * vec3(1.0, 0.9, 0.78);
117
+ }
118
+ // Procedural outline glyphs (original shapes). p is relative to the glyph centre, R is its radius in design units.
119
+ float iconCylinder(vec2 p, float R) {
120
+ float w = R * 0.62;
121
+ float h = R * 0.78;
122
+ float e = R * 0.27;
123
+ float d = min(sdSeg(p, vec2(-w, -h), vec2(-w, h)), sdSeg(p, vec2(w, -h), vec2(w, h)));
124
+ d = min(d, abs(sdEll(p - vec2(0.0, -h), vec2(w, e))));
125
+ if (p.y > h) d = min(d, abs(sdEll(p - vec2(0.0, h), vec2(w, e))));
126
+ return strokeAA(d, 1.5);
127
+ }
128
+ float iconFolder(vec2 p, float R) {
129
+ float d = abs(sdRound(p - vec2(0.0, R * 0.14), vec2(R * 0.95, R * 0.62), 2.0));
130
+ d = min(d, sdSeg(p, vec2(-R * 0.95, -R * 0.48), vec2(-R * 0.95, -R * 0.76)));
131
+ d = min(d, sdSeg(p, vec2(-R * 0.95, -R * 0.76), vec2(-R * 0.25, -R * 0.76)));
132
+ d = min(d, sdSeg(p, vec2(-R * 0.25, -R * 0.76), vec2(R * 0.02, -R * 0.48)));
133
+ return strokeAA(d, 1.5);
134
+ }
135
+ float iconSwirl(vec2 p, float R) {
136
+ float r = length(p);
137
+ return max(burst(p, R * 0.2, R, 14.0, 1.2, 0.0, 1.7), fillAA(r - R * 0.11));
138
+ }
139
+ float iconLayers(vec2 p, float R) {
140
+ float d = abs(sdRhomb(p - vec2(0.0, -R * 0.38), vec2(R, R * 0.46)));
141
+ vec2 a = vec2(-R, R * 0.04);
142
+ vec2 b = vec2(0.0, R * 0.5);
143
+ vec2 c = vec2(R, R * 0.04);
144
+ d = min(d, min(sdSeg(p, a, b), sdSeg(p, b, c)));
145
+ d = min(d, min(sdSeg(p, a + vec2(0.0, R * 0.42), b + vec2(0.0, R * 0.42)), sdSeg(p, b + vec2(0.0, R * 0.42), c + vec2(0.0, R * 0.42))));
146
+ return strokeAA(d, 1.5);
147
+ }
148
+ float iconMoon(vec2 p, float R) {
149
+ return fillAA(max(length(p) - R * 0.88, -(length(p - vec2(R * 0.46, -R * 0.14)) - R * 0.74)));
150
+ }
151
+ float iconSnow(vec2 p, float R) {
152
+ float m = max(burst(p, R * 0.3, R, 8.0, 1.3, 0.3927, 0.0), burst(p, R * 0.3, R * 0.62, 8.0, 1.3, 0.0, 0.0));
153
+ return max(m, strokeAA(length(p) - R * 0.22, 1.4));
154
+ }
155
+ float iconTrefoil(vec2 p, float R) {
156
+ float r = R * 0.34;
157
+ float d = abs(sdTri(vec2(p.x, -(p.y + R * 0.5)), r));
158
+ d = min(d, abs(sdTri(vec2(p.x + R * 0.5, -(p.y - R * 0.36)), r)));
159
+ d = min(d, abs(sdTri(vec2(p.x - R * 0.5, -(p.y - R * 0.36)), r)));
160
+ return max(strokeAA(d, 1.4), fillAA(length(p - vec2(0.0, R * 0.12)) - R * 0.07));
161
+ }
162
+ float iconDots(vec2 p, float R) {
163
+ float d = abs(sdEll(p, vec2(R, R * 0.78)));
164
+ d = min(d, abs(length(p - vec2(-R * 0.3, 0.0)) - R * 0.2));
165
+ d = min(d, abs(length(p - vec2(R * 0.3, 0.0)) - R * 0.2));
166
+ return strokeAA(d, 1.4);
167
+ }
168
+ float iconCube(vec2 p, float R) {
169
+ float d = 1e3;
170
+ vec2 prev = R * vec2(cos(0.5236), sin(0.5236));
171
+ for (int i = 1; i <= 6; i++) {
172
+ float a = 0.5236 + float(i) * 1.0472;
173
+ vec2 cur = R * vec2(cos(a), sin(a));
174
+ d = min(d, sdSeg(p, prev, cur));
175
+ prev = cur;
176
+ }
177
+ d = min(d, sdSeg(p, vec2(0.0), R * vec2(cos(0.5236), sin(0.5236))));
178
+ d = min(d, sdSeg(p, vec2(0.0), R * vec2(cos(2.618), sin(2.618))));
179
+ d = min(d, sdSeg(p, vec2(0.0), R * vec2(0.0, -1.0)));
180
+ float grid = step(0.5, mod(floor(p.x / 3.0) + floor(p.y / 3.0), 2.0)) * fillAA(sdBox(p - R * vec2(0.28, 0.2), R * vec2(0.22, 0.28)));
181
+ return max(strokeAA(d, 1.5), grid);
182
+ }
183
+ float iconCircleCross(vec2 p, float R) {
184
+ return max(strokeAA(length(p) - R, 1.3), plusMark(p, R * 1.2));
185
+ }
186
+ float iconOverlap(vec2 p, float R) {
187
+ float d = min(abs(length(p - vec2(-R * 0.25, -R * 0.2)) - R * 0.62), abs(sdBox(p - vec2(R * 0.28, R * 0.25), vec2(R * 0.5))));
188
+ return strokeAA(d, 1.3);
189
+ }
190
+ // staggered power-on: panel k (0..1) flickers in between k*introMs and k*introMs + 140 ms
191
+ float rev(float k) {
192
+ float a = (TIME * 1000.0 - introMs * k) / 140.0;
193
+ if (a >= 1.0) return 1.0;
194
+ if (a <= 0.0) return 0.0;
195
+ return step(0.45, hash12(vec2(k * 37.0, float(FRAMEINDEX))));
196
+ }
197
+
198
+ vec2 gWC;
199
+ vec2 gWH;
200
+
201
+ // beat tears: blocks of rows slide sideways for a couple of frames after each beat
202
+ vec2 tearP(vec2 p) {
203
+ float on = step(0.3, beatPulse(8.0)) * tearAmount;
204
+ if (on <= 0.0) return p;
205
+ float row = floor(p.y / 20.0);
206
+ float f = float(FRAMEINDEX / 2);
207
+ p.x += (hash12(vec2(row, f)) - 0.5) * 2.0 * on * 150.0 * step(0.55, hash12(vec2(row, f + 1.7)));
208
+ return p;
209
+ }
210
+ float lumAt(vec2 p) {
211
+ vec2 uv = coverUV(tearP(p), gWC, gWH * 2.0);
212
+ float L = pow(clamp(luma(mediaRaw(uv)), 0.0, 1.0), 0.4545);
213
+ return clamp((L - 0.5) * mediaContrast + 0.5 + mediaBias, 0.0, 1.0);
214
+ }
215
+ // Single-tone screens. The including shader defines `float lumAt(vec2 p)` first: ink amount 0..1 at a design
216
+ // space point (1 = full dot). Cell sizes g are in design units.
217
+
218
+ // Dot screen: rotated square lattice, dot radius grows with sqrt(ink) so the dot AREA follows tone.
219
+ // The 3x3 neighbourhood is evaluated so large dots overlap instead of being clipped to their cell.
220
+ float dotScreen(vec2 p, float g, float ang, float gain, float soft) {
221
+ mat2 R = rot(ang);
222
+ vec2 q = (R * p) / g;
223
+ vec2 cell = floor(q);
224
+ float m = 0.0;
225
+ for (int j = -1; j <= 1; j++) {
226
+ for (int i = -1; i <= 1; i++) {
227
+ vec2 c = cell + vec2(float(i), float(j)) + 0.5;
228
+ float L = lumAt((c * g) * R);
229
+ float r = 0.5 * sqrt(clamp(L, 0.0, 1.0)) * gain;
230
+ m = max(m, clamp(0.5 - (length(q - c) - r) * g * U / soft, 0.0, 1.0));
231
+ }
232
+ }
233
+ return m;
234
+ }
235
+
236
+ // Ordered dither: Bayer 8x8 thresholds on blocks of `block` design units.
237
+ float orderedDither(vec2 p, float block) {
238
+ vec2 b = floor(p * U / max(block * U, 1.0));
239
+ vec2 centre = (b + 0.5) * block;
240
+ return step(bayer8(b), lumAt(centre));
241
+ }
242
+
243
+ // ASCII-style cell: one of six procedural glyphs picked by tone (dot, +, x, #, =, block), no font needed.
244
+ float asciiScreen(vec2 p, float g) {
245
+ vec2 id = floor(p / g);
246
+ vec2 f = fract(p / g) - 0.5;
247
+ float L = lumAt((id + 0.5) * g);
248
+ float d = 1e3;
249
+ if (L < 0.1) return 0.0;
250
+ if (L < 0.26) d = length(f) - 0.09;
251
+ else if (L < 0.42) d = min(abs(f.x), abs(f.y)) - 0.05 + step(0.34, max(abs(f.x), abs(f.y))) * 1e3;
252
+ else if (L < 0.58) d = min(abs(f.x - f.y), abs(f.x + f.y)) * 0.7071 - 0.05 + step(0.36, max(abs(f.x), abs(f.y))) * 1e3;
253
+ else if (L < 0.74) d = min(min(abs(abs(f.x) - 0.15), abs(abs(f.y) - 0.15)), 1e3) - 0.045 + step(0.4, max(abs(f.x), abs(f.y))) * 1e3;
254
+ else if (L < 0.88) d = min(abs(f.y - 0.13), abs(f.y + 0.13)) - 0.06 + step(0.4, abs(f.x)) * 1e3;
255
+ else d = max(abs(f.x), abs(f.y)) - 0.4;
256
+ return clamp(0.5 - d * g * U, 0.0, 1.0);
257
+ }
258
+ float winSD(vec2 p) {
259
+ vec2 q = p - gWC;
260
+ if (winShape == 0) return sdRound(q, gWH, 8.0);
261
+ if (winShape == 1) return sdRound(q, gWH, min(gWH.x, gWH.y) * 0.12);
262
+ return sdChamfer(q, gWH, chamfer, 14.0);
263
+ }
264
+
265
+ vec3 windowColor(vec2 p) {
266
+ if (mediaMode == 2) return mix(winBg.rgb, tone.rgb, dotScreen(p, dotSize, dotAngle, 1.18, 1.0));
267
+ if (mediaMode == 3) return mix(winBg.rgb, tone.rgb, smoothstep(0.06, 0.94, lumAt(p)));
268
+ vec3 c = mediaRaw(coverUV(tearP(p), gWC, gWH * 2.0));
269
+ c = max((c - 0.18) * mediaContrast + 0.18 + (mediaBias * 0.2), 0.0);
270
+ return mediaMode == 1 ? vec3(luma(c)) : c;
271
+ }
272
+
273
+ // white-hot horizontal light bar (eye flare) that breathes with the beat
274
+ vec3 flareAdd(vec2 p) {
275
+ float amt = flare * (0.5 + 0.5 * mix(1.0, beatPulse(5.0), flareBeat));
276
+ vec2 c = gWC + (vec2(flareX, flareY) - 0.5) * gWH * 2.0;
277
+ float len = flareW * gWH.x * 2.0;
278
+ float dx = (p.x - c.x) / len;
279
+ float dy = p.y - c.y;
280
+ float tap = clamp(1.0 - dx * dx, 0.0, 1.0);
281
+ float s1 = 4.5 * tap + 0.8;
282
+ float s2 = 28.0 * tap + 2.0;
283
+ float core = exp(-dy * dy / (2.0 * s1 * s1)) * tap;
284
+ float halo = exp(-dy * dy / (2.0 * s2 * s2)) * tap * 0.4;
285
+ return (core * vec3(2.4) + halo * vec3(1.0, 0.78, 0.45)) * amt;
286
+ }
287
+
288
+ // Tile layout (octagon window, off-centre): dial gauge, segment meter, readout column, pad matrix,
289
+ // bar meters, scan ruler, timeline with a barcode strip, nested rhombus target and crop brackets.
290
+ // four-point astroid star (also used by the night layout's icon rows)
291
+ float dkAstroid(vec2 p, float R) {
292
+ float f = sqrt(abs(p.x)) + sqrt(abs(p.y)) - sqrt(R);
293
+ return strokeAA(f * R * 0.22, 1.4);
294
+ }
295
+ float dkOutlineRect(vec2 p, vec2 lo, vec2 hi) { return strokeAA(sdRound(p - 0.5 * (lo + hi), 0.5 * (hi - lo), 2.0), 1.5); }
296
+ float dkBand(int i) { return clamp(AUDIO_BANDS[clamp(i, 0, 31)] * reactivity, 0.0, 1.0); }
297
+
298
+ // upper half dial: two arcs, 40 ticks (every 5th long), a lit level band and a needle at value v
299
+ vec2 dkDial(vec2 p, vec2 c, float R, float v) {
300
+ vec2 q = p - c;
301
+ if (q.y > 2.0 || length(q) > R + 4.0) return vec2(0.0);
302
+ float r = length(q);
303
+ float a = atan(-q.y, q.x);
304
+ float up = step(q.y, 0.0);
305
+ float ink = up * max(strokeAA(r - R, 1.5), strokeAA(r - R * 0.6, 1.2));
306
+ float sec = 3.14159265 / 40.0;
307
+ float idx = floor((a + 0.5 * sec) / sec);
308
+ float da = a - idx * sec;
309
+ bool major = mod(idx, 5.0) < 0.5;
310
+ float rin = R - (major ? 26.0 : 12.0);
311
+ ink = max(ink, up * strokeAA(r * sin(da), major ? 2.0 : 1.2) * step(rin, r) * step(r, R - 4.0));
312
+ float seg = up * step(R * 0.64, r) * step(r, R * 0.74) * step(abs(da), sec * 0.32);
313
+ float lit = step(1.0 - idx / 40.0, v);
314
+ float an = 3.14159265 * (1.0 - v);
315
+ vec2 tip = c + R * 0.9 * vec2(cos(an), -sin(an));
316
+ ink = max(ink, max(seg * lit, strokeAA(sdSeg(p, c, tip), 2.0)));
317
+ ink = max(ink, max(fillAA(r - 6.0), strokeAA(r - 14.0, 1.2) * up));
318
+ ink = max(ink, strokeAA(sdSeg(p, c - vec2(R, 0.0), c + vec2(R, 0.0)), 1.2));
319
+ return vec2(ink, seg * (1.0 - lit));
320
+ }
321
+
322
+ // L-shaped crop mark just outside a window corner; sx, sy = -1 or 1 point away from the window
323
+ float dkBracket(vec2 p, vec2 corner, float sx, float sy) {
324
+ vec2 a = corner + vec2(sx, sy) * 16.0;
325
+ return strokeAA(min(sdSeg(p, a, a - vec2(sx * 44.0, 0.0)), sdSeg(p, a, a - vec2(0.0, sy * 44.0))), 2.0);
326
+ }
327
+
328
+ vec2 deckTiles(vec2 p, float drive) {
329
+ float ink = 0.0;
330
+ float dim = 0.0;
331
+ float W = designWidth();
332
+ vec2 lo = gWC - gWH;
333
+ vec2 hi = gWC + gWH;
334
+ float lv = clamp(drive, 0.0, 1.0);
335
+
336
+ // top: header rule with tabs and a running time readout
337
+ float k = rev(0.15);
338
+ ink = max(ink, k * strokeAA(p.y - 96.0, 1.2) * step(lo.x, p.x) * step(p.x, hi.x));
339
+ ink = max(ink, k * dkOutlineRect(p, vec2(lo.x, 52.0), vec2(lo.x + 224.0, 84.0)));
340
+ ink = max(ink, k * dkOutlineRect(p, vec2(lo.x + 244.0, 52.0), vec2(lo.x + 304.0, 84.0)));
341
+ ink = max(ink, k * dkOutlineRect(p, vec2(hi.x - 100.0, 52.0), vec2(hi.x, 84.0)));
342
+ ink = max(ink, k * printNum(p - snapPx(vec2(lo.x + 14.0, 58.0)), mod(TIME, 1000.0), 3, 2, 4.0));
343
+ ink = max(ink, k * plusMark(p - vec2(lo.x - 30.0, 96.0), 8.0));
344
+ ink = max(ink, k * plusMark(p - vec2(hi.x + 30.0, 96.0), 8.0));
345
+ ink = max(ink, k * dkBracket(p, lo, -1.0, -1.0));
346
+ ink = max(ink, k * dkBracket(p, vec2(hi.x, lo.y), 1.0, -1.0));
347
+ ink = max(ink, k * dkBracket(p, vec2(lo.x, hi.y), -1.0, 1.0));
348
+ ink = max(ink, k * dkBracket(p, hi, 1.0, 1.0));
349
+
350
+ // left: dial, segment meter, readout column, pad matrix
351
+ k = rev(0.3);
352
+ if (p.x < 420.0 && p.y < 270.0) {
353
+ vec2 d = dkDial(p, vec2(214.0, 250.0), 180.0, lv);
354
+ ink = max(ink, k * d.x);
355
+ dim = max(dim, k * d.y);
356
+ }
357
+ if (p.y > 290.0 && p.y < 340.0 && p.x < 420.0) {
358
+ float i = floor((p.x - 28.0) / 16.0);
359
+ vec2 cc = vec2(28.0 + i * 16.0 + 6.5, 314.0);
360
+ float box = sdBox(p - cc, vec2(6.5, 18.0));
361
+ float inRow = step(0.0, i) * step(i, 23.0);
362
+ float lit = step(i / 24.0, lv - 0.02);
363
+ ink = max(ink, k * inRow * max(strokeAA(box, 1.2), fillAA(box) * lit));
364
+ dim = max(dim, k * inRow * fillAA(box) * (1.0 - lit));
365
+ }
366
+ k = rev(0.45);
367
+ if (p.x > 290.0 && p.x < 440.0 && p.y > 400.0 && p.y < 720.0) {
368
+ for (int i = 0; i < 5; i++) {
369
+ float y = 412.0 + float(i) * 62.0;
370
+ float v = dkBand(2 + i * 6);
371
+ ink = max(ink, k * printNum(p - snapPx(vec2(304.0, y)), v, 1, 2, 4.0));
372
+ ink = max(ink, k * strokeAA(p.y - (y + 30.0), 2.0) * step(304.0, p.x) * step(p.x, 304.0 + 120.0 * v));
373
+ dim = max(dim, k * strokeAA(p.y - (y + 30.0), 2.0) * step(304.0, p.x) * step(p.x, 424.0));
374
+ ink = max(ink, k * strokeAA(sdSeg(p, vec2(294.0, y), vec2(294.0, y + 30.0)), 1.2));
375
+ }
376
+ }
377
+ if (p.x < 320.0 && p.y > 766.0) {
378
+ vec2 g = floor((p - vec2(28.0, 776.0)) / 70.0);
379
+ if (g.x >= 0.0 && g.x < 4.0 && g.y >= 0.0 && g.y < 4.0) {
380
+ vec2 cc = vec2(28.0, 776.0) + g * 70.0 + 29.0;
381
+ float cell = sdRound(p - cc, vec2(29.0), 6.0);
382
+ float lit = step(0.5, dkBand(int(g.y * 4.0 + g.x) * 2));
383
+ ink = max(ink, k * max(strokeAA(cell, 1.4), fillAA(cell + 9.0) * lit));
384
+ dim = max(dim, k * fillAA(cell + 9.0) * (1.0 - lit));
385
+ }
386
+ }
387
+
388
+ // right: scan ruler beside the window, bar meters, BPM and frame readouts, rhombus target
389
+ k = rev(0.6);
390
+ float rx = hi.x + 16.0;
391
+ if (p.x > rx - 14.0 && p.x < rx + 18.0 && p.y > lo.y - 2.0 && p.y < hi.y + 2.0) {
392
+ float t = mod(p.y - lo.y, 12.0);
393
+ float major = step(mod(p.y - lo.y, 60.0), 1.0);
394
+ ink = max(ink, k * strokeAA(p.x - rx, 1.2));
395
+ ink = max(ink, k * step(min(t, 12.0 - t), 0.6) * step(rx, p.x) * step(p.x, rx + mix(6.0, 14.0, major)));
396
+ float sy = lo.y + fract(TIME * 0.125) * (hi.y - lo.y);
397
+ ink = max(ink, k * max(fillAA(sdRhomb(p - vec2(rx, sy), vec2(7.0, 9.0))), strokeAA(p.y - sy, 1.2) * step(rx - 14.0, p.x)));
398
+ }
399
+ if (p.x > W - 262.0 && p.y > 130.0 && p.y < 346.0) {
400
+ float i = floor((p.x - (W - 260.0)) / 29.0);
401
+ if (i >= 0.0 && i < 8.0) {
402
+ vec2 cc = vec2(W - 260.0 + i * 29.0 + 10.0, 240.0);
403
+ float box = sdBox(p - cc, vec2(10.0, 100.0));
404
+ float h = dkBand(2 + int(i) * 3);
405
+ ink = max(ink, k * max(strokeAA(box, 1.2), fillAA(box + 3.0) * step(340.0 - h * 200.0, p.y)));
406
+ }
407
+ }
408
+ k = rev(0.75);
409
+ ink = max(ink, k * printNum(p - snapPx(vec2(W - 268.0, 770.0)), AUDIO_BPM, 3, 0, 7.0));
410
+ ink = max(ink, k * printNum(p - snapPx(vec2(W - 268.0, 822.0)), float(FRAMEINDEX % 10000), 4, 0, 4.0));
411
+ ink = max(ink, k * strokeAA(sdSeg(p, vec2(W - 268.0, 812.0), vec2(W - 28.0, 812.0)), 1.2));
412
+ if (p.x > W - 250.0 && p.y > 890.0) {
413
+ vec2 q = p - vec2(W - 150.0, 975.0);
414
+ float an = TIME * 0.2 + drive * 0.4;
415
+ q = mat2(cos(an), -sin(an), sin(an), cos(an)) * q;
416
+ float rh = min(abs(sdRhomb(q, vec2(66.0))), min(abs(sdRhomb(q, vec2(44.0))), abs(sdRhomb(q, vec2(22.0)))));
417
+ ink = max(ink, k * max(strokeAA(rh, 1.4), fillAA(length(q) - 4.0)));
418
+ }
419
+
420
+ // bottom: timeline with ticks and a playhead over a barcode strip that follows the bands
421
+ k = rev(0.85);
422
+ if (p.y > 900.0 && p.x > lo.x - 2.0 && p.x < hi.x + 2.0) {
423
+ float span = hi.x - lo.x;
424
+ float step48 = span / 48.0;
425
+ float lx = p.x - lo.x;
426
+ float tk = mod(lx + 0.5 * step48, step48) - 0.5 * step48;
427
+ float major = step(mod(floor((lx + 0.5 * step48) / step48), 8.0), 0.5);
428
+ ink = max(ink, k * strokeAA(p.y - 930.0, 1.4));
429
+ ink = max(ink, k * strokeAA(tk, 1.2) * step(930.0 - mix(8.0, 18.0, major), p.y) * step(p.y, 930.0));
430
+ float ph = lo.x + fract(TIME / 8.0) * span;
431
+ ink = max(ink, k * max(fillAA(sdRhomb(p - vec2(ph, 914.0), vec2(7.0, 9.0))), strokeAA(p.x - ph, 1.2) * step(930.0, p.y) * step(p.y, 1048.0)));
432
+ float col = floor(lx / 7.0);
433
+ float on = step(fract(lx / 7.0), 0.58) * step(hash12(vec2(col, 31.0)), 0.82);
434
+ float h = 90.0 * clamp(0.12 + 0.85 * dkBand(int(mod(col, 32.0))), 0.0, 1.0);
435
+ float bar = on * step(1040.0 - h, p.y) * step(p.y, 1040.0) * step(946.0, p.y);
436
+ ink = max(ink, k * bar);
437
+ dim = max(dim, k * on * (1.0 - bar) * step(946.0, p.y) * step(p.y, 1040.0) * 0.5);
438
+ }
439
+ return vec2(ink, dim);
440
+ }
441
+ // Night deck, bottom desk (design units): desk rules, label rules, waveform strip and a hatched spectrum area.
442
+ float boxLine(vec2 p, vec2 lo, vec2 hi, float r) { return strokeAA(sdRound(p - 0.5 * (lo + hi), 0.5 * (hi - lo), r), 1.5); }
443
+
444
+ // Seeded point cloud that drifts as an elongated blob; density follows the music.
445
+ float dkCloud(vec2 p, vec2 size, float drive) {
446
+ float t = TIME * driftSpeed;
447
+ vec2 c = size * 0.5 + vec2(sin(t * 0.37) * size.x * 0.1, sin(t * 0.23 + 1.0) * size.y * 0.07);
448
+ float ang = 0.8 + 0.6 * sin(t * 0.17);
449
+ mat2 R = rot(ang);
450
+ vec2 axes = vec2(size.x * (0.22 + 0.1 * drive), size.y * (0.09 + 0.13 * drive));
451
+ float cell = 6.0;
452
+ vec2 g = floor(p / cell);
453
+ float m = 0.0;
454
+ for (int j = -1; j <= 1; j++) {
455
+ for (int i = -1; i <= 1; i++) {
456
+ vec2 id = g + vec2(float(i), float(j));
457
+ vec2 h = hash22(id);
458
+ vec2 pt = (id + 0.1 + 0.8 * h) * cell;
459
+ pt += vec2(sin(t * (0.7 + h.x) + h.y * TAU), cos(t * (0.6 + h.y) + h.x * TAU)) * (1.2 + 2.5 * drive);
460
+ vec2 q = R * (pt - c) / axes;
461
+ float w = exp(-dot(q, q) * 1.15) * (0.7 + 1.6 * drive) * particleDensity;
462
+ float keep = step(hash12(id + 7.7), w);
463
+ m = max(m, keep * fillAA(length(p - pt) - 1.15));
464
+ }
465
+ }
466
+ return m;
467
+ }
468
+
469
+ // vertical hairlines min..max of the waveform per pixel column (trigger-aligned wave texture, row 0)
470
+ float dkWave(vec2 p, float w, float amp) {
471
+ float x0 = clamp((p.x - 0.5) / w, 0.0, 1.0);
472
+ float x1 = clamp((p.x + 0.5) / w, 0.0, 1.0);
473
+ float lo = 1e3;
474
+ float hi = -1e3;
475
+ for (int k = 0; k < 3; k++) {
476
+ float s = (texture(audio, vec2(mix(x0, x1, float(k) * 0.5), 0.25)).r - 0.5) * 2.0 * amp * waveGain;
477
+ lo = min(lo, s);
478
+ hi = max(hi, s);
479
+ }
480
+ lo = min(lo, -0.4);
481
+ hi = max(hi, 0.4);
482
+ return clamp(min(p.y - lo + 0.5, hi - p.y + 0.5) * U, 0.0, 1.0);
483
+ }
484
+
485
+ float dkSpecValue(float xd, vec2 lo, float w) {
486
+ float u = clamp((xd - lo.x) / w, 0.0, 1.0);
487
+ return texture(specState, vec2(u * 256.0 / RENDERSIZE.x, 0.5 / RENDERSIZE.y)).r;
488
+ }
489
+
490
+ // spectrum as an area: a solid top edge over a vertical hatch down to the floor
491
+ vec2 dkSpecArea(vec2 p, vec2 lo, vec2 hi) {
492
+ float w = hi.x - lo.x;
493
+ float y0 = hi.y - 2.0;
494
+ float span = (hi.y - lo.y - 8.0) * spectrumGain;
495
+ float a = y0 - dkSpecValue(p.x - 0.5, lo, w) * span;
496
+ float b = y0 - dkSpecValue(p.x + 0.5, lo, w) * span;
497
+ float c = y0 - dkSpecValue(p.x, lo, w) * span;
498
+ float top = min(c, min(a, b)) - 0.8;
499
+ float bot = max(c, max(a, b)) + 0.8;
500
+ float inX = step(lo.x + 1.0, p.x) * step(p.x, hi.x - 1.0);
501
+ float edge = clamp(min(p.y - top, bot - p.y) * U + 0.5, 0.0, 1.0);
502
+ float hatch = step(c, p.y) * step(p.y, y0) * step(fract(p.x / 4.0), 0.4);
503
+ return vec2(max(edge * step(p.y, y0 + 0.6), hatch) * inX, 0.0);
504
+ }
505
+
506
+ vec2 deckLeft(vec2 p, float drive) {
507
+ float ink = 0.0;
508
+ float dim = 0.0;
509
+ if (p.y < 776.0 || p.x > 1352.0) return vec2(0.0);
510
+ float k = rev(0.3);
511
+ // desk rule, label rules, column dividers
512
+ ink = max(ink, k * strokeAA(p.y - 780.0, 1.2) * step(30.0, p.x));
513
+ ink = max(ink, k * strokeAA(p.y - 890.0, 1.2) * step(30.0, p.x) * step(p.x, 520.0));
514
+ dim = max(dim, k * strokeAA(p.x - 540.0, 1.2) * step(796.0, p.y) * step(p.y, 1046.0));
515
+ dim = max(dim, k * strokeAA(p.x - 1350.0, 1.2) * step(796.0, p.y) * step(p.y, 1046.0));
516
+ ink = max(ink, k * fillAA(sdBox(p - vec2(512.0, 798.0), vec2(8.0, 4.0))));
517
+ ink = max(ink, k * fillAA(sdBox(p - vec2(512.0, 900.0), vec2(8.0, 4.0))));
518
+ // waveform strip with a dotted baseline
519
+ if (p.y > 994.0 && p.x < 530.0) {
520
+ float k2 = rev(0.7);
521
+ float x0 = 30.0;
522
+ float w = 490.0;
523
+ ink = max(ink, k2 * dkWave(vec2(p.x - x0, p.y - 1022.0), w, 20.0) * step(x0, p.x) * step(p.x, x0 + w));
524
+ dim = max(dim, k2 * strokeAA(p.y - 1046.0, 1.2) * step(0.5, fract(p.x / 6.0)) * step(x0, p.x) * step(p.x, x0 + w));
525
+ }
526
+ // hatched spectrum area with dashed guides at the label columns
527
+ vec2 sLo = vec2(560.0, 800.0);
528
+ vec2 sHi = vec2(1330.0, 1000.0);
529
+ if (p.x > 550.0 && p.y < 1004.0) {
530
+ float k2 = rev(0.45);
531
+ vec2 s = dkSpecArea(p, sLo, sHi);
532
+ ink = max(ink, k2 * s.x);
533
+ ink = max(ink, k2 * strokeAA(p.y - (sHi.y - 2.0), 1.4) * step(sLo.x, p.x) * step(p.x, sHi.x));
534
+ for (int i = 0; i < 5; i++) {
535
+ float xi = sLo.x + float(i) * (sHi.x - sLo.x) / 4.0;
536
+ dim = max(dim, k2 * strokeAA(p.x - xi, 1.2) * step(0.5, fract(p.y / 8.0)) * step(sLo.y, p.y) * step(p.y, sHi.y));
537
+ }
538
+ }
539
+ return vec2(ink, dim);
540
+ }
541
+ // Night deck, right rail: contour map with readouts, chamfered particle box, 16-step beat sequencer.
542
+ // iso-lines of fbm: a line wherever the field crosses a level, anti-aliased with the screen derivative
543
+ float dkField(vec2 p, vec2 lo, float drive) {
544
+ float t = TIME * driftSpeed * 0.035;
545
+ return fbm((p - lo) / 150.0 * contourScale + vec2(t, -t * 0.6) + drive * 0.12, 4) * contourLevels;
546
+ }
547
+ float dkContour(vec2 p, vec2 lo, float drive) {
548
+ float s = dkField(p, lo, drive);
549
+ float gx = dkField(p + vec2(1.0, 0.0), lo, drive) - s;
550
+ float gy = dkField(p + vec2(0.0, 1.0), lo, drive) - s;
551
+ float fw = max(length(vec2(gx, gy)) / U, 0.006);
552
+ float dist = (0.5 - abs(fract(s) - 0.5)) / fw;
553
+ return clamp(1.15 - dist, 0.0, 1.0);
554
+ }
555
+
556
+ vec2 deckRight(vec2 p, float drive) {
557
+ float ink = 0.0;
558
+ float dim = 0.0;
559
+ if (p.x < 1360.0) return vec2(0.0);
560
+ // contour map: frame, corner ticks, a dashed mid line, readouts beneath
561
+ vec2 cLo = vec2(1370.0, 30.0);
562
+ vec2 cHi = vec2(1890.0, 330.0);
563
+ if (p.y < 370.0) {
564
+ float k = rev(0.2);
565
+ ink = max(ink, k * boxLine(p, cLo, cHi, 0.0));
566
+ float inside = step(cLo.x + 1.0, p.x) * step(p.x, cHi.x - 1.0) * step(cLo.y + 1.0, p.y) * step(p.y, cHi.y - 1.0);
567
+ ink = max(ink, k * inside * dkContour(p, cLo, drive));
568
+ dim = max(dim, k * inside * strokeAA(p.y - 0.5 * (cLo.y + cHi.y), 1.2) * step(0.5, fract(p.x / 10.0)));
569
+ vec2 q = abs(p - 0.5 * (cLo + cHi)) - (0.5 * (cHi - cLo) - 14.0);
570
+ ink = max(ink, k * step(0.0, q.x) * step(0.0, q.y) * max(strokeAA(q.x, 3.0), strokeAA(q.y, 3.0)) * inside);
571
+ float cell = cellPx(2.8);
572
+ float va = 212.4 + 90.0 * sin(TIME * 0.9) + 60.0 * drive;
573
+ float vb = 3.71 + 2.0 * sin(TIME * 1.7 + 1.0) + 4.0 * AUDIO_PEAK;
574
+ ink = max(ink, k * printNum(p - snapPx(vec2(1366.0, 344.0)), va, 3, 1, cell));
575
+ ink = max(ink, k * printNum(p - snapPx(vec2(1890.0 - numWidth(1, 3, cell), 344.0)), vb, 1, 3, cell));
576
+ }
577
+ // particle box with cut corners
578
+ vec2 bLo = vec2(1370.0, 400.0);
579
+ vec2 bHi = vec2(1890.0, 750.0);
580
+ if (p.y > 394.0 && p.y < 756.0) {
581
+ float k = rev(0.5);
582
+ float sd = sdChamfer(p - 0.5 * (bLo + bHi), 0.5 * (bHi - bLo), 22.0, 0.0);
583
+ ink = max(ink, k * strokeAA(sd, 1.5));
584
+ ink = max(ink, k * dkCloud(p - bLo, bHi - bLo, drive) * step(sd, -4.0));
585
+ }
586
+ // beat sequencer: 16 cells, the current step filled, every fourth cell heavier
587
+ if (p.y > 796.0 && p.y < 834.0) {
588
+ float k = rev(0.65);
589
+ float cw = (1890.0 - 1370.0) / 16.0;
590
+ float i = floor((p.x - 1370.0) / cw);
591
+ if (i >= 0.0 && i < 16.0) {
592
+ vec2 cc = vec2(1370.0 + (i + 0.5) * cw, 815.0);
593
+ float box = sdBox(p - cc, vec2(cw * 0.5 - 4.0, 15.0));
594
+ float beats = AUDIO_BPM > 1.0 ? TIME * AUDIO_BPM / 60.0 : TIME * 2.0;
595
+ float cur = mod(floor(beats), 16.0);
596
+ float heavy = step(mod(i, 4.0), 0.5);
597
+ ink = max(ink, k * max(strokeAA(box, mix(1.2, 2.4, heavy)), fillAA(box + 3.0) * step(abs(i - cur), 0.5)));
598
+ }
599
+ }
600
+ return vec2(ink, dim);
601
+ }
602
+ void main() {
603
+ initDesign();
604
+ float W = designWidth();
605
+ gWC = vec2(winX * W, winY * 1080.0);
606
+ gWH = vec2(winW * W, winH * 1080.0) * 0.5;
607
+ float kick = clamp((AUDIO_BASS - 1.0) / 3.0, 0.0, 1.0);
608
+ float drive = clamp(0.5 * AUDIO_BANDS[1] + 0.4 * AUDIO_BANDS[3] + 0.4 * kick, 0.0, 1.3) * reactivity;
609
+
610
+ vec3 col = groundColor.rgb;
611
+ float wd = winSD(D);
612
+ float inside = fillAA(wd);
613
+ if (inside > 0.0) {
614
+ vec3 m = windowColor(D);
615
+ if (flare > 0.0) m += flareAdd(D);
616
+ col = mix(col, m, inside);
617
+ }
618
+ float ink = strokeAA(wd, 1.5 + 2.0 * beatPulse(10.0) * reactivity) * rev(0.1);
619
+ float dim = 0.0;
620
+
621
+ vec2 pan = vec2(0.0);
622
+ if (deckLayout == 0) {
623
+ pan = max(deckLeft(D, drive), deckRight(D, drive));
624
+ if (marks) {
625
+ vec2 o = gWH + 12.0;
626
+ pan.x = max(pan.x, plusMark(D - (gWC + o * vec2(-1.0, -1.0)), 6.0));
627
+ pan.x = max(pan.x, plusMark(D - (gWC + o * vec2(1.0, -1.0)), 6.0));
628
+ pan.x = max(pan.x, plusMark(D - (gWC + o * vec2(-1.0, 1.0)), 6.0));
629
+ pan.x = max(pan.x, plusMark(D - (gWC + o * vec2(1.0, 1.0)), 6.0));
630
+ }
631
+ } else {
632
+ pan = deckTiles(D, drive);
633
+ }
634
+ ink = max(ink, pan.x);
635
+ dim = max(dim, pan.y);
636
+
637
+ vec4 tm = HAS_TEXT ? texture(TEXTMASK, vUv) : vec4(0.0);
638
+ bool micro = D.y > 395.0 && D.y < 720.0 && (D.x < 276.0 || D.x > W - 276.0);
639
+ float gate = (deckLayout == 0) != micro ? 1.0 : 0.0;
640
+ ink = max(ink, tm.r * gate * rev(0.25));
641
+
642
+ col = mix(col, inkColor.rgb, clamp(dim, 0.0, 1.0) * dimAmount);
643
+ col = mix(col, inkColor.rgb, clamp(ink, 0.0, 1.0));
644
+ fragColor = vec4(col, 1.0);
645
+ }
@@ -0,0 +1,38 @@
1
+ // hud-deck pass 0: pro-smoothed spectrum columns, persistent in specState (row 0 of the buffer).
2
+ // 256 log-spaced columns startFreq..endFreq. Each column takes the maximum of four taps of the 512-bin
3
+ // audioFFT (bin s sits near 29.3 + 46.875 * s Hz), is windowed by floorLevel / ceilLevel and shaped by
4
+ // a power, lifts its neighbours by 0.78^distance (peak preserving), then follows with attack / release.
5
+ const int NCOL = 256;
6
+ float specAtHz(float hz) {
7
+ float s = (hz - 29.3) / 46.875;
8
+ return texture(audioFFT, vec2(clamp((s + 0.5) / 512.0, 0.0, 1.0), 0.5)).r;
9
+ }
10
+ float colRaw(int i) {
11
+ float ratio = endFreq / startFreq;
12
+ float f0 = startFreq * pow(ratio, float(i) / float(NCOL));
13
+ float f1 = startFreq * pow(ratio, float(i + 1) / float(NCOL));
14
+ float v = 0.0;
15
+ for (int k = 0; k < 4; k++) v = max(v, specAtHz(mix(f0, f1, (float(k) + 0.5) / 4.0)));
16
+ float x = clamp((v - floorLevel) / max(ceilLevel - floorLevel, 0.01), 0.0, 1.0);
17
+ return pow(x, specExp);
18
+ }
19
+ float colSmooth(int i) {
20
+ float v = colRaw(i);
21
+ for (int d = 1; d <= 3; d++) {
22
+ float w = pow(0.78, float(d));
23
+ if (i - d >= 0) v = max(v, colRaw(i - d) * w);
24
+ if (i + d < NCOL) v = max(v, colRaw(i + d) * w);
25
+ }
26
+ return v;
27
+ }
28
+ void main() {
29
+ ivec2 px = ivec2(gl_FragCoord.xy);
30
+ vec4 prev = texelFetch(specState, px, 0);
31
+ if (px.y == 0 && px.x < NCOL) {
32
+ float raw = colSmooth(px.x);
33
+ float k = 1.0 - exp(-TIMEDELTA / max((raw > prev.r ? attackMs : releaseMs) * 0.001, 0.0005));
34
+ fragColor = vec4(prev.r + (raw - prev.r) * k, 0.0, 0.0, 1.0);
35
+ return;
36
+ }
37
+ fragColor = vec4(0.0);
38
+ }
@@ -0,0 +1 @@
1
+ {"version":1,"template":"lattice","preset":"cobalt-fine","input":{"video":"test-media/clip-01.mp4","audio":"test-media/beat-132.mp3","startSec":0},"durationSec":4,"seed":47,"out":"lattice-cobalt-fine"}
@@ -0,0 +1 @@
1
+ {"version":1,"template":"lattice","preset":"ink-yellow","input":{"video":"test-media/clip-01.mp4","audio":"test-media/beat-132.mp3","startSec":0},"durationSec":4,"seed":31,"out":"lattice-ink-yellow"}