agentvfx 0.0.0-stage → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +8 -0
- package/GEMINI.md +1 -0
- package/LICENSE +202 -0
- package/README.md +228 -2
- package/package.json +35 -4
- package/skills/agentvfx/LICENSE +202 -0
- package/skills/agentvfx/NOTICE +50 -0
- package/skills/agentvfx/SKILL.md +90 -0
- package/skills/agentvfx/engine/core/constants.mjs +84 -0
- package/skills/agentvfx/engine/core/flash-constants.mjs +23 -0
- package/skills/agentvfx/engine/core/flash.mjs +240 -0
- package/skills/agentvfx/engine/core/mark.mjs +25 -0
- package/skills/agentvfx/engine/core/palettes.mjs +36 -0
- package/skills/agentvfx/engine/core/schedule.mjs +85 -0
- package/skills/agentvfx/engine/core/templates.mjs +43 -0
- package/skills/agentvfx/engine/core/util.mjs +167 -0
- package/skills/agentvfx/engine/core/validate.mjs +334 -0
- package/skills/agentvfx/engine/node/analysis.mjs +172 -0
- package/skills/agentvfx/engine/node/audio.mjs +621 -0
- package/skills/agentvfx/engine/node/board.mjs +24 -0
- package/skills/agentvfx/engine/node/chrome.mjs +349 -0
- package/skills/agentvfx/engine/node/encode.mjs +110 -0
- package/skills/agentvfx/engine/node/eye.mjs +77 -0
- package/skills/agentvfx/engine/node/footage.mjs +129 -0
- package/skills/agentvfx/engine/node/frame-worker.mjs +39 -0
- package/skills/agentvfx/engine/node/host.mjs +31 -0
- package/skills/agentvfx/engine/node/job.mjs +181 -0
- package/skills/agentvfx/engine/node/png.mjs +112 -0
- package/skills/agentvfx/engine/node/render.mjs +161 -0
- package/skills/agentvfx/engine/node/stage-capture.mjs +187 -0
- package/skills/agentvfx/engine/node/stage-serve.mjs +72 -0
- package/skills/agentvfx/engine/node/stills.mjs +100 -0
- package/skills/agentvfx/engine/node/ws-server.mjs +132 -0
- package/skills/agentvfx/engine/web/gl.mjs +319 -0
- package/skills/agentvfx/engine/web/glsl-common.mjs +78 -0
- package/skills/agentvfx/engine/web/init.js +23 -0
- package/skills/agentvfx/engine/web/prelude.mjs +150 -0
- package/skills/agentvfx/engine/web/render.html +11 -0
- package/skills/agentvfx/engine/web/render.mjs +388 -0
- package/skills/agentvfx/engine/web/scale.mjs +15 -0
- package/skills/agentvfx/engine/web/text.mjs +158 -0
- package/skills/agentvfx/plates/terminalcore/README.md +61 -0
- package/skills/agentvfx/plates/terminalcore/__pycache__/crt.cpython-313.pyc +0 -0
- package/skills/agentvfx/plates/terminalcore/__pycache__/font.cpython-313.pyc +0 -0
- package/skills/agentvfx/plates/terminalcore/__pycache__/gallery.cpython-313.pyc +0 -0
- package/skills/agentvfx/plates/terminalcore/__pycache__/gallery_mats.cpython-313.pyc +0 -0
- package/skills/agentvfx/plates/terminalcore/__pycache__/gallery_room.cpython-313.pyc +0 -0
- package/skills/agentvfx/plates/terminalcore/__pycache__/materials.cpython-313.pyc +0 -0
- package/skills/agentvfx/plates/terminalcore/__pycache__/nodekit.cpython-313.pyc +0 -0
- package/skills/agentvfx/plates/terminalcore/__pycache__/room.cpython-313.pyc +0 -0
- package/skills/agentvfx/plates/terminalcore/__pycache__/shots.cpython-313.pyc +0 -0
- package/skills/agentvfx/plates/terminalcore/__pycache__/textures.cpython-313.pyc +0 -0
- package/skills/agentvfx/plates/terminalcore/__pycache__/wall.cpython-313.pyc +0 -0
- package/skills/agentvfx/plates/terminalcore/crt.py +143 -0
- package/skills/agentvfx/plates/terminalcore/font.py +80 -0
- package/skills/agentvfx/plates/terminalcore/gallery.py +61 -0
- package/skills/agentvfx/plates/terminalcore/gallery_mats.py +144 -0
- package/skills/agentvfx/plates/terminalcore/gallery_room.py +126 -0
- package/skills/agentvfx/plates/terminalcore/materials.py +170 -0
- package/skills/agentvfx/plates/terminalcore/nodekit.py +87 -0
- package/skills/agentvfx/plates/terminalcore/room.py +82 -0
- package/skills/agentvfx/plates/terminalcore/scene.py +219 -0
- package/skills/agentvfx/plates/terminalcore/shots.py +48 -0
- package/skills/agentvfx/plates/terminalcore/textures.py +79 -0
- package/skills/agentvfx/plates/terminalcore/wall.py +103 -0
- package/skills/agentvfx/references/plates.md +22 -0
- package/skills/agentvfx/references/template-format.md +149 -0
- package/skills/agentvfx/references/web.md +63 -0
- package/skills/agentvfx/runtime/agentvfx.js +708 -0
- package/skills/agentvfx/schemas/fx-score.schema.json +98 -0
- package/skills/agentvfx/scripts/export-web.mjs +157 -0
- package/skills/agentvfx/scripts/loop.mjs +129 -0
- package/skills/agentvfx/scripts/make-beat.mjs +133 -0
- package/skills/agentvfx/scripts/plate.mjs +82 -0
- package/skills/agentvfx/scripts/vfx.mjs +173 -0
- package/skills/agentvfx/templates/_test/feedback-counter/fx.json +11 -0
- package/skills/agentvfx/templates/_test/feedback-counter/main.frag +4 -0
- package/skills/agentvfx/templates/_test/feedback-counter/pass0.frag +4 -0
- package/skills/agentvfx/templates/_test/gradient/fx.json +23 -0
- package/skills/agentvfx/templates/_test/gradient/main.frag +5 -0
- package/skills/agentvfx/templates/_test/identity/fx.json +10 -0
- package/skills/agentvfx/templates/_test/identity/main.frag +4 -0
- package/skills/agentvfx/templates/_test/strobe/fx.json +14 -0
- package/skills/agentvfx/templates/_test/strobe/main.frag +6 -0
- package/skills/agentvfx/templates/_test/text-probe/fx.json +15 -0
- package/skills/agentvfx/templates/_test/text-probe/main.frag +6 -0
- package/skills/agentvfx/templates/brutal/NOTES.md +14 -0
- package/skills/agentvfx/templates/brutal/_src/boot-log/def.mjs +57 -0
- package/skills/agentvfx/templates/brutal/_src/boot-log/main.src.frag +129 -0
- package/skills/agentvfx/templates/brutal/_src/build.mjs +33 -0
- package/skills/agentvfx/templates/brutal/_src/halftone-field/def.mjs +72 -0
- package/skills/agentvfx/templates/brutal/_src/halftone-field/main.src.frag +94 -0
- package/skills/agentvfx/templates/brutal/_src/hud-deck/deck-left.src.glsl +100 -0
- package/skills/agentvfx/templates/brutal/_src/hud-deck/deck-right.src.glsl +61 -0
- package/skills/agentvfx/templates/brutal/_src/hud-deck/deck-tiles.src.glsl +153 -0
- package/skills/agentvfx/templates/brutal/_src/hud-deck/def.mjs +82 -0
- package/skills/agentvfx/templates/brutal/_src/hud-deck/main.src.frag +110 -0
- package/skills/agentvfx/templates/brutal/_src/hud-deck/pass0.src.frag +38 -0
- package/skills/agentvfx/templates/brutal/_src/shared/defs.mjs +28 -0
- package/skills/agentvfx/templates/brutal/_src/shared/icons.glsl +72 -0
- package/skills/agentvfx/templates/brutal/_src/shared/lib.glsl +115 -0
- package/skills/agentvfx/templates/brutal/_src/shared/screen.glsl +43 -0
- package/skills/agentvfx/templates/brutal/boot-log/demo-acid.json +1 -0
- package/skills/agentvfx/templates/brutal/boot-log/demo-phosphor.json +1 -0
- package/skills/agentvfx/templates/brutal/boot-log/demo-ultramarine.json +1 -0
- package/skills/agentvfx/templates/brutal/boot-log/fx.json +257 -0
- package/skills/agentvfx/templates/brutal/boot-log/main.frag +242 -0
- package/skills/agentvfx/templates/brutal/collage/_src/00-lib.glsl +73 -0
- package/skills/agentvfx/templates/brutal/collage/_src/10-spectrum-scope.glsl +73 -0
- package/skills/agentvfx/templates/brutal/collage/_src/20-meter-readout-cross.glsl +87 -0
- package/skills/agentvfx/templates/brutal/collage/_src/30-footage-fillers.glsl +92 -0
- package/skills/agentvfx/templates/brutal/collage/_src/40-editorial.glsl +232 -0
- package/skills/agentvfx/templates/brutal/collage/_src/50-typefx.glsl +163 -0
- package/skills/agentvfx/templates/brutal/collage/_src/60-scene-lib.glsl +104 -0
- package/skills/agentvfx/templates/brutal/collage/_src/61-scene-specimen.glsl +71 -0
- package/skills/agentvfx/templates/brutal/collage/_src/62-scene-wiring.glsl +96 -0
- package/skills/agentvfx/templates/brutal/collage/_src/63-scene-fieldcut.glsl +119 -0
- package/skills/agentvfx/templates/brutal/collage/_src/64-scene-pattern.glsl +64 -0
- package/skills/agentvfx/templates/brutal/collage/_src/641-scene-anatomy.glsl +49 -0
- package/skills/agentvfx/templates/brutal/collage/_src/642-scene-deck.glsl +78 -0
- package/skills/agentvfx/templates/brutal/collage/_src/643-scene-bootlog.glsl +60 -0
- package/skills/agentvfx/templates/brutal/collage/_src/644-scene-tunnel.glsl +48 -0
- package/skills/agentvfx/templates/brutal/collage/_src/645-scene-runner.glsl +42 -0
- package/skills/agentvfx/templates/brutal/collage/_src/646-scene-ascii.glsl +66 -0
- package/skills/agentvfx/templates/brutal/collage/_src/647-scene-cubewall.glsl +80 -0
- package/skills/agentvfx/templates/brutal/collage/_src/648-scene-vortex.glsl +46 -0
- package/skills/agentvfx/templates/brutal/collage/_src/649-scene-sticker.glsl +72 -0
- package/skills/agentvfx/templates/brutal/collage/_src/65-scene-main.glsl +1 -0
- package/skills/agentvfx/templates/brutal/collage/_src/650-scene-ribbon.glsl +55 -0
- package/skills/agentvfx/templates/brutal/collage/_src/651-scene-slab.glsl +38 -0
- package/skills/agentvfx/templates/brutal/collage/_src/652-scene-framedial.glsl +79 -0
- package/skills/agentvfx/templates/brutal/collage/_src/653-scene-tilt.glsl +40 -0
- package/skills/agentvfx/templates/brutal/collage/_src/654-scene-marquee.glsl +45 -0
- package/skills/agentvfx/templates/brutal/collage/_src/655-scene-lens.glsl +57 -0
- package/skills/agentvfx/templates/brutal/collage/_src/656-scene-liquid.glsl +35 -0
- package/skills/agentvfx/templates/brutal/collage/_src/657-scene-panelgrid.glsl +75 -0
- package/skills/agentvfx/templates/brutal/collage/_src/658-scene-mirror.glsl +49 -0
- package/skills/agentvfx/templates/brutal/collage/_src/66-scene-main.glsl +27 -0
- package/skills/agentvfx/templates/brutal/collage/_src/90-main.glsl +120 -0
- package/skills/agentvfx/templates/brutal/collage/_src/build.mjs +24 -0
- package/skills/agentvfx/templates/brutal/collage/_src/sync-presets.mjs +16 -0
- package/skills/agentvfx/templates/brutal/collage/demo-bone-lime.json +1 -0
- package/skills/agentvfx/templates/brutal/collage/demo-lime-sparse.json +1 -0
- package/skills/agentvfx/templates/brutal/collage/demo-orange-dense.json +1 -0
- package/skills/agentvfx/templates/brutal/collage/demo-ultra-slow.json +1 -0
- package/skills/agentvfx/templates/brutal/collage/fx.json +4882 -0
- package/skills/agentvfx/templates/brutal/collage/layout.mjs +97 -0
- package/skills/agentvfx/templates/brutal/collage/layouts.json +366 -0
- package/skills/agentvfx/templates/brutal/collage/main.frag +2367 -0
- package/skills/agentvfx/templates/brutal/collage/pass0.frag +265 -0
- package/skills/agentvfx/templates/brutal/halftone-field/demo-acid.json +1 -0
- package/skills/agentvfx/templates/brutal/halftone-field/demo-ascii.json +1 -0
- package/skills/agentvfx/templates/brutal/halftone-field/demo-dither.json +1 -0
- package/skills/agentvfx/templates/brutal/halftone-field/demo-orange.json +1 -0
- package/skills/agentvfx/templates/brutal/halftone-field/demo-phosphor.json +1 -0
- package/skills/agentvfx/templates/brutal/halftone-field/demo-ultramarine.json +1 -0
- package/skills/agentvfx/templates/brutal/halftone-field/fx.json +474 -0
- package/skills/agentvfx/templates/brutal/halftone-field/main.frag +248 -0
- package/skills/agentvfx/templates/brutal/hud-deck/demo-acid.json +1 -0
- package/skills/agentvfx/templates/brutal/hud-deck/demo-night.json +1 -0
- package/skills/agentvfx/templates/brutal/hud-deck/demo-octagon.json +1 -0
- package/skills/agentvfx/templates/brutal/hud-deck/demo-ultramarine.json +1 -0
- package/skills/agentvfx/templates/brutal/hud-deck/fx.json +601 -0
- package/skills/agentvfx/templates/brutal/hud-deck/main.frag +645 -0
- package/skills/agentvfx/templates/brutal/hud-deck/pass0.frag +38 -0
- package/skills/agentvfx/templates/brutal/lattice/demo-cobalt-fine.json +1 -0
- package/skills/agentvfx/templates/brutal/lattice/demo-ink-yellow.json +1 -0
- package/skills/agentvfx/templates/brutal/lattice/demo-vermilion.json +1 -0
- package/skills/agentvfx/templates/brutal/lattice/demo-violet-slow.json +1 -0
- package/skills/agentvfx/templates/brutal/lattice/fx.json +130 -0
- package/skills/agentvfx/templates/brutal/lattice/main.frag +175 -0
- package/skills/agentvfx/templates/brutal/lattice/pass0.frag +29 -0
- package/skills/agentvfx/templates/glitch/block-glitch/demo-mosaic.json +1 -0
- package/skills/agentvfx/templates/glitch/block-glitch/demo-onset.json +1 -0
- package/skills/agentvfx/templates/glitch/block-glitch/demo-static.json +1 -0
- package/skills/agentvfx/templates/glitch/block-glitch/demo-tear.json +1 -0
- package/skills/agentvfx/templates/glitch/block-glitch/fx.json +54 -0
- package/skills/agentvfx/templates/glitch/block-glitch/main.frag +132 -0
- package/skills/agentvfx/templates/glitch/block-glitch/pass0.frag +12 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/NOTES.md +13 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/build-passes.mjs +162 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/demo-chunk.json +1 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/demo-hue.json +1 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/demo-kick.json +1 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/demo-streak.json +1 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/demo-vertical.json +1 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/fx.json +60 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/main.frag +83 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/pass0.frag +64 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/pass1.frag +66 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/pass2.frag +66 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/pass3.frag +66 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/pass4.frag +66 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/pass5.frag +66 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/pass6.frag +66 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/pass7.frag +66 -0
- package/skills/agentvfx/templates/glitch/pixel-sort/pass8.frag +66 -0
- package/skills/agentvfx/templates/glitch/rgb-split/demo-diagonal-stutter.json +1 -0
- package/skills/agentvfx/templates/glitch/rgb-split/demo-hard.json +1 -0
- package/skills/agentvfx/templates/glitch/rgb-split/demo-kick.json +1 -0
- package/skills/agentvfx/templates/glitch/rgb-split/demo-radial.json +1 -0
- package/skills/agentvfx/templates/glitch/rgb-split/fx.json +46 -0
- package/skills/agentvfx/templates/glitch/rgb-split/main.frag +76 -0
- package/skills/agentvfx/templates/glitch/vhs/demo-clean.json +1 -0
- package/skills/agentvfx/templates/glitch/vhs/demo-crash.json +1 -0
- package/skills/agentvfx/templates/glitch/vhs/demo-tape.json +1 -0
- package/skills/agentvfx/templates/glitch/vhs/demo-worn.json +1 -0
- package/skills/agentvfx/templates/glitch/vhs/fx.json +46 -0
- package/skills/agentvfx/templates/glitch/vhs/main.frag +96 -0
- package/skills/agentvfx/templates/impact/impact-1bit/demo-onebit-bayer.json +1 -0
- package/skills/agentvfx/templates/impact/impact-1bit/fx.json +45 -0
- package/skills/agentvfx/templates/impact/impact-1bit/main.frag +64 -0
- package/skills/agentvfx/templates/impact/impact-invert/demo-invert-snap.json +1 -0
- package/skills/agentvfx/templates/impact/impact-invert/fx.json +37 -0
- package/skills/agentvfx/templates/impact/impact-invert/main.frag +44 -0
- package/skills/agentvfx/templates/impact/punch-shake/demo-punch-hard.json +1 -0
- package/skills/agentvfx/templates/impact/punch-shake/fx.json +36 -0
- package/skills/agentvfx/templates/impact/punch-shake/main.frag +62 -0
- package/skills/agentvfx/templates/impact/rgb-hit/demo-rgb-slam.json +1 -0
- package/skills/agentvfx/templates/impact/rgb-hit/fx.json +39 -0
- package/skills/agentvfx/templates/impact/rgb-hit/main.frag +62 -0
- package/skills/agentvfx/templates/impact/signal-cut/demo-lime-hold.json +1 -0
- package/skills/agentvfx/templates/impact/signal-cut/demo-lime.json +1 -0
- package/skills/agentvfx/templates/impact/signal-cut/demo-orange.json +1 -0
- package/skills/agentvfx/templates/impact/signal-cut/demo-ultramarine.json +1 -0
- package/skills/agentvfx/templates/impact/signal-cut/fx.json +83 -0
- package/skills/agentvfx/templates/impact/signal-cut/main.frag +101 -0
- package/skills/agentvfx/templates/impact/signal-cut/pass0.frag +68 -0
- package/skills/agentvfx/templates/impact/speedline-burst/demo-speed-white.json +1 -0
- package/skills/agentvfx/templates/impact/speedline-burst/fx.json +44 -0
- package/skills/agentvfx/templates/impact/speedline-burst/main.frag +68 -0
- package/skills/agentvfx/templates/impact/strobe-burst/demo-strobe-white-16.json +1 -0
- package/skills/agentvfx/templates/impact/strobe-burst/fx.json +42 -0
- package/skills/agentvfx/templates/impact/strobe-burst/main.frag +43 -0
- package/skills/agentvfx/templates/light/anamorphic-streak/demo-anamorphic-cinema.json +10 -0
- package/skills/agentvfx/templates/light/anamorphic-streak/demo-data.json +10 -0
- package/skills/agentvfx/templates/light/anamorphic-streak/fx.json +47 -0
- package/skills/agentvfx/templates/light/anamorphic-streak/main.frag +45 -0
- package/skills/agentvfx/templates/light/anamorphic-streak/pass0.frag +22 -0
- package/skills/agentvfx/templates/light/anamorphic-streak/pass1.frag +16 -0
- package/skills/agentvfx/templates/light/anamorphic-streak/pass2.frag +16 -0
- package/skills/agentvfx/templates/light/anamorphic-streak/pass3.frag +16 -0
- package/skills/agentvfx/templates/light/bloom-glow/demo-clip01-low.json +11 -0
- package/skills/agentvfx/templates/light/bloom-glow/demo-neon-night.json +10 -0
- package/skills/agentvfx/templates/light/bloom-glow/demo-phosphor.json +11 -0
- package/skills/agentvfx/templates/light/bloom-glow/fx.json +53 -0
- package/skills/agentvfx/templates/light/bloom-glow/main.frag +85 -0
- package/skills/agentvfx/templates/light/bloom-glow/pass0.frag +21 -0
- package/skills/agentvfx/templates/light/bloom-glow/pass1.frag +50 -0
- package/skills/agentvfx/templates/light/bloom-glow/pass2.frag +44 -0
- package/skills/agentvfx/templates/light/bloom-glow/pass3.frag +32 -0
- package/skills/agentvfx/templates/light/bloom-glow/pass4.frag +48 -0
- package/skills/agentvfx/templates/light/bloom-glow/pass5.frag +46 -0
- package/skills/agentvfx/templates/light/god-rays/demo-golden-hour.json +10 -0
- package/skills/agentvfx/templates/light/god-rays/demo-point-lamp.json +10 -0
- package/skills/agentvfx/templates/light/god-rays/fx.json +39 -0
- package/skills/agentvfx/templates/light/god-rays/main.frag +54 -0
- package/skills/agentvfx/templates/light/lens-flare/demo-clip01-bar.json +11 -0
- package/skills/agentvfx/templates/light/lens-flare/demo-eye-bar.json +10 -0
- package/skills/agentvfx/templates/light/lens-flare/demo-sun-ghosts.json +10 -0
- package/skills/agentvfx/templates/light/lens-flare/fx.json +49 -0
- package/skills/agentvfx/templates/light/lens-flare/main.frag +86 -0
- package/skills/agentvfx/templates/light/lens-flare/pass0.frag +24 -0
- package/skills/agentvfx/templates/light/light-leak/demo-slit.json +10 -0
- package/skills/agentvfx/templates/light/light-leak/demo-vintage-burn.json +10 -0
- package/skills/agentvfx/templates/light/light-leak/fx.json +40 -0
- package/skills/agentvfx/templates/light/light-leak/main.frag +46 -0
- package/skills/agentvfx/templates/light/light-stage/fx.json +29 -0
- package/skills/agentvfx/templates/light/light-stage/main.frag +56 -0
- package/skills/agentvfx/templates/light/light-sweep/demo-hard-bar.json +12 -0
- package/skills/agentvfx/templates/light/light-sweep/demo-logo-sweep.json +10 -0
- package/skills/agentvfx/templates/light/light-sweep/demo-onset.json +11 -0
- package/skills/agentvfx/templates/light/light-sweep/fx.json +45 -0
- package/skills/agentvfx/templates/light/light-sweep/main.frag +29 -0
- package/skills/agentvfx/templates/light/light-sweep/pass0.frag +17 -0
- package/skills/agentvfx/templates/light/light-sweep/pass1.frag +15 -0
- package/skills/agentvfx/templates/light/neon-saber/demo-hairline.json +10 -0
- package/skills/agentvfx/templates/light/neon-saber/demo-saber-laser.json +10 -0
- package/skills/agentvfx/templates/light/neon-saber/fx.json +48 -0
- package/skills/agentvfx/templates/light/neon-saber/main.frag +27 -0
- package/skills/agentvfx/templates/light/neon-saber/pass0.frag +46 -0
- package/skills/agentvfx/templates/light/neon-saber/pass1.frag +15 -0
- package/skills/agentvfx/templates/psychedelic/echo-flow/demo-trail.json +1 -0
- package/skills/agentvfx/templates/psychedelic/echo-flow/fx.json +38 -0
- package/skills/agentvfx/templates/psychedelic/echo-flow/main.frag +19 -0
- package/skills/agentvfx/templates/psychedelic/echo-flow/pass0.frag +16 -0
- package/skills/agentvfx/templates/psychedelic/echo-flow/pass1.frag +20 -0
- package/skills/agentvfx/templates/psychedelic/echo-flow/pass2.frag +11 -0
- package/skills/agentvfx/templates/psychedelic/echo-flow/pass3.frag +4 -0
- package/skills/agentvfx/templates/psychedelic/hologram-scan/demo-cyan.json +1 -0
- package/skills/agentvfx/templates/psychedelic/hologram-scan/fx.json +36 -0
- package/skills/agentvfx/templates/psychedelic/hologram-scan/main.frag +30 -0
- package/skills/agentvfx/templates/psychedelic/kaleido-fold/demo-six.json +1 -0
- package/skills/agentvfx/templates/psychedelic/kaleido-fold/fx.json +37 -0
- package/skills/agentvfx/templates/psychedelic/kaleido-fold/main.frag +10 -0
- package/skills/agentvfx/templates/psychedelic/kaleido-fold/pass0.frag +34 -0
- package/skills/agentvfx/templates/psychedelic/mosh-melt/demo-classic.json +1 -0
- package/skills/agentvfx/templates/psychedelic/mosh-melt/fx.json +38 -0
- package/skills/agentvfx/templates/psychedelic/mosh-melt/main.frag +20 -0
- package/skills/agentvfx/templates/psychedelic/mosh-melt/pass0.frag +22 -0
- package/skills/agentvfx/templates/psychedelic/sacred/NOTES.md +13 -0
- package/skills/agentvfx/templates/psychedelic/sacred/demo-classic.json +1 -0
- package/skills/agentvfx/templates/psychedelic/sacred/demo-halo.json +1 -0
- package/skills/agentvfx/templates/psychedelic/sacred/demo-slow-tide.json +1 -0
- package/skills/agentvfx/templates/psychedelic/sacred/demo-thermal.json +1 -0
- package/skills/agentvfx/templates/psychedelic/sacred/fx.json +263 -0
- package/skills/agentvfx/templates/psychedelic/sacred/main.frag +109 -0
- package/skills/agentvfx/templates/psychedelic/sacred/pass0.frag +25 -0
- package/skills/agentvfx/templates/psychedelic/sacred/pass1.frag +23 -0
- package/skills/agentvfx/templates/psychedelic/tidal-bands/demo-classic.json +1 -0
- package/skills/agentvfx/templates/psychedelic/tidal-bands/fx.json +37 -0
- package/skills/agentvfx/templates/psychedelic/tidal-bands/main.frag +54 -0
- package/skills/agentvfx/templates/scope/_chrome.glsl +242 -0
- package/skills/agentvfx/templates/scope/goniometer/demo-boot-green.json +1 -0
- package/skills/agentvfx/templates/scope/goniometer/demo-field-lime.json +1 -0
- package/skills/agentvfx/templates/scope/goniometer/demo-field-ultramarine.json +1 -0
- package/skills/agentvfx/templates/scope/goniometer/demo-glow-phosphor.json +1 -0
- package/skills/agentvfx/templates/scope/goniometer/demo-hud-black.json +1 -0
- package/skills/agentvfx/templates/scope/goniometer/fx.json +635 -0
- package/skills/agentvfx/templates/scope/goniometer/main.frag +33 -0
- package/skills/agentvfx/templates/scope/goniometer/pass0.frag +58 -0
- package/skills/agentvfx/templates/scope/goniometer/pass1.frag +43 -0
- package/skills/agentvfx/templates/scope/goniometer/pass2.frag +12 -0
- package/skills/agentvfx/templates/scope/goniometer/pass3.frag +12 -0
- package/skills/agentvfx/templates/scope/goniometer/pass4.frag +12 -0
- package/skills/agentvfx/templates/scope/goniometer/pass5.frag +12 -0
- package/skills/agentvfx/templates/scope/goniometer/pass6.frag +251 -0
- package/skills/agentvfx/templates/scope/scope-polar/demo-boot-green.json +1 -0
- package/skills/agentvfx/templates/scope/scope-polar/demo-field-lime.json +1 -0
- package/skills/agentvfx/templates/scope/scope-polar/demo-field-ultramarine.json +1 -0
- package/skills/agentvfx/templates/scope/scope-polar/demo-glow-phosphor.json +1 -0
- package/skills/agentvfx/templates/scope/scope-polar/demo-hud-black.json +1 -0
- package/skills/agentvfx/templates/scope/scope-polar/fx.json +686 -0
- package/skills/agentvfx/templates/scope/scope-polar/main.frag +39 -0
- package/skills/agentvfx/templates/scope/scope-polar/pass0.frag +84 -0
- package/skills/agentvfx/templates/scope/scope-polar/pass1.frag +49 -0
- package/skills/agentvfx/templates/scope/scope-polar/pass2.frag +12 -0
- package/skills/agentvfx/templates/scope/scope-polar/pass3.frag +12 -0
- package/skills/agentvfx/templates/scope/scope-polar/pass4.frag +12 -0
- package/skills/agentvfx/templates/scope/scope-polar/pass5.frag +12 -0
- package/skills/agentvfx/templates/scope/scope-polar/pass6.frag +251 -0
- package/skills/agentvfx/templates/scope/scope-triggered/demo-boot-green.json +1 -0
- package/skills/agentvfx/templates/scope/scope-triggered/demo-field-lime.json +1 -0
- package/skills/agentvfx/templates/scope/scope-triggered/demo-field-ultramarine.json +1 -0
- package/skills/agentvfx/templates/scope/scope-triggered/demo-glow-phosphor.json +1 -0
- package/skills/agentvfx/templates/scope/scope-triggered/demo-hud-black.json +1 -0
- package/skills/agentvfx/templates/scope/scope-triggered/fx.json +712 -0
- package/skills/agentvfx/templates/scope/scope-triggered/main.frag +36 -0
- package/skills/agentvfx/templates/scope/scope-triggered/pass0.frag +78 -0
- package/skills/agentvfx/templates/scope/scope-triggered/pass1.frag +50 -0
- package/skills/agentvfx/templates/scope/scope-triggered/pass2.frag +12 -0
- package/skills/agentvfx/templates/scope/scope-triggered/pass3.frag +12 -0
- package/skills/agentvfx/templates/scope/scope-triggered/pass4.frag +12 -0
- package/skills/agentvfx/templates/scope/scope-triggered/pass5.frag +12 -0
- package/skills/agentvfx/templates/scope/scope-triggered/pass6.frag +251 -0
- package/skills/agentvfx/templates/scope/spectrogram-scroll/demo-boot-green.json +1 -0
- package/skills/agentvfx/templates/scope/spectrogram-scroll/demo-field-lime.json +1 -0
- package/skills/agentvfx/templates/scope/spectrogram-scroll/demo-field-ultramarine.json +1 -0
- package/skills/agentvfx/templates/scope/spectrogram-scroll/demo-glow-phosphor.json +1 -0
- package/skills/agentvfx/templates/scope/spectrogram-scroll/demo-hud-black.json +1 -0
- package/skills/agentvfx/templates/scope/spectrogram-scroll/fx.json +595 -0
- package/skills/agentvfx/templates/scope/spectrogram-scroll/main.frag +83 -0
- package/skills/agentvfx/templates/scope/spectrogram-scroll/pass0.frag +52 -0
- package/skills/agentvfx/templates/scope/spectrogram-scroll/pass1.frag +251 -0
- package/skills/agentvfx/templates/scope/xy-phosphor/demo-boot-green.json +1 -0
- package/skills/agentvfx/templates/scope/xy-phosphor/demo-field-lime.json +1 -0
- package/skills/agentvfx/templates/scope/xy-phosphor/demo-field-ultramarine.json +1 -0
- package/skills/agentvfx/templates/scope/xy-phosphor/demo-glow-phosphor.json +1 -0
- package/skills/agentvfx/templates/scope/xy-phosphor/demo-hud-black.json +1 -0
- package/skills/agentvfx/templates/scope/xy-phosphor/fx.json +642 -0
- package/skills/agentvfx/templates/scope/xy-phosphor/main.frag +33 -0
- package/skills/agentvfx/templates/scope/xy-phosphor/pass0.frag +56 -0
- package/skills/agentvfx/templates/scope/xy-phosphor/pass1.frag +44 -0
- package/skills/agentvfx/templates/scope/xy-phosphor/pass2.frag +12 -0
- package/skills/agentvfx/templates/scope/xy-phosphor/pass3.frag +12 -0
- package/skills/agentvfx/templates/scope/xy-phosphor/pass4.frag +12 -0
- package/skills/agentvfx/templates/scope/xy-phosphor/pass5.frag +12 -0
- package/skills/agentvfx/templates/scope/xy-phosphor/pass6.frag +251 -0
- package/skills/agentvfx/templates/spectrum/_src/bars-linear/fx.src.json +61 -0
- package/skills/agentvfx/templates/spectrum/_src/bars-linear/main.src.frag +112 -0
- package/skills/agentvfx/templates/spectrum/_src/bars-linear/pass0.src.frag +2 -0
- package/skills/agentvfx/templates/spectrum/_src/bars-mirror/fx.src.json +51 -0
- package/skills/agentvfx/templates/spectrum/_src/bars-mirror/main.src.frag +72 -0
- package/skills/agentvfx/templates/spectrum/_src/bars-mirror/pass0.src.frag +2 -0
- package/skills/agentvfx/templates/spectrum/_src/bass-circle/fx.src.json +56 -0
- package/skills/agentvfx/templates/spectrum/_src/bass-circle/main.src.frag +136 -0
- package/skills/agentvfx/templates/spectrum/_src/bass-circle/pass0.src.frag +2 -0
- package/skills/agentvfx/templates/spectrum/_src/build.mjs +68 -0
- package/skills/agentvfx/templates/spectrum/_src/label-bars/fx.src.json +54 -0
- package/skills/agentvfx/templates/spectrum/_src/label-bars/main.src.frag +102 -0
- package/skills/agentvfx/templates/spectrum/_src/label-bars/pass0.src.frag +2 -0
- package/skills/agentvfx/templates/spectrum/_src/shared/bars-fn.glsl +64 -0
- package/skills/agentvfx/templates/spectrum/_src/shared/bars-pass.glsl +22 -0
- package/skills/agentvfx/templates/spectrum/_src/shared/clock.glsl +7 -0
- package/skills/agentvfx/templates/spectrum/_src/shared/hud.glsl +50 -0
- package/skills/agentvfx/templates/spectrum/_src/shared/stage.glsl +74 -0
- package/skills/agentvfx/templates/spectrum/_src/spectrum-particles/fx.src.json +58 -0
- package/skills/agentvfx/templates/spectrum/_src/spectrum-particles/main.src.frag +119 -0
- package/skills/agentvfx/templates/spectrum/_src/spectrum-particles/pass0.src.frag +33 -0
- package/skills/agentvfx/templates/spectrum/_src/spectrum-radial/fx.src.json +56 -0
- package/skills/agentvfx/templates/spectrum/_src/spectrum-radial/main.src.frag +95 -0
- package/skills/agentvfx/templates/spectrum/_src/spectrum-radial/pass0.src.frag +2 -0
- package/skills/agentvfx/templates/spectrum/_src/waveform-line/fx.src.json +60 -0
- package/skills/agentvfx/templates/spectrum/_src/waveform-line/main.src.frag +98 -0
- package/skills/agentvfx/templates/spectrum/_src/waveform-line/pass0.src.frag +43 -0
- package/skills/agentvfx/templates/spectrum/bars-linear/demo-graph-acid.json +1 -0
- package/skills/agentvfx/templates/spectrum/bars-linear/demo-graph-black.json +1 -0
- package/skills/agentvfx/templates/spectrum/bars-linear/fx.json +632 -0
- package/skills/agentvfx/templates/spectrum/bars-linear/main.frag +233 -0
- package/skills/agentvfx/templates/spectrum/bars-linear/pass0.frag +91 -0
- package/skills/agentvfx/templates/spectrum/bars-mirror/demo-field-acid.json +1 -0
- package/skills/agentvfx/templates/spectrum/bars-mirror/demo-field-ultramarine.json +1 -0
- package/skills/agentvfx/templates/spectrum/bars-mirror/fx.json +539 -0
- package/skills/agentvfx/templates/spectrum/bars-mirror/main.frag +193 -0
- package/skills/agentvfx/templates/spectrum/bars-mirror/pass0.frag +91 -0
- package/skills/agentvfx/templates/spectrum/bass-circle/demo-bracket-black.json +1 -0
- package/skills/agentvfx/templates/spectrum/bass-circle/demo-bracket-ultramarine.json +1 -0
- package/skills/agentvfx/templates/spectrum/bass-circle/fx.json +552 -0
- package/skills/agentvfx/templates/spectrum/bass-circle/main.frag +258 -0
- package/skills/agentvfx/templates/spectrum/bass-circle/pass0.frag +91 -0
- package/skills/agentvfx/templates/spectrum/label-bars/demo-deck-black.json +1 -0
- package/skills/agentvfx/templates/spectrum/label-bars/demo-deck-ultramarine.json +1 -0
- package/skills/agentvfx/templates/spectrum/label-bars/fx.json +552 -0
- package/skills/agentvfx/templates/spectrum/label-bars/main.frag +223 -0
- package/skills/agentvfx/templates/spectrum/label-bars/pass0.frag +91 -0
- package/skills/agentvfx/templates/spectrum/spectrum-particles/demo-cloud-black.json +1 -0
- package/skills/agentvfx/templates/spectrum/spectrum-particles/demo-cloud-ultramarine.json +1 -0
- package/skills/agentvfx/templates/spectrum/spectrum-particles/fx.json +584 -0
- package/skills/agentvfx/templates/spectrum/spectrum-particles/main.frag +240 -0
- package/skills/agentvfx/templates/spectrum/spectrum-particles/pass0.frag +101 -0
- package/skills/agentvfx/templates/spectrum/spectrum-radial/demo-starburst-black.json +1 -0
- package/skills/agentvfx/templates/spectrum/spectrum-radial/demo-starburst-ultramarine.json +1 -0
- package/skills/agentvfx/templates/spectrum/spectrum-radial/fx.json +566 -0
- package/skills/agentvfx/templates/spectrum/spectrum-radial/main.frag +217 -0
- package/skills/agentvfx/templates/spectrum/spectrum-radial/pass0.frag +91 -0
- package/skills/agentvfx/templates/spectrum/waveform-line/demo-strip-acid.json +1 -0
- package/skills/agentvfx/templates/spectrum/waveform-line/demo-strip-black.json +1 -0
- package/skills/agentvfx/templates/spectrum/waveform-line/fx.json +481 -0
- package/skills/agentvfx/templates/spectrum/waveform-line/main.frag +219 -0
- package/skills/agentvfx/templates/spectrum/waveform-line/pass0.frag +48 -0
- package/skills/agentvfx/templates/spectrum/waveform-line/pass1.frag +86 -0
- package/skills/agentvfx/test/_render_light.mjs +38 -0
- package/skills/agentvfx/test/audio-stereo.test.mjs +45 -0
- package/skills/agentvfx/test/audio.test.mjs +257 -0
- package/skills/agentvfx/test/brutal.test.mjs +190 -0
- package/skills/agentvfx/test/concept-collage-layout.test.mjs +236 -0
- package/skills/agentvfx/test/concept-collage-scenes.test.mjs +305 -0
- package/skills/agentvfx/test/concept-collage-typefx.test.mjs +153 -0
- package/skills/agentvfx/test/concept-collage.test.mjs +84 -0
- package/skills/agentvfx/test/concept-lattice.test.mjs +133 -0
- package/skills/agentvfx/test/concept-signal-cut.test.mjs +172 -0
- package/skills/agentvfx/test/credit-overlay.test.mjs +58 -0
- package/skills/agentvfx/test/credit.test.mjs +54 -0
- package/skills/agentvfx/test/doctor.test.mjs +31 -0
- package/skills/agentvfx/test/encode.test.mjs +22 -0
- package/skills/agentvfx/test/fixtures/r7-collage-LAYOUTS.json +5780 -0
- package/skills/agentvfx/test/fixtures/score-bad-duration.json +7 -0
- package/skills/agentvfx/test/fixtures/score-bad-safety.json +8 -0
- package/skills/agentvfx/test/fixtures/score-identity-footage.json +8 -0
- package/skills/agentvfx/test/fixtures/score-missing-template.json +7 -0
- package/skills/agentvfx/test/fixtures/score-ok.json +8 -0
- package/skills/agentvfx/test/fixtures/score-strobe-12hz.json +8 -0
- package/skills/agentvfx/test/fixtures/score-text-probe.json +1 -0
- package/skills/agentvfx/test/flash-audit.test.mjs +150 -0
- package/skills/agentvfx/test/flash.test.mjs +83 -0
- package/skills/agentvfx/test/footage.test.mjs +88 -0
- package/skills/agentvfx/test/glitch.test.mjs +272 -0
- package/skills/agentvfx/test/impact.test.mjs +231 -0
- package/skills/agentvfx/test/imports.test.mjs +39 -0
- package/skills/agentvfx/test/light.test.mjs +200 -0
- package/skills/agentvfx/test/loop.test.mjs +80 -0
- package/skills/agentvfx/test/psychedelic.test.mjs +99 -0
- package/skills/agentvfx/test/render.test.mjs +73 -0
- package/skills/agentvfx/test/sacred.test.mjs +175 -0
- package/skills/agentvfx/test/schema.test.mjs +103 -0
- package/skills/agentvfx/test/scope.test.mjs +306 -0
- package/skills/agentvfx/test/spectrum.test.mjs +165 -0
- package/skills/agentvfx/test/text.test.mjs +142 -0
- package/skills/agentvfx/test/web.test.mjs +400 -0
- package/skills/agentvfx/test-media/SOURCES.md +39 -0
- package/skills/agentvfx/test-media/beat-132.mp3 +0 -0
- package/skills/agentvfx/test-media/clip-01.mp4 +0 -0
- package/skills/agentvfx/test-media/clip-02.mp4 +0 -0
|
@@ -0,0 +1,2367 @@
|
|
|
1
|
+
// collage main (generated from _src/*.glsl by _src/build.mjs; edit the parts, not this file).
|
|
2
|
+
// A collage on a 32 x 18 grid. Pass 0 decodes up to 16 cells (cell0.., style0.., src0.. inputs; or a seeded
|
|
3
|
+
// partition rebuilt on every cut in reshuffle mode) into the state texture; this pass draws them in list order.
|
|
4
|
+
// A cell is either the old boxed "tile" panel (gutter, header strip, frame) or an editorial cell with no box
|
|
5
|
+
// of its own: footage, hairline spectrum / scope / meters, live numbers, registration marks, rules and "type"
|
|
6
|
+
// cells that window the engine text sheet. Pixel units: U = pixels per design pixel at 1080p. Cells hold their
|
|
7
|
+
// place; only the instruments move, and nothing eases.
|
|
8
|
+
float U;
|
|
9
|
+
float HW;
|
|
10
|
+
const int MAXL = 16;
|
|
11
|
+
const float HEAD = 22.0;
|
|
12
|
+
|
|
13
|
+
float hlw(float d, float w) { return clamp(w * 0.5 - abs(d) + 0.5, 0.0, 1.0); }
|
|
14
|
+
float hl(float d) { return hlw(d, HW); }
|
|
15
|
+
float cov(float d) { return clamp(0.5 - d, 0.0, 1.0); }
|
|
16
|
+
float inBox(vec2 p, vec2 lo, vec2 hi) { return step(lo.x, p.x) * step(p.x, hi.x) * step(lo.y, p.y) * step(p.y, hi.y); }
|
|
17
|
+
float boxLnW(vec2 p, vec2 lo, vec2 hi, float w) {
|
|
18
|
+
vec2 q = abs(p - (lo + hi) * 0.5) - (hi - lo) * 0.5;
|
|
19
|
+
return hlw(max(q.x, q.y), w);
|
|
20
|
+
}
|
|
21
|
+
float dashed(float x, float period, float duty) { return step(fract(x / (period * U)), duty); }
|
|
22
|
+
float plusAt(vec2 p, vec2 c, float arm) {
|
|
23
|
+
vec2 d = abs(p - c);
|
|
24
|
+
return max(hl(d.y) * step(d.x, arm), hl(d.x) * step(d.y, arm));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
vec4 stClock() { return texelFetch(state, ivec2(0, 0), 0); }
|
|
28
|
+
vec4 stLevel() { return texelFetch(state, ivec2(1, 0), 0); }
|
|
29
|
+
vec4 stHit() { return texelFetch(state, ivec2(3, 0), 0); }
|
|
30
|
+
float stBand(int i) { return texelFetch(state, ivec2(i, 1), 0).r; }
|
|
31
|
+
|
|
32
|
+
// 3 x 5 pixel font, 3 bits per row, row 0 at the top. Index: 0-9, A-Z (10..35), . - + / : % (36..41).
|
|
33
|
+
const int FONT[42] = int[42](0x7B6F, 0x2C97, 0x73E7, 0x73CF, 0x5BC9, 0x79CF, 0x79EF, 0x7249, 0x7BEF, 0x7BCF, 0x2BED, 0x6BAE, 0x3923, 0x6B6E, 0x79A7, 0x79A4, 0x396B, 0x5BED, 0x7497, 0x126A, 0x5BAD, 0x4927, 0x5FED, 0x6B6D, 0x2B6A, 0x6BA4, 0x2B73, 0x6BAD, 0x388E, 0x7492, 0x5B6F, 0x5B6A, 0x5BFD, 0x5AAD, 0x5A92, 0x72A7, 0x2, 0x1C0, 0x5D0, 0x12A4, 0x410, 0x52A5);
|
|
34
|
+
int fontIndex(int ch) {
|
|
35
|
+
if (ch >= 48 && ch <= 57) { return ch - 48; }
|
|
36
|
+
if (ch >= 65 && ch <= 90) { return ch - 55; }
|
|
37
|
+
if (ch == 46) { return 36; }
|
|
38
|
+
if (ch == 45) { return 37; }
|
|
39
|
+
if (ch == 43) { return 38; }
|
|
40
|
+
if (ch == 47) { return 39; }
|
|
41
|
+
if (ch == 58) { return 40; }
|
|
42
|
+
if (ch == 37) { return 41; }
|
|
43
|
+
return -1;
|
|
44
|
+
}
|
|
45
|
+
float cellPx(float c) { return max(1.0, floor(c + 0.5)); }
|
|
46
|
+
float glyphAt(vec2 p, int ch, float cell) {
|
|
47
|
+
int gi = fontIndex(ch);
|
|
48
|
+
if (gi < 0 || p.x < 0.0 || p.y < 0.0) { return 0.0; }
|
|
49
|
+
ivec2 c = ivec2(floor(p / cell));
|
|
50
|
+
if (c.x > 2 || c.y > 4) { return 0.0; }
|
|
51
|
+
return float((FONT[gi] >> ((4 - c.y) * 3 + (2 - c.x))) & 1);
|
|
52
|
+
}
|
|
53
|
+
// up to four characters (ASCII codes, 0 = none) from the top-left o; advance is 4 cells
|
|
54
|
+
float txt4(vec2 p, vec2 o, float cell, int a, int b, int c, int d) {
|
|
55
|
+
vec2 q = p - o;
|
|
56
|
+
if (q.x < 0.0 || q.y < 0.0) { return 0.0; }
|
|
57
|
+
float adv = 4.0 * cell;
|
|
58
|
+
int i = int(floor(q.x / adv));
|
|
59
|
+
if (i > 3) { return 0.0; }
|
|
60
|
+
int ch = i == 0 ? a : (i == 1 ? b : (i == 2 ? c : d));
|
|
61
|
+
return glyphAt(vec2(q.x - float(i) * adv, q.y), ch, cell);
|
|
62
|
+
}
|
|
63
|
+
// non-negative integer with nd digits
|
|
64
|
+
float numTxt(vec2 p, vec2 o, float cell, float v, int nd) {
|
|
65
|
+
vec2 q = p - o;
|
|
66
|
+
if (q.x < 0.0 || q.y < 0.0) { return 0.0; }
|
|
67
|
+
float adv = 4.0 * cell;
|
|
68
|
+
int i = int(floor(q.x / adv));
|
|
69
|
+
if (i >= nd) { return 0.0; }
|
|
70
|
+
int dg = int(mod(floor(v / pow(10.0, float(nd - 1 - i)) + 0.001), 10.0));
|
|
71
|
+
return glyphAt(vec2(q.x - float(i) * adv, q.y), 48 + dg, cell);
|
|
72
|
+
}
|
|
73
|
+
float numW(int nd, float cell) { return float(nd) * 4.0 * cell - cell; }
|
|
74
|
+
|
|
75
|
+
// Panels return vec3(ink, accent, negative) coverage; q is in pixels from the panel's top-left, S its size.
|
|
76
|
+
|
|
77
|
+
// spectrum steps: columns of dashes that light in whole rows, accent on the top row of each column
|
|
78
|
+
vec3 pSpectrum(vec2 q, vec2 S) {
|
|
79
|
+
float pad = 10.0 * U;
|
|
80
|
+
vec2 lo = vec2(pad, HEAD * U + pad);
|
|
81
|
+
vec2 hi = vec2(S.x - pad, S.y - pad - 14.0 * U);
|
|
82
|
+
vec2 sz = hi - lo;
|
|
83
|
+
float ink = 0.0;
|
|
84
|
+
float acc = 0.0;
|
|
85
|
+
float xr = step(lo.x, q.x) * step(q.x, hi.x);
|
|
86
|
+
for (int r = 1; r < 4; r++) {
|
|
87
|
+
float yr = hi.y - sz.y * float(r) / 4.0;
|
|
88
|
+
ink = max(ink, hl(q.y - yr) * dashed(q.x, 6.0, 0.35) * xr * 0.4);
|
|
89
|
+
}
|
|
90
|
+
ink = max(ink, hl(q.y - hi.y) * xr);
|
|
91
|
+
float pitch = sz.x / float(bands);
|
|
92
|
+
float cx = q.x - lo.x;
|
|
93
|
+
int b = int(floor(cx / pitch));
|
|
94
|
+
if (cx >= 0.0 && b < bands) {
|
|
95
|
+
float rows = max(floor(sz.y / (6.0 * U)), 4.0);
|
|
96
|
+
float rowH = sz.y / rows;
|
|
97
|
+
float lit = floor(stBand(b) * rows + 0.5);
|
|
98
|
+
float y = hi.y - q.y;
|
|
99
|
+
float xin = mod(cx, pitch);
|
|
100
|
+
float on = step(0.0, y) * step(floor(y / rowH), lit - 1.0) * step(U, xin) * step(xin, pitch - U) * step(fract(y / rowH), 0.7) * step(0.5, lit);
|
|
101
|
+
ink = max(ink, on * 0.6);
|
|
102
|
+
acc = max(acc, on * step(lit - 1.5, floor(y / rowH)));
|
|
103
|
+
}
|
|
104
|
+
float span = log(endFreq / startFreq);
|
|
105
|
+
for (int k = 0; k < 3; k++) {
|
|
106
|
+
float f = k == 0 ? 100.0 : (k == 1 ? 1000.0 : 10000.0);
|
|
107
|
+
float tx = log(f / startFreq) / span;
|
|
108
|
+
if (tx <= 0.0 || tx >= 1.0) { continue; }
|
|
109
|
+
float x = lo.x + tx * sz.x;
|
|
110
|
+
ink = max(ink, hl(q.x - x) * step(hi.y, q.y) * step(q.y, hi.y + 5.0 * U));
|
|
111
|
+
float c = cellPx(2.0 * U);
|
|
112
|
+
ink = max(ink, k == 0 ? txt4(q, vec2(x + 3.0 * U, hi.y + 5.0 * U), c, 49, 48, 48, 0) : (k == 1 ? txt4(q, vec2(x + 3.0 * U, hi.y + 5.0 * U), c, 49, 75, 0, 0) : txt4(q, vec2(x + 3.0 * U, hi.y + 5.0 * U), c, 49, 48, 75, 0)));
|
|
113
|
+
}
|
|
114
|
+
return vec3(ink, acc, 0.0);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
float waveAt(float i) { return texture(audio, vec2((clamp(i, 0.0, 511.0) + 0.5) / 512.0, 0.25)).r - 0.5; }
|
|
118
|
+
float waveI(float i) {
|
|
119
|
+
float f = floor(i);
|
|
120
|
+
return mix(waveAt(f), waveAt(f + 1.0), i - f);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// scope trace: dashed graticule, centre axis with ticks, a trigger-aligned trace drawn as the vertical
|
|
124
|
+
// extent of the wave across each pixel column so steep edges stay solid
|
|
125
|
+
vec3 pScope(vec2 q, vec2 S) {
|
|
126
|
+
float pad = 10.0 * U;
|
|
127
|
+
vec2 lo = vec2(pad, HEAD * U + pad);
|
|
128
|
+
vec2 hi = S - vec2(pad);
|
|
129
|
+
vec2 sz = hi - lo;
|
|
130
|
+
float yc = (lo.y + hi.y) * 0.5;
|
|
131
|
+
float inb = inBox(q, lo, hi);
|
|
132
|
+
float ink = 0.0;
|
|
133
|
+
for (int k = 1; k < 8; k++) { ink = max(ink, hl(q.x - (lo.x + sz.x * float(k) / 8.0)) * dashed(q.y, 6.0, 0.3) * inb * 0.35); }
|
|
134
|
+
for (int k = 1; k < 4; k++) { ink = max(ink, hl(q.y - (lo.y + sz.y * float(k) / 4.0)) * dashed(q.x, 6.0, 0.3) * inb * 0.35); }
|
|
135
|
+
float tick = step(abs(q.y - yc), (fract((q.x - lo.x) / (sz.x / 40.0) + 0.5) < 0.1 ? 3.0 : 0.0) * U) * inb;
|
|
136
|
+
ink = max(ink, max(hl(q.y - yc) * inb * 0.7, tick * 0.7));
|
|
137
|
+
ink = max(ink, max(hl(q.x - lo.x + 5.0 * U), 0.0) * step(abs(q.y - yc), 4.0 * U) * step(q.x, lo.x));
|
|
138
|
+
float dx = 0.5 / sz.x * 511.0;
|
|
139
|
+
float t = (q.x - lo.x) / sz.x * 511.0;
|
|
140
|
+
float yA = yc - waveI(t - dx) * scopeGain * sz.y;
|
|
141
|
+
float yB = yc - waveI(t + dx) * scopeGain * sz.y;
|
|
142
|
+
float yMin = clamp(min(yA, yB), lo.y, hi.y);
|
|
143
|
+
float yMax = clamp(max(yA, yB), lo.y, hi.y);
|
|
144
|
+
float d = max(max(yMin - q.y, q.y - yMax), 0.0);
|
|
145
|
+
float acc = hlw(d, HW * 1.15) * step(lo.x, q.x) * step(q.x, hi.x);
|
|
146
|
+
return vec3(ink, acc, 0.0);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// level meter: four segmented channels (bass, mid, treble, rms) that fill in whole segments, accent on the
|
|
150
|
+
// top lit segment and the clip zone; the long side of the panel is the scale
|
|
151
|
+
vec3 pMeter(vec2 q, vec2 S) {
|
|
152
|
+
vec4 lv = stLevel();
|
|
153
|
+
float pad = 10.0 * U;
|
|
154
|
+
vec2 lo = vec2(pad, HEAD * U + pad);
|
|
155
|
+
vec2 hi = vec2(S.x - pad, S.y - pad - 12.0 * U);
|
|
156
|
+
vec2 a = q - lo;
|
|
157
|
+
vec2 sz = hi - lo;
|
|
158
|
+
bool vert = S.y >= S.x * 0.75;
|
|
159
|
+
float len = vert ? sz.y : sz.x;
|
|
160
|
+
float wid = vert ? sz.x : sz.y;
|
|
161
|
+
float along = vert ? sz.y - a.y : a.x;
|
|
162
|
+
float across = vert ? a.x : a.y;
|
|
163
|
+
float chW = wid / 4.0;
|
|
164
|
+
float c = cellPx(2.0 * U);
|
|
165
|
+
vec2 lp = q - vec2(lo.x, hi.y + 4.0 * U);
|
|
166
|
+
int lc = int(clamp(floor(lp.x / chW), 0.0, 3.0));
|
|
167
|
+
vec2 lo_ = vec2(lp.x - float(lc) * chW - (chW * 0.5 - 6.0 * c), lp.y);
|
|
168
|
+
float labels = !vert || lp.x < 0.0 ? 0.0 : (lc == 0 ? txt4(lo_, vec2(0.0), c, 66, 83, 83, 0) : (lc == 1 ? txt4(lo_, vec2(0.0), c, 77, 73, 68, 0) : (lc == 2 ? txt4(lo_, vec2(0.0), c, 84, 82, 66, 0) : txt4(lo_, vec2(0.0), c, 82, 77, 83, 0))));
|
|
169
|
+
if (along < 0.0 || across < 0.0 || along >= len || across >= wid) { return vec3(labels, 0.0, 0.0); }
|
|
170
|
+
int ch = int(floor(across / chW));
|
|
171
|
+
float within = fract(across / chW);
|
|
172
|
+
float nseg = max(floor(len / (6.0 * U)), 8.0);
|
|
173
|
+
float segLen = len / nseg;
|
|
174
|
+
float seg = floor(along / segLen);
|
|
175
|
+
float lit = floor(lv[ch] * nseg + 0.5);
|
|
176
|
+
float shape = step(fract(along / segLen), 0.68) * step(0.16, within) * step(within, 0.84);
|
|
177
|
+
float on = shape * step(seg, lit - 1.0) * step(0.5, lit);
|
|
178
|
+
float off = shape * (1.0 - on) * 0.16;
|
|
179
|
+
float clip = step(nseg * 0.8, seg);
|
|
180
|
+
float top = step(lit - 1.5, seg);
|
|
181
|
+
float acc = on * max(clip, top);
|
|
182
|
+
float ink = max(on * (1.0 - acc) * 0.85, off);
|
|
183
|
+
return vec3(max(ink, labels), acc, 0.0);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// readout: one large three digit number (rms x 999), then smaller rows for tempo, cut index and frame
|
|
187
|
+
vec3 pReadout(vec2 q, vec2 S, vec4 clk) {
|
|
188
|
+
vec4 lv = stLevel();
|
|
189
|
+
float pad = 10.0 * U;
|
|
190
|
+
float top = HEAD * U + pad;
|
|
191
|
+
float big = cellPx(min((S.x - 2.0 * pad) / 11.0, (S.y - top) * 0.42 / 5.0));
|
|
192
|
+
float ink = numTxt(q, vec2(pad, top), big, floor(lv.a * 999.0), 3);
|
|
193
|
+
float small = cellPx(min(4.0 * U, big * 0.5));
|
|
194
|
+
float rowStep = 5.0 * small + 8.0 * U;
|
|
195
|
+
float y0 = S.y - pad - 5.0 * small - 2.0 * rowStep;
|
|
196
|
+
ink = max(ink, hl(q.y - (y0 - 6.0 * U)) * step(pad, q.x) * step(q.x, S.x - pad) * 0.6);
|
|
197
|
+
float valX = pad + 16.0 * small;
|
|
198
|
+
ink = max(ink, txt4(q, vec2(pad, y0), small, 66, 80, 77, 0) + numTxt(q, vec2(valX, y0), small, floor(AUDIO_BPM), 3));
|
|
199
|
+
ink = max(ink, txt4(q, vec2(pad, y0 + rowStep), small, 67, 85, 84, 0) + numTxt(q, vec2(valX, y0 + rowStep), small, mod(clk.x, 1000.0), 3));
|
|
200
|
+
ink = max(ink, txt4(q, vec2(pad, y0 + 2.0 * rowStep), small, 70, 82, 77, 0) + numTxt(q, vec2(valX, y0 + 2.0 * rowStep), small, mod(float(FRAMEINDEX), 1000.0), 3));
|
|
201
|
+
float pulse = step(float(FRAMEINDEX) - clk.w, 1.5) * step(0.5, clk.z);
|
|
202
|
+
float lamp = inBox(q, vec2(S.x - pad - 10.0 * U, top), vec2(S.x - pad, top + 10.0 * U));
|
|
203
|
+
return vec3(min(ink, 1.0), lamp * pulse, 0.0);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// crosshair: hairlines through a target that follows the spectral balance (x) and loudness (y), tick
|
|
207
|
+
// scales, a ring that tracks rms and a second ring that steps outward for three frames after each onset
|
|
208
|
+
vec3 pCross(vec2 q, vec2 S, vec4 clk) {
|
|
209
|
+
vec4 lv = stLevel();
|
|
210
|
+
float pad = 10.0 * U;
|
|
211
|
+
vec2 lo = vec2(pad, HEAD * U + pad);
|
|
212
|
+
vec2 hi = S - vec2(pad);
|
|
213
|
+
vec2 ctr = (lo + hi) * 0.5;
|
|
214
|
+
vec2 half_ = (hi - lo) * 0.5;
|
|
215
|
+
vec2 tp = ctr + half_ * vec2(0.6 * (lv.b - lv.r), -0.7 * (lv.a * 1.8 - 0.7));
|
|
216
|
+
tp = clamp(tp, lo + 8.0 * U, hi - 8.0 * U);
|
|
217
|
+
float inb = inBox(q, lo, hi);
|
|
218
|
+
vec2 d = q - tp;
|
|
219
|
+
float ink = max(hl(d.y) * inb, hl(d.x) * inb) * 0.8;
|
|
220
|
+
float tickX = step(abs(d.y), (fract(d.x / (8.0 * U) + 0.5) < 0.12 ? (fract(d.x / (40.0 * U) + 0.5) < 0.12 ? 7.0 : 3.5) : 0.0) * U);
|
|
221
|
+
float tickY = step(abs(d.x), (fract(d.y / (8.0 * U) + 0.5) < 0.12 ? (fract(d.y / (40.0 * U) + 0.5) < 0.12 ? 7.0 : 3.5) : 0.0) * U);
|
|
222
|
+
ink = max(ink, max(tickX, tickY) * inb);
|
|
223
|
+
float r = length(d);
|
|
224
|
+
float base = min(half_.x, half_.y);
|
|
225
|
+
float ringA = hl(r - base * (0.2 + 0.45 * lv.a));
|
|
226
|
+
float hitF = float(FRAMEINDEX) - clk.w;
|
|
227
|
+
float ringB = hitF < 3.0 && clk.z > 0.5 ? hl(r - base * (0.8 + 0.3 * hitF)) : 0.0;
|
|
228
|
+
float dot_ = inBox(d, vec2(-3.0 * U), vec2(3.0 * U));
|
|
229
|
+
float mid = hl(length(q - ctr) - base * 0.75) * dashed(atan(q.y - ctr.y, q.x - ctr.x) * base * 0.75, 7.0, 0.35) * 0.4;
|
|
230
|
+
float acc = max(max(ringA, ringB), dot_) * inb;
|
|
231
|
+
float c = cellPx(2.0 * U);
|
|
232
|
+
float xy = numTxt(q, vec2(lo.x + 4.0 * U, hi.y - 12.0 * U), c, floor(clamp((tp.x - lo.x) / (hi.x - lo.x), 0.0, 1.0) * 999.0), 3)
|
|
233
|
+
+ numTxt(q, vec2(hi.x - numW(3, c) - 4.0 * U, hi.y - 12.0 * U), c, floor(clamp(1.0 - (tp.y - lo.y) / (hi.y - lo.y), 0.0, 1.0) * 999.0), 3);
|
|
234
|
+
return vec3(min(max(ink, max(mid, xy)), 1.0), acc, 0.0);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// footage: cover-fit into the cell below `top` (the tile header height, 0 for editorial cells), contrast curve,
|
|
238
|
+
// optional single-tone mix, saturation and dim, scanlines. Variants 1..4 lay a dark scrim over it (bottom, top,
|
|
239
|
+
// left, vignette, bottom plus vignette) so type reads on top. Without an input the cell shows a crossed empty-media mark.
|
|
240
|
+
vec3 footageBody(vec2 q, vec2 S, float top, int variant) {
|
|
241
|
+
vec2 lo = vec2(0.0, top);
|
|
242
|
+
vec2 sz = S - lo;
|
|
243
|
+
vec2 d = (q - (lo + S) * 0.5) / sz;
|
|
244
|
+
vec2 tex = IMG_SIZE(inputImage);
|
|
245
|
+
float ta = tex.x / tex.y;
|
|
246
|
+
float wa = sz.x / sz.y;
|
|
247
|
+
vec2 vis = wa > ta ? vec2(1.0, ta / wa) : vec2(wa / ta, 1.0);
|
|
248
|
+
vec3 c = texture(inputImage, vec2(0.5 + d.x * vis.x, 0.5 - d.y * vis.y)).rgb;
|
|
249
|
+
c = max((c - 0.18) * footageContrast + 0.18, 0.0);
|
|
250
|
+
vec3 duo = mix(groundColor.rgb, inkColor.rgb, smoothstep(0.02, 0.6, luma(c)));
|
|
251
|
+
c = mix(c, duo, footageTone);
|
|
252
|
+
c = mix(vec3(luma(c)), c, footageSat) * (1.0 - footageDim);
|
|
253
|
+
vec2 u = (q - lo) / sz;
|
|
254
|
+
float scrim = 1.0;
|
|
255
|
+
if (variant == 1) { scrim = smoothstep(0.32, 1.0, u.y); }
|
|
256
|
+
if (variant == 2) { scrim = smoothstep(0.68, 0.0, u.y); }
|
|
257
|
+
if (variant == 3) { scrim = smoothstep(0.7, 0.0, u.x); }
|
|
258
|
+
if (variant == 4) { scrim = smoothstep(0.35, 1.0, length((u - 0.5) * vec2(1.0, 1.15)) * 1.6); }
|
|
259
|
+
if (variant == 5) { scrim = max(smoothstep(0.3, 0.95, u.y), smoothstep(0.3, 1.0, length((u - 0.5) * vec2(1.0, 1.25)) * 1.5) * 0.85); }
|
|
260
|
+
if (variant == 6) { scrim = 0.93; }
|
|
261
|
+
if (variant == 7) { scrim = 0.55; }
|
|
262
|
+
c *= mix(1.0, 0.1, scrim * step(0.5, float(variant)));
|
|
263
|
+
return c * (1.0 - footageScan * step(0.5, fract(q.y / (3.0 * U))));
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
float hatch(vec2 q, float pitch) { return hl(mod(q.x + q.y, pitch * U) - pitch * 0.5 * U); }
|
|
267
|
+
|
|
268
|
+
// fillers: 7 = ruler or pixel cluster, 8 = accent plate with the cut number or hatching, 9 = sparse hatch
|
|
269
|
+
vec3 pFiller(int role, vec2 q, vec2 S, float hs, vec4 clk) {
|
|
270
|
+
float pad = 10.0 * U;
|
|
271
|
+
float top = HEAD * U;
|
|
272
|
+
bool wide = S.x >= S.y;
|
|
273
|
+
if (role == 7 && hs < 0.5) {
|
|
274
|
+
float along = wide ? q.x : S.y - q.y;
|
|
275
|
+
float across = wide ? S.y - q.y : q.x;
|
|
276
|
+
float k = floor(along / (8.0 * U) + 0.5);
|
|
277
|
+
float len = (mod(k, 5.0) < 0.5 ? 14.0 : 6.0) * U;
|
|
278
|
+
float tk = step(abs(along - k * 8.0 * U), HW * 0.5 + 0.5) * step(across, len) * step(top, q.y) * step(pad * 0.5, along);
|
|
279
|
+
float base = hl(across) * step(top, q.y);
|
|
280
|
+
float c = cellPx(2.0 * U);
|
|
281
|
+
float mj = floor((along - 3.0 * U) / (40.0 * U));
|
|
282
|
+
vec2 o = wide ? vec2(mj * 40.0 * U + 3.0 * U, S.y - 18.0 * U - 5.0 * c) : vec2(18.0 * U, S.y - (mj * 40.0 * U + 3.0 * U) - 5.0 * c);
|
|
283
|
+
float nTxt = mj >= 0.0 ? numTxt(q, o, c, mod(mj, 100.0), 2) * step(top + 3.0 * U, q.y) : 0.0;
|
|
284
|
+
return vec3(max(max(tk, base) * 0.8, nTxt), 0.0, 0.0);
|
|
285
|
+
}
|
|
286
|
+
if (role == 7) {
|
|
287
|
+
vec2 g = (q - vec2(pad, top + pad)) / (11.0 * U);
|
|
288
|
+
vec2 id = floor(g + 0.5);
|
|
289
|
+
float lit = step(0.72, fract(sin(dot(id + clk.x * 1.7, vec2(12.9898, 78.233))) * 43758.5453));
|
|
290
|
+
float dotc = cov(length((g - id) * 11.0 * U) - (1.2 + 1.3 * lit) * U) * inBox(q, vec2(pad, top + pad), S - vec2(pad));
|
|
291
|
+
return vec3(dotc * (1.0 - lit) * 0.7, dotc * lit, 0.0);
|
|
292
|
+
}
|
|
293
|
+
if (role == 8 && hs < 0.6 && plateAmount > 0.5) {
|
|
294
|
+
float cn = cellPx(min(S.x * 0.78 / 11.0, S.y * 0.5 / 5.0));
|
|
295
|
+
vec2 o = vec2(pad, S.y - pad - 5.0 * cn);
|
|
296
|
+
return vec3(0.0, 1.0, numTxt(q, o, cn, mod(clk.x, 1000.0), 3));
|
|
297
|
+
}
|
|
298
|
+
float hp = role == 8 ? 9.0 : 16.0;
|
|
299
|
+
float amt = role == 8 ? 0.5 : 0.28;
|
|
300
|
+
float h = hatch(q, hp) * step(top, q.y) * amt;
|
|
301
|
+
float cr = role == 9 ? plusAt(q, (vec2(0.0, top) + S) * 0.5, min(S.x, S.y) * 0.12) : 0.0;
|
|
302
|
+
return vec3(max(h, cr), 0.0, 0.0);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// header strip: frame, rule under the label, role tag, and the cut number (or timecode for the footage panel)
|
|
306
|
+
vec3 panelHead(int role, float hs, vec2 q, vec2 S, vec4 clk, float snap) {
|
|
307
|
+
float w = snap > 0.5 ? HW * 3.0 : HW;
|
|
308
|
+
float frame = boxLnW(q, vec2(0.0), S, w);
|
|
309
|
+
float rule = hl(q.y - HEAD * U) * step(0.0, q.x) * step(q.x, S.x);
|
|
310
|
+
float c = cellPx(2.5 * U);
|
|
311
|
+
vec2 o = vec2(8.0 * U, (HEAD * U - 5.0 * c) * 0.5);
|
|
312
|
+
float tag = role == 1 ? txt4(q, o, c, 83, 82, 67, 0) : (role == 2 ? txt4(q, o, c, 70, 70, 84, 0) : (role == 3 ? txt4(q, o, c, 79, 83, 67, 0)
|
|
313
|
+
: (role == 4 ? txt4(q, o, c, 76, 86, 76, 0) : (role == 5 ? txt4(q, o, c, 78, 85, 77, 0) : (role == 6 ? txt4(q, o, c, 88, 72, 82, 0)
|
|
314
|
+
: (role == 7 ? (hs < 0.5 ? txt4(q, o, c, 82, 85, 76, 0) : txt4(q, o, c, 80, 73, 88, 0)) : txt4(q, o, c, 72, 67, 72, 0)))))));
|
|
315
|
+
float right = 0.0;
|
|
316
|
+
if (role == 1) {
|
|
317
|
+
float tc = TIME;
|
|
318
|
+
float x0 = S.x - 8.0 * U - 31.0 * c;
|
|
319
|
+
vec2 p = vec2(x0, o.y);
|
|
320
|
+
right = numTxt(q, p, c, floor(tc / 60.0), 2) + glyphAt(q - p - vec2(8.0 * c, 0.0), 58, c)
|
|
321
|
+
+ numTxt(q, p + vec2(12.0 * c, 0.0), c, mod(floor(tc), 60.0), 2) + glyphAt(q - p - vec2(20.0 * c, 0.0), 58, c)
|
|
322
|
+
+ numTxt(q, p + vec2(24.0 * c, 0.0), c, mod(float(FRAMEINDEX), 30.0), 2);
|
|
323
|
+
} else {
|
|
324
|
+
right = numTxt(q, vec2(S.x - 8.0 * U - numW(3, c), o.y), c, mod(clk.x, 1000.0), 3);
|
|
325
|
+
}
|
|
326
|
+
float ink = max(max(frame, rule * (role == 8 ? 0.0 : 1.0)), max(tag, min(right, 1.0)));
|
|
327
|
+
return vec3(ink, snap > 0.5 ? frame : 0.0, 0.0);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// Editorial roles. The engine text layer (TEXTMASK) is a "sheet" of type slots (see fx.json X_AGENTVFX.text);
|
|
331
|
+
// a type cell shows a window of that sheet, scaled and optionally turned 90 degrees, and the shader only
|
|
332
|
+
// colours it. Live numbers and labels come from the mono "atlas" row of the sheet (digits, colon, A..Z).
|
|
333
|
+
// Every role below returns vec3(ink, hot, 0) coverage in the cell's own pixel space (q from its top-left).
|
|
334
|
+
const float ATLAS_X = 0.35938;
|
|
335
|
+
const float ATLAS_Y = 0.93333;
|
|
336
|
+
const float ATLAS_PX = 0.05;
|
|
337
|
+
const float MONO_ADV = 0.602;
|
|
338
|
+
vec2 UN;
|
|
339
|
+
|
|
340
|
+
// one text-sheet channel (0 R the editorial sheet, 1 G, 2 B) at sheet pixel sp (origin top left)
|
|
341
|
+
float sheetC(vec2 sp, int ch) {
|
|
342
|
+
vec2 res = RENDERSIZE;
|
|
343
|
+
if (!HAS_TEXT || sp.x < 0.0 || sp.y < 0.0 || sp.x >= res.x || sp.y >= res.y) { return 0.0; }
|
|
344
|
+
vec3 t = texture(TEXTMASK, vec2(sp.x, res.y - sp.y) / res).rgb;
|
|
345
|
+
return ch == 1 ? t.g : (ch == 2 ? t.b : t.r);
|
|
346
|
+
}
|
|
347
|
+
float sheetAt(vec2 sp) { return sheetC(sp, 0); }
|
|
348
|
+
|
|
349
|
+
int aIdx(int ch) {
|
|
350
|
+
if (ch >= 48 && ch <= 57) { return ch - 48; }
|
|
351
|
+
if (ch == 58) { return 10; }
|
|
352
|
+
if (ch >= 65 && ch <= 90) { return ch - 54; }
|
|
353
|
+
return -1;
|
|
354
|
+
}
|
|
355
|
+
// one atlas glyph; p is in pixels from the top-left of its character box (MONO_ADV * fs wide, fs high)
|
|
356
|
+
float aGlyph(vec2 p, int ch, float fs) {
|
|
357
|
+
int idx = aIdx(ch);
|
|
358
|
+
if (idx < 0 || p.x < 0.0 || p.y < 0.0 || p.x >= MONO_ADV * fs || p.y >= fs) { return 0.0; }
|
|
359
|
+
float apx = ATLAS_PX * RENDERSIZE.y;
|
|
360
|
+
vec2 o = vec2(ATLAS_X * RENDERSIZE.x + float(idx) * MONO_ADV * apx, ATLAS_Y * RENDERSIZE.y);
|
|
361
|
+
return sheetAt(o + p * (apx / fs));
|
|
362
|
+
}
|
|
363
|
+
float aTxt(vec2 p, float fs, int a, int b, int c, int d) {
|
|
364
|
+
if (p.x < 0.0) { return 0.0; }
|
|
365
|
+
float adv = MONO_ADV * fs;
|
|
366
|
+
int i = int(floor(p.x / adv));
|
|
367
|
+
if (i > 3) { return 0.0; }
|
|
368
|
+
int ch = i == 0 ? a : (i == 1 ? b : (i == 2 ? c : d));
|
|
369
|
+
return aGlyph(vec2(p.x - float(i) * adv, p.y), ch, fs);
|
|
370
|
+
}
|
|
371
|
+
float aNum(vec2 p, float fs, float v, int nd) {
|
|
372
|
+
if (p.x < 0.0) { return 0.0; }
|
|
373
|
+
float adv = MONO_ADV * fs;
|
|
374
|
+
int i = int(floor(p.x / adv));
|
|
375
|
+
if (i >= nd) { return 0.0; }
|
|
376
|
+
int dg = int(mod(floor(v / pow(10.0, float(nd - 1 - i)) + 0.001), 10.0));
|
|
377
|
+
return aGlyph(vec2(p.x - float(i) * adv, p.y), 48 + dg, fs);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
float bandAt(float x) {
|
|
381
|
+
float f = x * float(bands) - 0.5;
|
|
382
|
+
float i0 = floor(f);
|
|
383
|
+
return mix(stBand(clamp(int(i0), 0, bands - 1)), stBand(clamp(int(i0) + 1, 0, bands - 1)), f - i0);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// spectrum, hairline family. 1: one line over the bands; 2: comb of single-pixel bars. Both stand on a
|
|
387
|
+
// baseline with a tick scale under it and an accent dot on the loudest band.
|
|
388
|
+
vec3 pSpecHair(vec2 q, vec2 S, int v) {
|
|
389
|
+
float y0 = S.y - 14.0 * U;
|
|
390
|
+
float amp = y0 - 2.0 * U;
|
|
391
|
+
float inx = step(0.0, q.x) * step(q.x, S.x);
|
|
392
|
+
float pitch = S.x / float(bands);
|
|
393
|
+
float ink = hl(q.y - y0) * inx * 0.85;
|
|
394
|
+
float tk = floor(q.x / pitch + 0.5);
|
|
395
|
+
float isMaj = mod(tk, 5.0) < 0.5 ? 1.0 : 0.0;
|
|
396
|
+
ink = max(ink, step(abs(q.x - tk * pitch), HW * 0.5 + 0.25) * step(y0, q.y) * step(q.y, y0 + (3.0 + 3.5 * isMaj) * U) * 0.8);
|
|
397
|
+
float hot = 0.0;
|
|
398
|
+
if (v == 2) {
|
|
399
|
+
int b = int(clamp(floor(q.x / pitch), 0.0, float(bands - 1)));
|
|
400
|
+
float top = y0 - stBand(b) * amp;
|
|
401
|
+
float bar = hl(q.x - (float(b) + 0.5) * pitch) * step(top, q.y) * step(q.y, y0) * inx;
|
|
402
|
+
ink = max(ink, bar * 0.8);
|
|
403
|
+
hot = max(hot, bar * step(q.y, top + 3.0 * U));
|
|
404
|
+
} else {
|
|
405
|
+
float yA = y0 - bandAt((q.x - 0.5) / S.x) * amp;
|
|
406
|
+
float yB = y0 - bandAt((q.x + 0.5) / S.x) * amp;
|
|
407
|
+
float d = max(max(min(yA, yB) - q.y, q.y - max(yA, yB)), 0.0);
|
|
408
|
+
ink = max(ink, hlw(d, HW * 1.15) * inx);
|
|
409
|
+
}
|
|
410
|
+
vec4 pk = texelFetch(state, ivec2(2, 0), 0);
|
|
411
|
+
vec2 pp = vec2((pk.x + 0.5) * pitch, y0 - pk.y * amp);
|
|
412
|
+
float lit = step(0.06, pk.y);
|
|
413
|
+
hot = max(hot, lit * max(inBox(q - pp, vec2(-3.0 * U), vec2(3.0 * U)), hl(q.x - pp.x) * step(q.y, pp.y - 3.0 * U) * step(pp.y - 12.0 * U, q.y)));
|
|
414
|
+
return vec3(ink, hot, 0.0);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// scope as one line crossing the cell: faint axis, trigger-free wave trace. 1: trace hot; 2: trace ink
|
|
418
|
+
vec3 pScopeLine(vec2 q, vec2 S, int v) {
|
|
419
|
+
float yc = S.y * 0.5;
|
|
420
|
+
float inx = step(0.0, q.x) * step(q.x, S.x);
|
|
421
|
+
float dx = 0.5 / S.x * 511.0;
|
|
422
|
+
float t = q.x / S.x * 511.0;
|
|
423
|
+
float yA = yc - waveI(t - dx) * scopeGain * S.y;
|
|
424
|
+
float yB = yc - waveI(t + dx) * scopeGain * S.y;
|
|
425
|
+
float d = max(max(clamp(min(yA, yB), 0.0, S.y) - q.y, q.y - clamp(max(yA, yB), 0.0, S.y)), 0.0);
|
|
426
|
+
float tr = hlw(d, HW * 1.15) * inx;
|
|
427
|
+
float axis = hl(q.y - yc) * inx * 0.22;
|
|
428
|
+
return vec3(max(axis, v == 2 ? tr : 0.0), v == 2 ? 0.0 : tr, 0.0);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// hairline track with a heavier fill up to the level and a cap tick, along the long side of the cell
|
|
432
|
+
vec3 levelBar(vec2 q, vec2 S, int ch) {
|
|
433
|
+
float lv = stLevel()[ch];
|
|
434
|
+
bool wide = S.x >= S.y;
|
|
435
|
+
float len = wide ? S.x : S.y;
|
|
436
|
+
float along = wide ? q.x : S.y - q.y;
|
|
437
|
+
float across = wide ? q.y - S.y * 0.5 : q.x - S.x * 0.5;
|
|
438
|
+
if (along < -1.0 || along > len + 1.0) { return vec3(0.0); }
|
|
439
|
+
float track = hl(across) * 0.3;
|
|
440
|
+
float fillv = hlw(across, HW * 2.4) * step(0.0, along) * step(along, lv * len);
|
|
441
|
+
float cap = step(abs(along - lv * len), HW * 0.75 + 0.5) * step(abs(across), 5.0 * U) * step(0.04, lv);
|
|
442
|
+
float ends = step(abs(along), HW * 0.5 + 0.25) * step(abs(across), 3.0 * U);
|
|
443
|
+
return vec3(max(max(track, fillv), ends * 0.6), cap, 0.0);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// four thin level bars (bass, mid, treble, rms) with mono labels: rows in a wide cell, columns in a tall one
|
|
447
|
+
vec3 pMeterEd(vec2 q, vec2 S) {
|
|
448
|
+
bool wide = S.x >= S.y * 1.2;
|
|
449
|
+
if (wide) {
|
|
450
|
+
float rh = S.y / 4.0;
|
|
451
|
+
int ch = int(clamp(floor(q.y / rh), 0.0, 3.0));
|
|
452
|
+
vec2 lq = vec2(q.x, q.y - float(ch) * rh);
|
|
453
|
+
float fs = min(rh * 0.8, 15.0 * U);
|
|
454
|
+
float lw = 4.2 * MONO_ADV * fs;
|
|
455
|
+
vec2 gp = lq - vec2(0.0, (rh - fs) * 0.5);
|
|
456
|
+
float lab = ch == 0 ? aTxt(gp, fs, 66, 83, 83, 0) : (ch == 1 ? aTxt(gp, fs, 77, 73, 68, 0) : (ch == 2 ? aTxt(gp, fs, 84, 82, 66, 0) : aTxt(gp, fs, 82, 77, 83, 0)));
|
|
457
|
+
vec3 b = levelBar(lq - vec2(lw, 0.0), vec2(S.x - lw, rh), ch);
|
|
458
|
+
return vec3(max(lab * 0.9, b.x), b.y, 0.0);
|
|
459
|
+
}
|
|
460
|
+
float cw = S.x / 4.0;
|
|
461
|
+
int ch = int(clamp(floor(q.x / cw), 0.0, 3.0));
|
|
462
|
+
float fs = min(cw * 0.7, 15.0 * U);
|
|
463
|
+
float lh = fs * 1.5;
|
|
464
|
+
vec2 lq = vec2(q.x - float(ch) * cw, q.y);
|
|
465
|
+
vec2 gp = lq - vec2((cw - 3.0 * MONO_ADV * fs) * 0.5, S.y - lh);
|
|
466
|
+
float lab = ch == 0 ? aTxt(gp, fs, 66, 83, 83, 0) : (ch == 1 ? aTxt(gp, fs, 77, 73, 68, 0) : (ch == 2 ? aTxt(gp, fs, 84, 82, 66, 0) : aTxt(gp, fs, 82, 77, 83, 0)));
|
|
467
|
+
vec3 b = levelBar(lq, vec2(cw, S.y - lh), ch);
|
|
468
|
+
return vec3(max(lab * 0.9, b.x), b.y, 0.0);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
// live number, left aligned and sized to the cell width: 1 rms, 2 cut count (flashes hot for 4 frames), 3 frame, 4 timecode, 5 bpm
|
|
472
|
+
vec3 pReadEd(vec2 q, vec2 S, int v, vec4 clk) {
|
|
473
|
+
int nch = v == 4 ? 8 : (v == 3 ? 4 : 3);
|
|
474
|
+
float fs = min(S.x / (float(nch) * MONO_ADV), S.y / 0.86);
|
|
475
|
+
vec2 p = q - vec2(0.0, S.y * 0.5 - fs * 0.455);
|
|
476
|
+
float ink = 0.0;
|
|
477
|
+
if (v == 1) { ink = aNum(p, fs, floor(stLevel().a * 999.0), 3); }
|
|
478
|
+
if (v == 2) { ink = aNum(p, fs, mod(clk.x, 1000.0), 3); }
|
|
479
|
+
if (v == 3) { ink = aNum(p, fs, mod(float(FRAMEINDEX), 10000.0), 4); }
|
|
480
|
+
if (v == 5) { ink = aNum(p, fs, floor(AUDIO_BPM), 3); }
|
|
481
|
+
if (v == 4) {
|
|
482
|
+
float adv = MONO_ADV * fs;
|
|
483
|
+
ink = aNum(p, fs, mod(floor(TIME / 60.0), 100.0), 2) + aGlyph(p - vec2(2.0 * adv, 0.0), 58, fs)
|
|
484
|
+
+ aNum(p - vec2(3.0 * adv, 0.0), fs, mod(floor(TIME), 60.0), 2) + aGlyph(p - vec2(5.0 * adv, 0.0), 58, fs)
|
|
485
|
+
+ aNum(p - vec2(6.0 * adv, 0.0), fs, mod(float(FRAMEINDEX), 30.0), 2);
|
|
486
|
+
}
|
|
487
|
+
ink = min(ink, 1.0);
|
|
488
|
+
float pulse = v == 2 && clk.x > 0.5 && float(FRAMEINDEX) - clk.y < 3.5 ? 1.0 : 0.0;
|
|
489
|
+
return vec3(ink, ink * pulse, 0.0);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
// registration mark: ring, inner ring and a cross reaching past the ring; an accent dot follows the spectral
|
|
493
|
+
// balance (x) and loudness (y) and an onset throws a second ring for three frames
|
|
494
|
+
vec3 pRegMark(vec2 q, vec2 S, vec4 clk) {
|
|
495
|
+
vec4 lv = stLevel();
|
|
496
|
+
vec2 c = S * 0.5;
|
|
497
|
+
float R = min(S.x, S.y) * 0.5;
|
|
498
|
+
vec2 d = q - c;
|
|
499
|
+
float r = length(d);
|
|
500
|
+
float r0 = R * 0.6;
|
|
501
|
+
float ink = max(hl(r - r0), hl(r - r0 * 0.28)) * 0.9;
|
|
502
|
+
ink = max(ink, max(hl(d.y) * step(abs(d.x), R * 0.96), hl(d.x) * step(abs(d.y), R * 0.96)) * 0.9);
|
|
503
|
+
vec2 tp = c + vec2(0.5 * r0 * (lv.b - lv.r), -0.6 * r0 * (lv.a * 1.8 - 0.7));
|
|
504
|
+
float hitF = float(FRAMEINDEX) - clk.w;
|
|
505
|
+
float ringB = hitF < 3.0 && clk.z > 0.5 ? hl(r - r0 * (1.0 + 0.22 * (hitF + 1.0))) : 0.0;
|
|
506
|
+
float hot = max(inBox(q - tp, vec2(-3.5 * U), vec2(3.5 * U)), ringB);
|
|
507
|
+
return vec3(ink, hot, 0.0);
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
// a type cell: window of the text sheet; 1..4 level fill (bass, mid, treble, rms) with a level hairline; 5 hot sweep per onset
|
|
511
|
+
vec3 pType(vec2 q, vec2 S, int v, int rot, vec3 src, int ch, vec4 clk) {
|
|
512
|
+
vec2 tq = rot == 1 ? vec2(S.y - q.y, q.x) : (rot == 2 ? vec2(q.y, S.x - q.x) : q);
|
|
513
|
+
float m = sheetC(src.xy * (RENDERSIZE / vec2(32.0, 18.0)) + tq / src.z, ch);
|
|
514
|
+
float hot = 0.0;
|
|
515
|
+
float line = 0.0;
|
|
516
|
+
if (v >= 1 && v <= 4) {
|
|
517
|
+
float lv = stLevel()[v - 1];
|
|
518
|
+
float yl = S.y * (1.0 - lv);
|
|
519
|
+
hot = m * step(yl, q.y);
|
|
520
|
+
line = hl(q.y - yl) * 0.55 * step(0.03, lv);
|
|
521
|
+
}
|
|
522
|
+
if (v == 5) {
|
|
523
|
+
float age = float(FRAMEINDEX) - clk.w;
|
|
524
|
+
float x0 = S.x * (age / 7.0 - 0.18);
|
|
525
|
+
hot = m * step(0.0, age) * step(age, 7.5) * step(x0, q.x) * step(q.x, x0 + S.x * 0.18) * step(0.5, clk.z);
|
|
526
|
+
}
|
|
527
|
+
return vec3(m, max(hot, line), 0.0);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
// rules. 1: horizontal hairline; 2: vertical hairline; 3: baseline with a tick scale; 4..7: level bar (bass, mid, treble, rms);
|
|
531
|
+
// 8: ruled rows, one hairline per grid unit
|
|
532
|
+
vec3 pRule(vec2 q, vec2 S, int v) {
|
|
533
|
+
float inx = step(-0.5, q.x) * step(q.x, S.x + 0.5);
|
|
534
|
+
float iny = step(-0.5, q.y) * step(q.y, S.y + 0.5);
|
|
535
|
+
if (v == 1) { return vec3(hl(q.y - S.y * 0.5) * inx, 0.0, 0.0); }
|
|
536
|
+
if (v == 2) { return vec3(hl(q.x - S.x * 0.5) * iny, 0.0, 0.0); }
|
|
537
|
+
if (v == 3) {
|
|
538
|
+
float k = floor(q.x / (8.0 * U) + 0.5);
|
|
539
|
+
float len = (mod(k, 5.0) < 0.5 ? 12.0 : 5.0) * U;
|
|
540
|
+
float tk = step(abs(q.x - k * 8.0 * U), HW * 0.5 + 0.25) * step(S.y - len, q.y) * step(q.y, S.y);
|
|
541
|
+
return vec3(max(hl(q.y - (S.y - HW * 0.5)) * inx, tk) * 0.85, 0.0, 0.0);
|
|
542
|
+
}
|
|
543
|
+
if (v >= 4 && v <= 7) { return levelBar(q, S, v - 4); }
|
|
544
|
+
if (v == 8) {
|
|
545
|
+
float rows = max(floor(S.y / UN.y + 0.5), 1.0);
|
|
546
|
+
float k = floor(q.y / (S.y / rows) + 0.5);
|
|
547
|
+
return vec3(hl(q.y - k * S.y / rows) * inx * 0.7, 0.0, 0.0);
|
|
548
|
+
}
|
|
549
|
+
return vec3(0.0);
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
float frameCov(int frame, vec2 q, vec2 S) {
|
|
553
|
+
if (frame == 2) { return boxLnW(q, vec2(0.5 * HW), S - vec2(0.5 * HW), HW); }
|
|
554
|
+
if (frame == 3) {
|
|
555
|
+
vec2 a = min(q, S - q);
|
|
556
|
+
float arm = 16.0 * U;
|
|
557
|
+
float inb = step(-0.5, q.x) * step(q.x, S.x + 0.5) * step(-0.5, q.y) * step(q.y, S.y + 0.5);
|
|
558
|
+
return max(hl(a.y - 0.5 * HW) * step(a.x, arm), hl(a.x - 0.5 * HW) * step(a.y, arm)) * inb;
|
|
559
|
+
}
|
|
560
|
+
return 0.0;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
// Role 13, typefx: type that the shader warps every frame. The text sheet is a static mask, so every effect below samples
|
|
564
|
+
// it through a changed coordinate (slices, stretch, history shear, smear taps, echo copies, band-cut fills). The cell holds
|
|
565
|
+
// its place; the letters inside it move on the music. Variants: 1 micro-type field, 2 glyph window, 3 slit-scan word,
|
|
566
|
+
// 4 echo stack, 5 echo ripple, 6 type equalizer. A cell reads one text-sheet channel (0 R, 1 G, 2 B) through its src window.
|
|
567
|
+
// Hits (stHit): x is an onset pulse, y a beat pulse; both jump on the event frame and fall in `release` seconds.
|
|
568
|
+
// The input typeWarp scales every audio-driven warp below (0 holds the type still, 1 default, 1.5 harder).
|
|
569
|
+
vec2 gP;
|
|
570
|
+
|
|
571
|
+
float winM(vec2 tq, vec3 src, int ch) { return sheetC(src.xy * (RENDERSIZE / vec2(32.0, 18.0)) + tq / src.z, ch); }
|
|
572
|
+
// re-sharpen a magnified glyph edge back to about one pixel
|
|
573
|
+
float crisp(float m, float s) {
|
|
574
|
+
float k = 0.5 / max(s, 1.0);
|
|
575
|
+
return smoothstep(0.5 - k, 0.5 + k, m);
|
|
576
|
+
}
|
|
577
|
+
float edgeOf(float raw) { return clamp(4.0 * raw * (1.0 - raw), 0.0, 1.0); }
|
|
578
|
+
// history (x beat pulse signed per hit, y mid, z treble, w rms), delay in frames, linear between frames
|
|
579
|
+
vec4 stHist(float delay) {
|
|
580
|
+
float d = clamp(delay, 0.0, 62.0);
|
|
581
|
+
float i0 = floor(d);
|
|
582
|
+
return mix(texelFetch(state, ivec2(63 - int(i0), 7), 0), texelFetch(state, ivec2(62 - int(i0), 7), 0), d - i0);
|
|
583
|
+
}
|
|
584
|
+
vec3 fxFootage(vec2 p) {
|
|
585
|
+
if (!HAS_INPUT) { return inkColor.rgb * 0.4; }
|
|
586
|
+
return footageBody(p, RENDERSIZE, 0.0, 0);
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
// micro-type lines live in the bottom band of the G sheet (5 lines from 84 percent of the height) and the B sheet (8 lines
|
|
590
|
+
// from 78 percent), one line per 2.5 percent of the height, as the text items microK and microM
|
|
591
|
+
vec3 microBand(int ch) { return ch == 1 ? vec3(0.84, 5.0, 0.025) : vec3(0.78, 8.0, 0.025); }
|
|
592
|
+
|
|
593
|
+
// rows of real text (system fonts through the sheet); each row is one spectrum band (bass at the bottom), lit up to its level,
|
|
594
|
+
// the front glyphs hot. Active rows pick another line and start on every onset. Returns (ink coverage, hot coverage).
|
|
595
|
+
vec2 microCov(vec2 q, vec2 S, vec4 clk, vec3 src, int ch) {
|
|
596
|
+
if (ch == 0) { return vec2(0.0); }
|
|
597
|
+
vec3 band = microBand(ch);
|
|
598
|
+
float rowH = band.z * RENDERSIZE.y * src.z;
|
|
599
|
+
float row = floor(q.y / rowH);
|
|
600
|
+
float lvl = bandAt(clamp(1.0 - (row + 0.5) * rowH / S.y, 0.0, 1.0));
|
|
601
|
+
float seed = row * 1.7 + step(0.3, lvl) * clk.z * 3.1;
|
|
602
|
+
float line = floor(hash12(vec2(seed, 2.0)) * band.y);
|
|
603
|
+
float xo = hash12(vec2(seed, 5.0)) * RENDERSIZE.x;
|
|
604
|
+
vec2 sp = vec2(mod(q.x / src.z + xo, RENDERSIZE.x), band.x * RENDERSIZE.y + line * band.z * RENDERSIZE.y + (q.y - row * rowH) / src.z);
|
|
605
|
+
float g = crisp(sheetC(sp, ch), src.z);
|
|
606
|
+
float lit = step(q.x, lvl * S.x);
|
|
607
|
+
float front = lit * step(lvl * S.x - q.x, 28.0 * U + 12.0) * step(0.25, lvl);
|
|
608
|
+
return vec2(g * mix(0.2, 0.85, lit), g * front);
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
// 2: giant glyph window. Footage (or, with tone accent, a solid fill) shows through the letter with the micro-type running on
|
|
612
|
+
// over it; a hard extrusion (darker the deeper it goes) runs down-left behind it and grows on each onset; the letter stretches
|
|
613
|
+
// taller on the onset and tears into horizontal slices that jump sideways on every beat.
|
|
614
|
+
void fxGlyph(vec2 q, vec2 S, vec3 src, int ch, int tone, vec4 clk, vec3 cInk, vec3 cHot, inout vec3 col) {
|
|
615
|
+
vec4 hit = stHit() * typeWarp;
|
|
616
|
+
float band = floor(q.y / (S.y / 9.0));
|
|
617
|
+
float h = hash12(vec2(band, clk.z * 1.37 + 5.0));
|
|
618
|
+
float dx = (fract(h * 7.0) * 2.0 - 1.0) * step(0.4, h) * max(hit.y, hit.x * 0.45) * S.x * 0.13;
|
|
619
|
+
vec2 qq = vec2(q.x - dx, S.y * 0.5 + (q.y - S.y * 0.5) / (1.0 + 0.2 * hit.x));
|
|
620
|
+
float raw = winM(qq, src, ch);
|
|
621
|
+
float m = crisp(raw, src.z);
|
|
622
|
+
float reach = (30.0 + 90.0 * hit.x) * U;
|
|
623
|
+
for (int i = 10; i >= 1; i--) {
|
|
624
|
+
float t = float(i) / 10.0;
|
|
625
|
+
float me = crisp(winM(qq - vec2(-0.8, 0.6) * reach * t, src, ch), src.z);
|
|
626
|
+
col = mix(col, cHot * (1.0 - 0.6 * t), me);
|
|
627
|
+
}
|
|
628
|
+
bool solid = tone == 2;
|
|
629
|
+
vec2 mc = microCov(gP, RENDERSIZE, clk, vec3(0.0, 0.0, 1.0), 2);
|
|
630
|
+
vec3 f = solid ? cInk : mix(fxFootage(gP), groundColor.rgb, mc.x * 0.6);
|
|
631
|
+
col = mix(col, f, m);
|
|
632
|
+
col = mix(col, solid ? groundColor.rgb : cInk, edgeOf(raw) * 0.9);
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
// 3: slit-scan word. Every row reads the hit history (beat pulse, onsets at 0.4) at its own delay, so each hit enters at the
|
|
636
|
+
// bottom row and travels up the letters as a sideways shear (direction chosen per hit); rows inside a shear jitter; the word
|
|
637
|
+
// smears into a streak on the beat (onsets smear at 0.3). The footage stays still behind the moving letter window.
|
|
638
|
+
void fxSlit(vec2 q, vec2 S, vec3 src, int ch, vec4 clk, vec3 cInk, vec3 cHot, inout vec3 col) {
|
|
639
|
+
vec4 hits = stHit() * typeWarp;
|
|
640
|
+
float hp = max(hits.y, 0.3 * hits.x);
|
|
641
|
+
float delay = (1.0 - clamp(q.y / S.y, 0.0, 1.0)) * 22.0;
|
|
642
|
+
float sh = 0.0;
|
|
643
|
+
for (int i = -2; i <= 2; i++) { sh += stHist(delay + float(i)).x * (i == 0 ? 0.32 : (abs(i) == 1 ? 0.22 : 0.12)); }
|
|
644
|
+
sh *= typeWarp;
|
|
645
|
+
float jit = (hash12(vec2(floor(q.y / max(U * 6.0, 2.0)), clk.z)) - 0.5) * abs(sh);
|
|
646
|
+
float dx = sh * S.x * 0.075 + jit * S.x * 0.04;
|
|
647
|
+
float dir = hash12(vec2(clk.z, 4.0)) < 0.5 ? 1.0 : -1.0;
|
|
648
|
+
float len = S.x * 0.2 * hp;
|
|
649
|
+
float streak = 0.0;
|
|
650
|
+
for (int i = 1; i < 13; i++) {
|
|
651
|
+
float t = float(i) / 12.0;
|
|
652
|
+
streak = max(streak, crisp(winM(vec2(q.x - dx - dir * t * len, q.y), src, ch), src.z) * (1.0 - t));
|
|
653
|
+
}
|
|
654
|
+
float raw = winM(vec2(q.x - dx, q.y), src, ch);
|
|
655
|
+
float m = crisp(raw, src.z);
|
|
656
|
+
col = mix(col, cHot, streak * (1.0 - m));
|
|
657
|
+
col = mix(col, fxFootage(gP), m);
|
|
658
|
+
col = mix(col, cInk, edgeOf(raw) * 0.9);
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
// 4: echo stack. The word repeats 2..10 times (the count follows the rms and jumps by up to 4 on the beat frame, by 1.6 on
|
|
662
|
+
// an onset), each copy stepped up-right and a little larger, painted back to front: odd copies solid hot, even copies knocked
|
|
663
|
+
// out to the ground, every edge in ink, and the footage in the front copy.
|
|
664
|
+
void fxEcho(vec2 q, vec2 S, vec3 src, int ch, vec3 cInk, vec3 cHot, vec3 cGnd, inout vec3 col) {
|
|
665
|
+
vec4 hits = stHit();
|
|
666
|
+
int n = min(2 + int(floor(typeWarp * (4.0 * stLevel().a + 4.0 * max(hits.y, 0.4 * hits.x)) + 0.5)), 11);
|
|
667
|
+
vec2 c = S * 0.5;
|
|
668
|
+
vec2 stp = vec2(S.x * 0.017, -S.y * 0.034);
|
|
669
|
+
for (int j = 0; j < 11; j++) {
|
|
670
|
+
int k = n - 1 - j;
|
|
671
|
+
if (k < 0) { break; }
|
|
672
|
+
float sk = 1.0 + 0.05 * float(k);
|
|
673
|
+
float raw = winM((q - c - stp * float(k)) / sk + c, src, ch);
|
|
674
|
+
float m = crisp(raw, src.z * sk);
|
|
675
|
+
bool odd = mod(float(k), 2.0) > 0.5;
|
|
676
|
+
col = mix(col, odd ? cHot : cGnd, m);
|
|
677
|
+
col = mix(col, cInk, edgeOf(raw) * (odd ? 0.95 : 0.8));
|
|
678
|
+
if (k == 0) { col = mix(col, fxFootage(gP), m); }
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
// 5: echo ripple. The word is ringed by 2..12 hairline outlines growing out of it from the centre of the cell (alternate rings
|
|
683
|
+
// hot, ink), the count following the rms and the beat as in the stack; the footage fills the word itself.
|
|
684
|
+
void fxRipple(vec2 q, vec2 S, vec3 src, int ch, vec3 cInk, vec3 cHot, inout vec3 col) {
|
|
685
|
+
vec4 hits = stHit();
|
|
686
|
+
int n = min(2 + int(floor(typeWarp * (5.0 * stLevel().a + 5.0 * max(hits.y, 0.4 * hits.x)) + 0.5)), 12);
|
|
687
|
+
vec2 c = S * 0.5;
|
|
688
|
+
for (int j = 0; j < 12; j++) {
|
|
689
|
+
int k = n - 1 - j;
|
|
690
|
+
if (k < 0) { break; }
|
|
691
|
+
float raw = winM((q - c) / (1.0 + 0.11 * float(k)) + c, src, ch);
|
|
692
|
+
if (k > 0) { col = mix(col, mod(float(k), 2.0) > 0.5 ? cHot : cInk, edgeOf(raw) * 0.9); continue; }
|
|
693
|
+
col = mix(col, fxFootage(gP), crisp(raw, src.z));
|
|
694
|
+
col = mix(col, cInk, edgeOf(raw) * 0.9);
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
// 6: type equalizer. The word is the analyzer: every column of the letters is filled solid up to the level of the spectrum band
|
|
699
|
+
// under it (bass at the left); above the level the letters are only an outline over a dim footage ghost.
|
|
700
|
+
void fxEq(vec2 q, vec2 S, vec3 src, int ch, vec3 cInk, vec3 cHot, inout vec3 col) {
|
|
701
|
+
float raw = winM(q, src, ch);
|
|
702
|
+
float m = crisp(raw, src.z);
|
|
703
|
+
float lv = clamp(bandAt(clamp(q.x / S.x, 0.0, 1.0)) + 0.3 * stHit().y * typeWarp, 0.0, 1.0);
|
|
704
|
+
float on = step(S.y * (1.0 - lv), q.y);
|
|
705
|
+
col = mix(col, fxFootage(gP), m * (1.0 - on) * 0.45);
|
|
706
|
+
col = mix(col, cHot, m * on);
|
|
707
|
+
col = mix(col, cInk, edgeOf(raw) * mix(0.9, 0.35, on));
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
void drawTypeFx(int v, vec4 aux, int ch, int tone, vec2 q, vec2 S, vec4 clk, vec3 cInk, vec3 cHot, inout vec3 col) {
|
|
711
|
+
int rot = int(aux.x + 0.5);
|
|
712
|
+
vec3 src = vec3(aux.yz, aux.w);
|
|
713
|
+
vec2 tq = rot == 1 ? vec2(S.y - q.y, q.x) : (rot == 2 ? vec2(q.y, S.x - q.x) : q);
|
|
714
|
+
vec2 TS = rot == 0 ? S : S.yx;
|
|
715
|
+
if (v == 1) {
|
|
716
|
+
vec2 mc = microCov(tq, TS, clk, src, ch);
|
|
717
|
+
col = mix(col, cInk, mc.x);
|
|
718
|
+
col = mix(col, cHot, mc.y);
|
|
719
|
+
}
|
|
720
|
+
if (v == 2) { fxGlyph(tq, TS, src, ch, tone, clk, cInk, cHot, col); }
|
|
721
|
+
if (v == 3) { fxSlit(tq, TS, src, ch, clk, cInk, cHot, col); }
|
|
722
|
+
if (v == 4) { fxEcho(tq, TS, src, ch, cInk, cHot, groundColor.rgb, col); }
|
|
723
|
+
if (v == 5) { fxRipple(tq, TS, src, ch, cInk, cHot, col); }
|
|
724
|
+
if (v == 6) { fxEq(tq, TS, src, ch, cInk, cHot, col); }
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
// Role 14, scene: a whole mixed-material collage in one cell (flat fields, an image treatment of the plate, geometric
|
|
728
|
+
// primitives, pixel matter, leader lines, instruments and several type roles). Compositions are written in unit space
|
|
729
|
+
// (height 1, width = cell aspect) so a scene scales with its cell. The scene reads the text sheet of its own set
|
|
730
|
+
// (input textSet) through its own positions, and the tint colours for what the three palette colours cannot hold.
|
|
731
|
+
// Hits: stHit().x onset pulse, .y beat pulse; the cut count (clk.x) moves on the beat.
|
|
732
|
+
vec2 scS;
|
|
733
|
+
float scU;
|
|
734
|
+
|
|
735
|
+
float scAA(float d) { return clamp(0.5 - d * scU, 0.0, 1.0); }
|
|
736
|
+
float scLine(float d, float w) { return clamp(0.5 * w - abs(d * scU) + 0.5, 0.0, 1.0); }
|
|
737
|
+
float scPx() { return max(2.0, floor(6.0 * U + 0.5)); }
|
|
738
|
+
float scCell() { return max(2.0, floor(3.0 * U + 0.5)); }
|
|
739
|
+
float scPlus(vec2 c, vec2 p, float arm) {
|
|
740
|
+
vec2 d = abs(c - p);
|
|
741
|
+
return max(scLine(c.y - p.y, 1.0) * step(d.x, arm), scLine(c.x - p.x, 1.0) * step(d.y, arm));
|
|
742
|
+
}
|
|
743
|
+
float scBox(vec2 c, vec2 lo, vec2 hi) { return step(lo.x, c.x) * step(c.x, hi.x) * step(lo.y, c.y) * step(c.y, hi.y); }
|
|
744
|
+
float sdBox(vec2 p, vec2 lo, vec2 hi) {
|
|
745
|
+
vec2 d = abs(p - 0.5 * (lo + hi)) - 0.5 * (hi - lo);
|
|
746
|
+
return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0);
|
|
747
|
+
}
|
|
748
|
+
float sdArch(vec2 p, vec2 lo, vec2 hi) {
|
|
749
|
+
float r = 0.5 * (hi.x - lo.x);
|
|
750
|
+
vec2 ctr = vec2(0.5 * (lo.x + hi.x), lo.y + r);
|
|
751
|
+
return p.y < ctr.y ? length(p - ctr) - r : sdBox(p, vec2(lo.x, ctr.y), hi);
|
|
752
|
+
}
|
|
753
|
+
float sdSeg(vec2 p, vec2 a, vec2 b) {
|
|
754
|
+
vec2 pa = p - a;
|
|
755
|
+
vec2 ba = b - a;
|
|
756
|
+
return length(pa - ba * clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0));
|
|
757
|
+
}
|
|
758
|
+
// rectangle with its four corners cut at 45 degrees by ch (the octagon media window)
|
|
759
|
+
float sdChamfer(vec2 p, vec2 lo, vec2 hi, float ch) {
|
|
760
|
+
vec2 q = abs(p - 0.5 * (lo + hi)) - 0.5 * (hi - lo);
|
|
761
|
+
return max(max(q.x, q.y), (q.x + q.y + ch) * 0.7071);
|
|
762
|
+
}
|
|
763
|
+
// starburst glyph: n thin rays from radius inner out to R (each ray as long as the spectrum band it is hashed to), turned by rot
|
|
764
|
+
float scBurst(vec2 p, float R, float inner, float rot, float n) {
|
|
765
|
+
float a = atan(p.y, p.x) + rot;
|
|
766
|
+
float id = floor(a * n / 6.28318);
|
|
767
|
+
float da = (fract(a * n / 6.28318) - 0.5) * 6.28318 / n;
|
|
768
|
+
float len = R * (0.45 + 0.55 * bandAt(fract(id * 0.37)));
|
|
769
|
+
float r = length(p);
|
|
770
|
+
return scLine(da * r, 1.0) * step(inner, r) * step(r, len);
|
|
771
|
+
}
|
|
772
|
+
float scBayer(vec2 pix) {
|
|
773
|
+
ivec2 p = ivec2(mod(pix, 8.0));
|
|
774
|
+
int v = 0;
|
|
775
|
+
for (int i = 0; i < 3; i++) { v = (v << 2) | ((((p.x ^ p.y) >> i) & 1) << 1) | ((p.y >> i) & 1); }
|
|
776
|
+
return (float(v) + 0.5) / 64.0;
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
// the plate cover-fitted into the window lo..hi (cell px)
|
|
780
|
+
vec3 scPlate(vec2 q, vec2 lo, vec2 hi) { return HAS_INPUT ? footageBody(q - lo, hi - lo, 0.0, 0) : vec3(0.3); }
|
|
781
|
+
float scTone(vec2 q, vec2 lo, vec2 hi, float gain, float lift) { return clamp((luma(scPlate(q, lo, hi)) - lift) * gain, 0.0, 1.0); }
|
|
782
|
+
|
|
783
|
+
// plate edge strength (central differences of the luma at step d px): the wireframe look
|
|
784
|
+
float scEdge(vec2 q, vec2 lo, vec2 hi, float d) {
|
|
785
|
+
float gx = luma(scPlate(q + vec2(d, 0.0), lo, hi)) - luma(scPlate(q - vec2(d, 0.0), lo, hi));
|
|
786
|
+
float gy = luma(scPlate(q + vec2(0.0, d), lo, hi)) - luma(scPlate(q - vec2(0.0, d), lo, hi));
|
|
787
|
+
return length(vec2(gx, gy));
|
|
788
|
+
}
|
|
789
|
+
// the text sheet at the same place on screen (1 : 1 for a full-frame cell)
|
|
790
|
+
float scSheet(vec2 q, int ch) { return sheetC(q * (RENDERSIZE / scS), ch); }
|
|
791
|
+
// a sheet word drawn with its own scale k (screen px per sheet px) so it can be squeezed or stretched: sheet point sheetLo lands at screen px o
|
|
792
|
+
float scWord(vec2 q, vec2 o, vec2 sheetLo, vec2 k, int ch) {
|
|
793
|
+
float m = sheetC(sheetLo + (q - o) / (k * scS.y / RENDERSIZE.y), ch);
|
|
794
|
+
return crisp(m, max(max(k.x, k.y), 1.0));
|
|
795
|
+
}
|
|
796
|
+
// the same with the horizontal strokes thinned (vertical erosion of d sheet px), for faux-tall type whose crossbars stretch
|
|
797
|
+
float scWordThin(vec2 q, vec2 o, vec2 sheetLo, vec2 k, int ch, float d) {
|
|
798
|
+
vec2 sp = sheetLo + (q - o) / (k * scS.y / RENDERSIZE.y);
|
|
799
|
+
float m = min(sheetC(sp, ch), min(sheetC(sp - vec2(0.0, d), ch), sheetC(sp + vec2(0.0, d), ch)));
|
|
800
|
+
return crisp(m, max(max(k.x, k.y), 1.0));
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
// dot halftone on a 30 degree grid: dot radius follows the plate under the dot centre; 1 where the dot is
|
|
804
|
+
float scDots(vec2 q, vec2 lo, vec2 hi, float pitch, float gain, float lift, float inv) {
|
|
805
|
+
mat2 R = mat2(0.866, 0.5, -0.5, 0.866);
|
|
806
|
+
vec2 g = R * q / pitch;
|
|
807
|
+
vec2 id = floor(g) + 0.5;
|
|
808
|
+
vec2 cq = transpose(R) * (id * pitch);
|
|
809
|
+
float l = scTone(cq, lo, hi, gain, lift);
|
|
810
|
+
l = mix(l, 1.0 - l, inv);
|
|
811
|
+
float r = 0.62 * sqrt(l);
|
|
812
|
+
return clamp((r - length(g - id)) * pitch + 0.5, 0.0, 1.0);
|
|
813
|
+
}
|
|
814
|
+
// QR-like stamp of 21 x 21 modules: 1 dark, 0 light, -1 outside; three finder squares, the rest re-seeded by seed
|
|
815
|
+
float scFinder(vec2 m, vec2 o) {
|
|
816
|
+
vec2 d = m - o;
|
|
817
|
+
if (d.x < 0.0 || d.y < 0.0 || d.x > 6.0 || d.y > 6.0) { return -1.0; }
|
|
818
|
+
bool ring = d.x < 0.5 || d.x > 5.5 || d.y < 0.5 || d.y > 5.5;
|
|
819
|
+
bool core = d.x > 1.5 && d.x < 4.5 && d.y > 1.5 && d.y < 4.5;
|
|
820
|
+
return ring || core ? 1.0 : 0.0;
|
|
821
|
+
}
|
|
822
|
+
float scQR(vec2 p, vec2 lo, float size, float seed) {
|
|
823
|
+
vec2 u = (p - lo) / size;
|
|
824
|
+
if (u.x < 0.0 || u.y < 0.0 || u.x >= 1.0 || u.y >= 1.0) { return -1.0; }
|
|
825
|
+
vec2 m = floor(u * 21.0);
|
|
826
|
+
float f = max(max(scFinder(m, vec2(0.0)), scFinder(m, vec2(14.0, 0.0))), scFinder(m, vec2(0.0, 14.0)));
|
|
827
|
+
if (f >= 0.0) { return f; }
|
|
828
|
+
if ((m.x < 8.0 && m.y < 8.0) || (m.x > 12.0 && m.y < 8.0) || (m.x < 8.0 && m.y > 12.0)) { return 0.0; }
|
|
829
|
+
return step(0.5, hash12(m + seed * 17.3));
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
// Scene 1, specimen: a deep ultramarine field; the plate as a single-tone lavender dither inside a tall arch; one ultra-tall
|
|
833
|
+
// thin word as a column; pink and cyan micro bars on the arch edges that are spectrum band levels; a solid black square with a
|
|
834
|
+
// semicircle that snaps to a new place of a fixed set on every cut; mono captions with live numbers. Palette: ground (field),
|
|
835
|
+
// ink (lavender), accent (pink), tintA (cyan), tintB (black). Text set 1.
|
|
836
|
+
vec2 spPair(float i) {
|
|
837
|
+
if (i < 0.5) { return vec2(1.44, 0.10); }
|
|
838
|
+
if (i < 1.5) { return vec2(0.50, 0.70); }
|
|
839
|
+
if (i < 2.5) { return vec2(1.44, 0.62); }
|
|
840
|
+
if (i < 3.5) { return vec2(1.14, 0.78); }
|
|
841
|
+
if (i < 4.5) { return vec2(0.50, 0.08); }
|
|
842
|
+
return vec2(1.22, 0.34);
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
void sceneSpecimen(vec2 q, vec2 S, vec4 clk, inout vec3 col) {
|
|
846
|
+
vec2 c = q / scU;
|
|
847
|
+
float A = S.x / S.y;
|
|
848
|
+
vec4 hit = stHit();
|
|
849
|
+
vec3 lav = inkColor.rgb;
|
|
850
|
+
vec3 pink = accentColor.rgb;
|
|
851
|
+
vec3 cyan = tintA.rgb;
|
|
852
|
+
vec3 blk = tintB.rgb;
|
|
853
|
+
col = groundColor.rgb;
|
|
854
|
+
col = mix(col, mix(groundColor.rgb, blk, 0.45), scAA(sdBox(c, vec2(0.03, 0.035), vec2(0.70, 0.965))));
|
|
855
|
+
vec2 lo = vec2(0.76, 0.07);
|
|
856
|
+
vec2 hi = vec2(1.36, 0.93);
|
|
857
|
+
// dithered plate in the arch
|
|
858
|
+
float px = scPx();
|
|
859
|
+
vec2 pix = floor(q / px);
|
|
860
|
+
float inside = scAA(sdArch(c, lo, hi));
|
|
861
|
+
float l = pow(scTone((pix + 0.5) * px, lo * scU, hi * scU, 1.6, 0.15), 0.65) * 0.92 + 0.08 * hit.y;
|
|
862
|
+
col = mix(col, mix(mix(groundColor.rgb, blk, 0.6), lav, step(scBayer(pix), l)), inside);
|
|
863
|
+
col = mix(col, lav, scLine(sdArch(c, lo - 0.016, hi + 0.016), 1.0));
|
|
864
|
+
// band-level micro bars on the straight sides of the arch: pink on the left, cyan on the right
|
|
865
|
+
float y0 = (lo.y + 0.5 * (hi.x - lo.x)) * scU;
|
|
866
|
+
float y1 = (hi.y - 0.02) * scU;
|
|
867
|
+
float row = floor((q.y - y0) / 4.0);
|
|
868
|
+
float t = clamp((row * 4.0 + 2.0) / (y1 - y0), 0.0, 1.0);
|
|
869
|
+
float inRow = step(0.0, q.y - y0) * step(q.y, y1) * step(mod(q.y - y0, 4.0), 2.0);
|
|
870
|
+
float lenL = floor((0.012 + 0.095 * bandAt(t)) * scU / 2.0) * 2.0;
|
|
871
|
+
float lenR = floor((0.012 + 0.095 * bandAt(1.0 - t * 0.8)) * scU / 2.0) * 2.0;
|
|
872
|
+
float xl = (lo.x - 0.016) * scU;
|
|
873
|
+
float xr = (hi.x + 0.016) * scU;
|
|
874
|
+
col = mix(col, pink, inRow * step(xl - lenL, q.x) * step(q.x, xl - 1.0));
|
|
875
|
+
col = mix(col, cyan, inRow * step(xr + 1.0, q.x) * step(q.x, xr + lenR));
|
|
876
|
+
// rules, ticks and a dot grid
|
|
877
|
+
float rule = max(scLine(c.y - 0.035, 1.0), scLine(c.y - 0.965, 1.0)) * step(0.05, c.x) * step(c.x, A - 0.05);
|
|
878
|
+
float tick = step(mod(q.x, 0.04 * scU), 1.0) * step(abs(c.y - 0.965), 0.014) * step(0.05, c.x) * step(c.x, A - 0.05);
|
|
879
|
+
col = mix(col, lav, max(rule * 0.8, tick * 0.8));
|
|
880
|
+
col = mix(col, lav, max(max(scPlus(c, vec2(0.03, 0.035), 0.016), scPlus(c, vec2(0.70, 0.035), 0.016)), max(scPlus(c, vec2(0.03, 0.965), 0.016), scPlus(c, vec2(0.70, 0.965), 0.016))));
|
|
881
|
+
vec2 dg = (c - vec2(1.44, 0.83)) / 0.026;
|
|
882
|
+
float dots = scAA((length(fract(dg) - 0.5) * 0.026 - 0.004)) * step(0.0, dg.x) * step(dg.x, 9.0) * step(0.0, dg.y) * step(dg.y, 4.0);
|
|
883
|
+
col = mix(col, lav, dots * 0.7);
|
|
884
|
+
// the tall word: Pretendard Thin stretched up and squeezed in
|
|
885
|
+
float w = scWordThin(q, vec2(0.05, -0.05) * scU, vec2(0.0, 0.0), vec2(0.35, 1.43), 0, 3.5);
|
|
886
|
+
col = mix(col, lav, w);
|
|
887
|
+
// the black square and semicircle: a new place of the fixed set on every cut
|
|
888
|
+
float i = mod(floor(clk.x) * 5.0 + floor(hash12(vec2(floor(clk.x / 6.0), 7.0)) * 6.0), 6.0);
|
|
889
|
+
vec2 P = spPair(i);
|
|
890
|
+
float s = 0.13;
|
|
891
|
+
float sq = scAA(sdBox(c, P, P + s));
|
|
892
|
+
vec2 sc = P + vec2(s, 0.5 * s);
|
|
893
|
+
sc.x += 0.03;
|
|
894
|
+
float semi = scAA(max(length(c - sc) - 0.5 * s, -(c.x - sc.x)));
|
|
895
|
+
col = mix(col, blk, max(sq, semi));
|
|
896
|
+
// captions and live numbers (MesloLGS NF)
|
|
897
|
+
col = mix(col, lav, scSheet(q, 1));
|
|
898
|
+
vec2 np = q - vec2(1.44, 0.50) * scU;
|
|
899
|
+
float fs = 0.03 * scU;
|
|
900
|
+
float num = aNum(np, fs, floor(stLevel().r * 99.0), 2) + aNum(np - vec2(3.0 * MONO_ADV * fs, 0.0), fs, floor(stLevel().g * 99.0), 2) + aNum(np - vec2(6.0 * MONO_ADV * fs, 0.0), fs, floor(stLevel().b * 99.0), 2);
|
|
901
|
+
col = mix(col, pink, min(num, 1.0));
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
// Scene 2, wiring: a black ground, the plate as a cyan / yellow duotone with scanline bands that re-seed on every cut, five yellow
|
|
905
|
+
// cables from fixed points on the CRT wall to boxed annotations (small Monument Extended caps and live readouts in a pixel font),
|
|
906
|
+
// quarter pixel arcs and a dot grid in the bottom-left corner, and a small crimson pixel glyph that blinks on every onset.
|
|
907
|
+
// Each onset sends a packet down the next cable and flashes its box. Palette: ground (black), ink (label white), accent (yellow),
|
|
908
|
+
// tintA (cyan), tintB (crimson). Text set 2.
|
|
909
|
+
const vec2 W_A[5] = vec2[5](vec2(0.663, 0.4355), vec2(0.573, 0.5775), vec2(0.663, 0.7195), vec2(1.115, 0.4355), vec2(1.025, 0.7195));
|
|
910
|
+
const vec2 W_B[5] = vec2[5](vec2(0.05, 0.14), vec2(0.05, 0.40), vec2(0.05, 0.62), vec2(1.43, 0.10), vec2(1.43, 0.62));
|
|
911
|
+
const vec2 W_SZ = vec2(0.30, 0.105);
|
|
912
|
+
const int W_GLYPH[7] = int[7](20, 62, 107, 127, 62, 34, 65);
|
|
913
|
+
|
|
914
|
+
vec2 wTail(int i) { return W_B[i] + (i < 3 ? vec2(W_SZ.x, 0.5 * W_SZ.y) : vec2(0.0, 0.5 * W_SZ.y)); }
|
|
915
|
+
vec2 wElbow(vec2 A, vec2 T) { return vec2(T.x + sign(A.x - T.x) * abs(A.y - T.y), T.y); }
|
|
916
|
+
float wCable(vec2 c, vec2 A, vec2 T, float w) {
|
|
917
|
+
vec2 E = wElbow(A, T);
|
|
918
|
+
return max(scLine(sdSeg(c, A, E), w), scLine(sdSeg(c, E, T), w));
|
|
919
|
+
}
|
|
920
|
+
vec2 wAlong(vec2 A, vec2 T, float t) {
|
|
921
|
+
vec2 E = wElbow(A, T);
|
|
922
|
+
float l1 = length(E - A);
|
|
923
|
+
float d = t * (l1 + length(T - E));
|
|
924
|
+
return d < l1 ? mix(A, E, d / max(l1, 1e-4)) : mix(E, T, (d - l1) / max(length(T - E), 1e-4));
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
void sceneWiring(vec2 q, vec2 S, vec4 clk, inout vec3 col) {
|
|
928
|
+
vec2 c = q / scU;
|
|
929
|
+
float A = S.x / S.y;
|
|
930
|
+
vec4 hit = stHit();
|
|
931
|
+
vec3 white = inkColor.rgb;
|
|
932
|
+
vec3 yel = accentColor.rgb;
|
|
933
|
+
vec3 cyan = tintA.rgb;
|
|
934
|
+
vec3 red = tintB.rgb;
|
|
935
|
+
float cut = floor(clk.x);
|
|
936
|
+
// plate: cyan / yellow duotone, scanline bands re-seeded on the cut, one slice thrown sideways on the beat
|
|
937
|
+
float sliceY = hash12(vec2(cut, 3.0));
|
|
938
|
+
float shift = step(abs(c.y - sliceY), 0.025) * hit.y * 0.05 * scU;
|
|
939
|
+
float l = clamp((luma(scPlate(q + vec2(shift, 0.0), vec2(0.0), S)) - 0.1) * 1.5, 0.0, 1.0);
|
|
940
|
+
vec3 d = mix(groundColor.rgb, cyan * 0.45, smoothstep(0.0, 0.4, l));
|
|
941
|
+
d = mix(d, cyan, smoothstep(0.35, 0.7, l));
|
|
942
|
+
d = mix(d, yel, smoothstep(0.66, 0.95, l));
|
|
943
|
+
float band = step(0.62, hash12(vec2(floor(c.y / 0.03), cut)));
|
|
944
|
+
d *= (1.0 - 0.22 * step(0.5, fract(c.y / 0.012))) * (1.0 - 0.5 * band);
|
|
945
|
+
d *= mix(0.45, 1.0, smoothstep(1.05, 0.3, length((c - vec2(0.5 * A, 0.5)) * vec2(0.8, 1.2))));
|
|
946
|
+
col = d;
|
|
947
|
+
// cables and anchors
|
|
948
|
+
int act = int(mod(clk.z, 5.0));
|
|
949
|
+
float age = float(FRAMEINDEX) - clk.w;
|
|
950
|
+
for (int i = 0; i < 5; i++) {
|
|
951
|
+
vec2 T = wTail(i);
|
|
952
|
+
bool on = i == act && clk.z > 0.5;
|
|
953
|
+
float flash = on ? step(0.3, hit.x) : 0.0;
|
|
954
|
+
col = mix(col, vec3(0.0), wCable(c, W_A[i], T, 4.0) * 0.85);
|
|
955
|
+
col = mix(col, mix(yel, white, flash), wCable(c, W_A[i], T, on ? 2.0 : 1.2));
|
|
956
|
+
float ring = scLine(length(c - W_A[i]) - 0.014, 1.2);
|
|
957
|
+
col = mix(col, vec3(0.0), scAA(length(c - W_A[i]) - 0.018) * 0.5);
|
|
958
|
+
col = mix(col, yel, max(ring, scAA(sdBox(c, W_A[i] - 0.004, W_A[i] + 0.004))));
|
|
959
|
+
if (on && age < 9.0) {
|
|
960
|
+
vec2 pp = wAlong(W_A[i], T, (age + 1.0) / 9.0);
|
|
961
|
+
col = mix(col, white, scAA(sdBox(c, pp - 0.007, pp + 0.007)));
|
|
962
|
+
}
|
|
963
|
+
// box: black plate, yellow outline, a live readout in the pixel font and a segmented level bar
|
|
964
|
+
float bf = scAA(sdBox(c, W_B[i], W_B[i] + W_SZ));
|
|
965
|
+
col = mix(col, mix(vec3(0.0), yel, flash), bf * 0.9);
|
|
966
|
+
col = mix(col, yel, scLine(sdBox(c, W_B[i], W_B[i] + W_SZ), 1.0));
|
|
967
|
+
float lev = bandAt(0.06 + 0.2 * float(i));
|
|
968
|
+
float cell = cellPx(0.0062 * scU);
|
|
969
|
+
vec2 np = q - (W_B[i] + vec2(0.014, 0.058)) * scU;
|
|
970
|
+
float num = numTxt(np, vec2(0.0), cell, floor(lev * 999.0), 3);
|
|
971
|
+
vec2 bp = (c - (W_B[i] + vec2(0.115, 0.064))) / vec2(0.17, 0.02);
|
|
972
|
+
float seg = step(0.0, bp.x) * step(bp.x, 1.0) * step(0.0, bp.y) * step(bp.y, 1.0) * step(mod(bp.x * 14.0, 1.0), 0.62);
|
|
973
|
+
float litSeg = step(bp.x, lev);
|
|
974
|
+
col = mix(col, mix(flash > 0.5 ? vec3(0.0) : yel, cyan, 1.0 - litSeg), seg * mix(0.35, 1.0, litSeg));
|
|
975
|
+
col = mix(col, flash > 0.5 ? vec3(0.0) : yel, min(num, 1.0));
|
|
976
|
+
}
|
|
977
|
+
// pixel arcs and a dot grid, bottom-left
|
|
978
|
+
float px = scPx();
|
|
979
|
+
vec2 pc = (floor(q / px) + 0.5) * px - vec2(0.0, S.y);
|
|
980
|
+
float r = length(pc) / scU;
|
|
981
|
+
float ring = floor((r - 0.05) / 0.036);
|
|
982
|
+
float ang = atan(-pc.y, pc.x) / 1.5708;
|
|
983
|
+
float seg = floor(ang * (5.0 + ring));
|
|
984
|
+
float arc = step(0.0, ring) * step(ring, 5.0) * step(fract((r - 0.05) / 0.036), 0.55) * step(0.0, ang) * step(ang, 1.0) * step(mod(seg + cut * (ring + 1.0), 3.0), 1.5);
|
|
985
|
+
col = mix(col, yel, arc);
|
|
986
|
+
vec2 dg = (c - vec2(0.27, 0.935)) / 0.026;
|
|
987
|
+
float dots = scAA(length(fract(dg) - 0.5) * 0.026 - 0.004) * step(0.0, dg.x) * step(dg.x, 12.0) * step(0.0, dg.y) * step(dg.y, 2.0);
|
|
988
|
+
col = mix(col, cyan, dots);
|
|
989
|
+
// the crimson pixel glyph: dim, full for 5 frames after every onset
|
|
990
|
+
vec2 gp = floor((c - vec2(0.405, 0.052)) / 0.0118);
|
|
991
|
+
float gl = 0.0;
|
|
992
|
+
if (gp.x >= 0.0 && gp.x < 7.0 && gp.y >= 0.0 && gp.y < 7.0) { gl = float((W_GLYPH[int(gp.y)] >> (6 - int(gp.x))) & 1); }
|
|
993
|
+
col = mix(col, red * (age < 5.0 && clk.z > 0.5 ? 1.0 : 0.3), gl);
|
|
994
|
+
// letterbox, corner brackets, label caps (Monument Extended)
|
|
995
|
+
col = mix(col, vec3(0.0), scAA(sdBox(c, vec2(-1.0), vec2(A + 1.0, 0.045))) + scAA(sdBox(c, vec2(-1.0, 0.955), vec2(A + 1.0, 2.0))));
|
|
996
|
+
vec2 a = min(c - 0.012, vec2(A, 1.0) - c - 0.012);
|
|
997
|
+
col = mix(col, white, max(scLine(a.y, 1.0) * step(a.x, 0.03), scLine(a.x, 1.0) * step(a.y, 0.03)) * step(0.0, min(a.x, a.y) + 0.001));
|
|
998
|
+
col = mix(col, white, scSheet(q, 0) * 0.9);
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
// Scene 3, field-cut: a collage over time. Every beat hard-cuts to the next of four full fields, each with its own fixed
|
|
1002
|
+
// composition: acid lime with a halftone of the plate, a black dot-matrix tower whose height is the bass and rule marks;
|
|
1003
|
+
// signal orange with rows of a condensed blue word that shear on every onset and a blue dither window of the plate; ultramarine
|
|
1004
|
+
// with the plate in a ringed circle, a Hangul word and checker blocks; a white field with the plate torn into RGB pixel slabs and
|
|
1005
|
+
// a lime brush chunk. Palette: ground (black), ink (white), accent (lime), tintA (orange), tintB (ultramarine).
|
|
1006
|
+
// Text set 3: r the condensed word, g the Hangul word, b the labels.
|
|
1007
|
+
void fcLime(vec2 q, vec2 c, vec4 hit, inout vec3 col) {
|
|
1008
|
+
vec3 blk = groundColor.rgb;
|
|
1009
|
+
col = accentColor.rgb;
|
|
1010
|
+
vec2 lo = vec2(0.07, 0.10);
|
|
1011
|
+
vec2 hi = vec2(0.95, 0.68);
|
|
1012
|
+
float pitch = max(3.0, 14.0 * U);
|
|
1013
|
+
col = mix(col, blk, scDots(q, lo * scU, hi * scU, pitch, 1.5, 0.15, 1.0) * scBox(c, lo, hi));
|
|
1014
|
+
col = mix(col, blk, max(max(scPlus(c, lo - 0.03, 0.02), scPlus(c, vec2(hi.x + 0.03, lo.y - 0.03), 0.02)), max(scPlus(c, vec2(lo.x - 0.03, hi.y + 0.03), 0.02), scPlus(c, hi + 0.03, 0.02))));
|
|
1015
|
+
// the bass tower: 6 x 28 dots, lit from the bottom up to the bass level
|
|
1016
|
+
float lv = stLevel().r;
|
|
1017
|
+
vec2 tg = (c - vec2(1.07, 0.93)) / vec2(0.026, -0.026);
|
|
1018
|
+
vec2 id = floor(tg);
|
|
1019
|
+
if (id.x >= 0.0 && id.x < 6.0 && id.y >= 0.0 && id.y < 28.0) {
|
|
1020
|
+
float h = (lv * 26.0 + 2.0 + 3.0 * hit.y) * (1.0 - 0.2 * hash12(vec2(id.x, 3.0)));
|
|
1021
|
+
float lit = step(id.y + 0.5, h);
|
|
1022
|
+
col = mix(col, blk, scAA(length(fract(tg) - 0.5) * 0.026 - mix(0.0035, 0.0115, lit)) * mix(0.4, 1.0, lit));
|
|
1023
|
+
}
|
|
1024
|
+
// label bar, live number, rule with ticks, readout rows
|
|
1025
|
+
col = mix(col, blk, scAA(sdBox(c, vec2(1.36, 0.14), vec2(1.72, 0.27))));
|
|
1026
|
+
col = mix(col, accentColor.rgb, scSheet(q, 2) * scBox(c, vec2(1.36, 0.14), vec2(1.72, 0.27)));
|
|
1027
|
+
float cell = cellPx(0.0125 * scU);
|
|
1028
|
+
col = mix(col, blk, min(numTxt(q, vec2(1.36, 0.31) * scU, cell, floor(lv * 999.0), 3), 1.0));
|
|
1029
|
+
col = mix(col, blk, max(scLine(c.y - 0.76, 1.0), step(mod(q.x, 0.04 * scU), 1.0) * step(abs(c.y - 0.77), 0.012)) * step(0.07, c.x) * step(c.x, 1.72));
|
|
1030
|
+
float rc = scCell();
|
|
1031
|
+
float rows = 0.0;
|
|
1032
|
+
for (int i = 0; i < 3; i++) {
|
|
1033
|
+
vec2 o = vec2(1.36, 0.47 + 0.075 * float(i)) * scU;
|
|
1034
|
+
float v = floor(stLevel()[i] * 999.0);
|
|
1035
|
+
rows = max(rows, i == 0 ? txt4(q, o, rc, 66, 83, 83, 0) : (i == 1 ? txt4(q, o, rc, 77, 73, 68, 0) : txt4(q, o, rc, 84, 82, 66, 0)));
|
|
1036
|
+
rows = max(rows, numTxt(q, o + vec2(16.0 * rc, 0.0), rc, v, 3));
|
|
1037
|
+
rows = max(rows, scBox(c, vec2(1.36, 0.47 + 0.075 * float(i) + 0.05), vec2(1.36 + 0.36 * stLevel()[i], 0.47 + 0.075 * float(i) + 0.056)));
|
|
1038
|
+
}
|
|
1039
|
+
col = mix(col, blk, rows);
|
|
1040
|
+
col = mix(col, blk, scBox(c, vec2(0.07, 0.82), vec2(0.07 + 0.88 * hit.y, 0.84)));
|
|
1041
|
+
col = mix(col, blk, numTxt(q, vec2(0.07, 0.88) * scU, rc, mod(float(FRAMEINDEX), 1000.0), 3));
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
void fcOrange(vec2 q, vec2 c, vec4 clk, vec4 hit, inout vec3 col) {
|
|
1045
|
+
vec3 blue = tintB.rgb;
|
|
1046
|
+
vec3 blk = groundColor.rgb;
|
|
1047
|
+
col = tintA.rgb;
|
|
1048
|
+
float row = floor((c.y - 0.035) / 0.134);
|
|
1049
|
+
float ry = q.y - (0.035 + row * 0.134) * scU;
|
|
1050
|
+
float h = hash12(vec2(row, clk.z));
|
|
1051
|
+
float shear = (fract(h * 7.0) < 0.5 ? -1.0 : 1.0) * (0.06 + 0.1 * fract(h * 11.0)) * step(0.45, hit.x) * step(h, 0.3) * scU;
|
|
1052
|
+
float pitch = 0.43 * scU;
|
|
1053
|
+
float lx = mod(q.x - (mod(row, 2.0) * 0.215 + 0.02) * scU - shear, pitch);
|
|
1054
|
+
float k = scS.y / RENDERSIZE.y;
|
|
1055
|
+
float m = crisp(sheetC(vec2(lx / (0.4 * k), 0.0333 * RENDERSIZE.y + (ry - 0.006 * scU) / (0.5 * k)), 0), 1.0) * step(0.0, row) * step(row, 6.0) * step(0.0, ry);
|
|
1056
|
+
col = mix(col, blue, m);
|
|
1057
|
+
vec2 lo = vec2(0.62, 0.38);
|
|
1058
|
+
vec2 hi = vec2(1.20, 0.66);
|
|
1059
|
+
float px = scPx();
|
|
1060
|
+
vec2 pix = floor(q / px);
|
|
1061
|
+
float win = scBox(c, lo, hi);
|
|
1062
|
+
float l = scTone((pix + 0.5) * px, lo * scU, hi * scU, 1.7, 0.2);
|
|
1063
|
+
col = mix(col, mix(tintA.rgb, blue, step(scBayer(pix), l)), win);
|
|
1064
|
+
col = mix(col, blk, max(scLine(sdBox(c, lo, hi), 1.5), max(max(scPlus(c, vec2(0.26, 0.20), 0.025), scPlus(c, vec2(1.45, 0.86), 0.025)), scPlus(c, vec2(1.62, 0.18), 0.025))));
|
|
1065
|
+
float cell = scCell();
|
|
1066
|
+
col = mix(col, blk, max(txt4(q, vec2(0.62, 0.68) * scU, cell, 82, 79, 87, 0), numTxt(q, vec2(0.62 + 0.06, 0.68) * scU, cell, mod(row + clk.z, 100.0), 2)));
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
void fcBlue(vec2 q, vec2 c, vec4 clk, inout vec3 col) {
|
|
1070
|
+
vec3 white = inkColor.rgb;
|
|
1071
|
+
col = tintB.rgb;
|
|
1072
|
+
vec2 ctr = vec2(1.22, 0.50);
|
|
1073
|
+
float R = 0.34;
|
|
1074
|
+
float d = length(c - ctr);
|
|
1075
|
+
vec3 f = clamp((scPlate(q, (ctr - R) * scU, (ctr + R) * scU) - 0.12) * 1.5, 0.0, 1.0);
|
|
1076
|
+
col = mix(col, f, scAA((d - R) * 1.0));
|
|
1077
|
+
float a = atan(c.y - ctr.y, c.x - ctr.x) / 6.28318;
|
|
1078
|
+
float tk = fract(a * 48.0 + floor(clk.x) * 0.5);
|
|
1079
|
+
float tickR = step(R + 0.07, d) * step(d, R + 0.07 + 0.03 * (mod(floor(a * 48.0 + floor(clk.x) * 0.5), 4.0) < 0.5 ? 1.8 : 1.0)) * step(tk, 0.16);
|
|
1080
|
+
col = mix(col, white, max(max(scLine(d - R - 0.025, 1.0), scLine(d - R - 0.05, 1.0) * step(fract(a * 24.0), 0.6)), tickR));
|
|
1081
|
+
col = mix(col, white, scSheet(q, 1));
|
|
1082
|
+
col = mix(col, groundColor.rgb, scAA(sdBox(c, vec2(0.07, 0.66), vec2(0.74, 0.76))));
|
|
1083
|
+
col = mix(col, accentColor.rgb, scSheet(q, 2) * scBox(c, vec2(0.07, 0.66), vec2(0.74, 0.76)));
|
|
1084
|
+
vec2 ck = floor((c - vec2(0.07, 0.83)) / 0.02);
|
|
1085
|
+
float chk = step(0.0, ck.x) * step(ck.x, 15.0) * step(0.0, ck.y) * step(ck.y, 4.0) * step(1.0, mod(ck.x + ck.y, 2.0));
|
|
1086
|
+
col = mix(col, groundColor.rgb, chk);
|
|
1087
|
+
col = mix(col, white, max(scPlus(c, vec2(0.05, 0.05), 0.02), scPlus(c, vec2(0.76, 0.05), 0.02)));
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
void fcWhite(vec2 q, vec2 c, float A, vec4 clk, vec4 hit, inout vec3 col) {
|
|
1091
|
+
vec3 blk = groundColor.rgb;
|
|
1092
|
+
col = inkColor.rgb;
|
|
1093
|
+
vec2 lo = vec2(0.06, 0.06);
|
|
1094
|
+
vec2 hi = vec2(A - 0.06, 0.94);
|
|
1095
|
+
float amt = 0.3 + 0.7 * step(0.7, hit.y);
|
|
1096
|
+
vec2 sl = floor(c / vec2(0.2, 0.045));
|
|
1097
|
+
float hs = hash12(vec2(sl.y, floor(clk.x) + 0.37 * sl.x));
|
|
1098
|
+
float off = step(0.55, hs) * (fract(hs * 13.0) - 0.5) * 0.18 * amt * scU;
|
|
1099
|
+
vec2 qq = q + vec2(off, 0.0);
|
|
1100
|
+
if (hs > 0.88) { qq = (floor(qq / 14.0) + 0.5) * 14.0; }
|
|
1101
|
+
float sp = 0.014 * amt * scU * step(0.5, hs);
|
|
1102
|
+
vec3 f = vec3(scPlate(qq + vec2(sp, 0.0), lo * scU, hi * scU).r, scPlate(qq, lo * scU, hi * scU).g, scPlate(qq - vec2(sp, 0.0), lo * scU, hi * scU).b);
|
|
1103
|
+
col = mix(col, clamp((f - 0.1) * 1.3, 0.0, 1.0), scBox(c, lo, hi));
|
|
1104
|
+
float ragged = 0.72 - 0.08 * hash12(vec2(floor(c.y / 0.012), 1.0)) - 0.1 * hit.y;
|
|
1105
|
+
col = mix(col, accentColor.rgb, scBox(c, vec2(0.30, 0.46), vec2(ragged, 0.54)));
|
|
1106
|
+
float cell = scCell();
|
|
1107
|
+
col = mix(col, blk, max(txt4(q, vec2(0.07, 0.955) * scU, cell, 70, 82, 77, 0), numTxt(q, vec2(0.07 + 0.045, 0.955) * scU, cell, mod(float(FRAMEINDEX), 1000.0), 3)));
|
|
1108
|
+
col = mix(col, blk, max(scPlus(c, vec2(0.03, 0.03), 0.018), scPlus(c, vec2(A - 0.03, 0.03), 0.018)));
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
void sceneFieldCut(vec2 q, vec2 S, vec4 clk, inout vec3 col) {
|
|
1112
|
+
vec2 c = q / scU;
|
|
1113
|
+
vec4 hit = stHit();
|
|
1114
|
+
int f = int(mod(floor(clk.x * 0.5), 4.0));
|
|
1115
|
+
if (f == 0) { fcLime(q, c, hit, col); }
|
|
1116
|
+
if (f == 1) { fcOrange(q, c, clk, hit, col); }
|
|
1117
|
+
if (f == 2) { fcBlue(q, c, clk, col); }
|
|
1118
|
+
if (f == 3) { fcWhite(q, c, S.x / S.y, clk, hit, col); }
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
// Scene 4, pattern-sheet: a bone sheet inside a signal-green frame border. The plate is a black line-screen engraving inside the
|
|
1122
|
+
// big circle; a heavy grotesk label between magenta serif quote marks; outline circles whose radius steps on every onset; thin
|
|
1123
|
+
// rules, ticks and crosshairs; QR-like pixel stamps that re-seed on every beat; a vertical waveform strip with a 0 to 5 ruler on the
|
|
1124
|
+
// left edge. Palette: ground (frame green), ink (black), accent (magenta), tintA (bone). Text set 4: r the label and caption,
|
|
1125
|
+
// g the quote marks.
|
|
1126
|
+
void scenePattern(vec2 q, vec2 S, vec4 clk, inout vec3 col) {
|
|
1127
|
+
vec2 c = q / scU;
|
|
1128
|
+
float A = S.x / S.y;
|
|
1129
|
+
vec3 ink = inkColor.rgb;
|
|
1130
|
+
vec3 mag = accentColor.rgb;
|
|
1131
|
+
vec3 bone = tintA.rgb;
|
|
1132
|
+
float cut = floor(clk.x);
|
|
1133
|
+
col = groundColor.rgb;
|
|
1134
|
+
col = mix(col, bone, scAA(sdBox(c, vec2(0.05), vec2(A - 0.05, 0.95))));
|
|
1135
|
+
// the big circle with the plate as a horizontal line screen
|
|
1136
|
+
vec2 ctr = vec2(1.30, 0.46);
|
|
1137
|
+
float R = 0.31;
|
|
1138
|
+
float pitch = max(3.0, 8.0 * U);
|
|
1139
|
+
float yc = (floor(q.y / pitch) + 0.5) * pitch;
|
|
1140
|
+
float l = scTone(vec2(q.x, yc), (ctr - R) * scU, (ctr + R) * scU, 1.5, 0.12);
|
|
1141
|
+
float line = clamp(((1.0 - l) * 0.95 * pitch * 0.5) - abs(q.y - yc) + 0.5, 0.0, 1.0);
|
|
1142
|
+
float inC = scAA(length(c - ctr) - R);
|
|
1143
|
+
col = mix(col, mix(bone, ink, line), inC);
|
|
1144
|
+
col = mix(col, ink, scLine(length(c - ctr) - R, 1.6));
|
|
1145
|
+
// outline circles; the radii step on every onset
|
|
1146
|
+
float st = mod(clk.z, 5.0);
|
|
1147
|
+
col = mix(col, ink, scLine(length(c - vec2(0.98, 0.74)) - (0.14 + 0.014 * st), 1.2));
|
|
1148
|
+
col = mix(col, ink, scLine(length(c - vec2(0.98, 0.74)) - (0.2 + 0.014 * st), 1.2) * step(0.0, sin(atan(c.y - 0.74, c.x - 0.98) * 18.0 + 1.0)));
|
|
1149
|
+
col = mix(col, mag, scLine(length(c - vec2(1.62, 0.80)) - (0.06 + 0.012 * st), 2.0));
|
|
1150
|
+
col = mix(col, ink, scLine(length(c - vec2(1.62, 0.80)) - 0.1, 1.0));
|
|
1151
|
+
// rules, ticks and crosshairs
|
|
1152
|
+
float ex = step(0.2, c.x) * step(c.x, A - 0.05);
|
|
1153
|
+
col = mix(col, ink, max(scLine(c.y - 0.87, 1.2) * ex, step(mod(q.x, 0.025 * scU), 1.0) * step(abs(c.y - 0.885), 0.013) * ex));
|
|
1154
|
+
col = mix(col, ink, scLine(c.x - 0.92, 1.0) * step(0.05, c.y) * step(c.y, 0.32) * 0.9);
|
|
1155
|
+
col = mix(col, ink, scLine((c.x - 0.2) - (0.95 - c.y), 1.0) * step(0.2, c.x) * step(c.x, 0.5) * step(0.75, c.y) * 0.8);
|
|
1156
|
+
col = mix(col, ink, scAA(length(c - vec2(0.92, 0.87)) - 0.016));
|
|
1157
|
+
col = mix(col, mag, scAA(length(c - vec2(1.62, 0.80)) - 0.016));
|
|
1158
|
+
for (int i = 0; i < 4; i++) {
|
|
1159
|
+
vec2 p = vec2(0.26 + 0.52 * float(i), 0.46);
|
|
1160
|
+
col = mix(col, ink, max(scLine(c.y - p.y, 1.0) * step(abs(c.x - p.x), 0.018), scLine(c.x - p.x, 1.0) * step(abs(c.y - p.y), 0.018)) * step(float(i), 1.5));
|
|
1161
|
+
}
|
|
1162
|
+
// QR stamps, re-seeded on the beat
|
|
1163
|
+
float q1 = scQR(c, vec2(0.25, 0.09), 0.17, cut);
|
|
1164
|
+
float q2 = scQR(c, vec2(0.62, 0.09), 0.11, cut + 41.0);
|
|
1165
|
+
col = mix(col, ink, step(0.5, q1));
|
|
1166
|
+
col = mix(col, ink, step(-0.5, q2));
|
|
1167
|
+
col = mix(col, bone, step(0.5, q2));
|
|
1168
|
+
// the vertical waveform strip and its 0..5 ruler
|
|
1169
|
+
float t = clamp((c.y - 0.09) / 0.82, 0.0, 1.0);
|
|
1170
|
+
float amp = clamp(waveI(floor(t * 255.0) * 2.0) * scopeGain * 0.08, -0.028, 0.028);
|
|
1171
|
+
float rowOn = step(mod(q.y, 2.0), 1.0);
|
|
1172
|
+
float wv = step(0.075, c.x) * step(c.x, 0.135) * step(0.09, c.y) * step(c.y, 0.91) * rowOn * step(abs(c.x - 0.105), abs(amp) + 0.0015);
|
|
1173
|
+
col = mix(col, ink, wv);
|
|
1174
|
+
col = mix(col, ink, scLine(sdBox(c, vec2(0.075, 0.09), vec2(0.135, 0.91)), 1.0));
|
|
1175
|
+
float rk = (c.y - 0.09) / 0.82 * 25.0;
|
|
1176
|
+
float major = step(abs(rk - floor(rk / 5.0 + 0.5) * 5.0), 0.12) * step(0.0, rk) * step(rk, 25.2);
|
|
1177
|
+
float minor = step(abs(rk - floor(rk + 0.5)), 0.12) * step(0.0, rk) * step(rk, 25.2);
|
|
1178
|
+
col = mix(col, ink, max(major * step(0.14, c.x) * step(c.x, 0.165), minor * step(0.14, c.x) * step(c.x, 0.152)));
|
|
1179
|
+
float dc = scCell();
|
|
1180
|
+
for (int i = 0; i < 6; i++) { col = mix(col, ink, numTxt(q, vec2(0.172, 0.09 + 0.164 * float(i) - 0.012) * scU, dc, float(i), 1)); }
|
|
1181
|
+
// the label and the quote marks
|
|
1182
|
+
col = mix(col, ink, scSheet(q, 0));
|
|
1183
|
+
col = mix(col, mag, scSheet(q, 1));
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
// Scene 5, anatomy: a sepia paper field, a huge cropped serif numeral, a dark panel holding the plate as a cream hairline wireframe
|
|
1187
|
+
// (edge detection), a thin ring around it, three callout cables to labels, a checkerboard tower of the mid level and tiny code
|
|
1188
|
+
// columns. The wireframe grows denser on every beat and a rust scan band jumps to a new height on every cut, turning the lines it
|
|
1189
|
+
// crosses rust. Palette: ground (tan paper), ink (umber), accent (rust), tintA (dark umber), tintB (cream). Text set 5: Times and
|
|
1190
|
+
// Pretendard Light.
|
|
1191
|
+
void sceneAnatomy(vec2 q, vec2 S, vec4 clk, inout vec3 col) {
|
|
1192
|
+
vec2 c = q / scU;
|
|
1193
|
+
float A = S.x / S.y;
|
|
1194
|
+
vec4 hit = stHit();
|
|
1195
|
+
vec3 ink = inkColor.rgb;
|
|
1196
|
+
vec3 rust = accentColor.rgb;
|
|
1197
|
+
vec3 dark = tintA.rgb;
|
|
1198
|
+
vec3 cream = tintB.rgb;
|
|
1199
|
+
col = groundColor.rgb;
|
|
1200
|
+
col = mix(col, ink, scSheet(q, 0));
|
|
1201
|
+
vec2 lo = vec2(0.52, 0.05);
|
|
1202
|
+
vec2 hi = vec2(1.30, 0.95);
|
|
1203
|
+
float inP = scBox(c, lo, hi);
|
|
1204
|
+
col = mix(col, dark, inP);
|
|
1205
|
+
float e = scEdge(q, lo * scU, hi * scU, max(1.5, 4.0 * U));
|
|
1206
|
+
float thr = 0.1 - 0.05 * hit.y;
|
|
1207
|
+
float wire = smoothstep(thr, thr + 0.07, e) * inP;
|
|
1208
|
+
float bandY = 0.08 + 0.84 * fract(floor(clk.x) * 0.137);
|
|
1209
|
+
float inBand = step(abs(c.y - bandY), 0.03);
|
|
1210
|
+
col = mix(col, cream, 0.14 * inBand * inP);
|
|
1211
|
+
col = mix(col, mix(cream, rust, inBand), wire);
|
|
1212
|
+
col = mix(col, ink, scLine(sdBox(c, lo, hi), 1.0));
|
|
1213
|
+
// ring and ticks around the panel
|
|
1214
|
+
vec2 ctr = vec2(0.91, 0.5);
|
|
1215
|
+
float d = length(c - ctr);
|
|
1216
|
+
float a = atan(c.y - ctr.y, c.x - ctr.x) / 6.28318;
|
|
1217
|
+
col = mix(col, ink, max(scLine(d - 0.47, 1.0), scLine(d - 0.5, 1.0) * step(fract(a * 90.0), 0.35)));
|
|
1218
|
+
// callout cables and labels
|
|
1219
|
+
for (int i = 0; i < 3; i++) {
|
|
1220
|
+
vec2 A0 = i == 0 ? vec2(1.05, 0.42) : (i == 1 ? vec2(0.98, 0.58) : vec2(0.9, 0.7));
|
|
1221
|
+
vec2 T = vec2(1.38, 0.2 + 0.3 * float(i));
|
|
1222
|
+
col = mix(col, ink, wCable(c, A0, T, 1.0));
|
|
1223
|
+
col = mix(col, rust, scAA(sdBox(c, A0 - 0.006, A0 + 0.006)));
|
|
1224
|
+
}
|
|
1225
|
+
// checkerboard tower of the mid level, tiny code columns
|
|
1226
|
+
vec2 tg = floor((c - vec2(0.45, 0.95)) / vec2(0.02, -0.02));
|
|
1227
|
+
float h = stLevel().g * 20.0 + 2.0;
|
|
1228
|
+
col = mix(col, ink, step(0.0, tg.x) * step(tg.x, 2.0) * step(0.0, tg.y) * step(tg.y + 0.5, h) * step(mod(tg.x + tg.y, 2.0), 0.5));
|
|
1229
|
+
float cell = scCell();
|
|
1230
|
+
float code = 0.0;
|
|
1231
|
+
for (int i = 0; i < 9; i++) { code = max(code, numTxt(q, vec2(1.40, 0.82 + 0.014 * float(i)) * scU, max(1.0, cell - 1.0), floor(hash12(vec2(float(i), clk.x)) * 9999.0), 4)); }
|
|
1232
|
+
col = mix(col, rust, code);
|
|
1233
|
+
col = mix(col, ink, scSheet(q, 1));
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
// Scene 6, deck: a hot pink field and a HUD deck of thin black lines. The plate sits in a chamfered octagon window; outlined
|
|
1237
|
+
// tab-box labels (DIN Condensed, Pretendard) down the left, a particle cloud box that scatters on the onset, a starburst glyph
|
|
1238
|
+
// whose rays are band levels and which steps round on every beat, a text ring that turns a notch per onset, a contour-map box whose
|
|
1239
|
+
// terrain shifts on the beat, and a 0..5 ruler strip. Palette: ground (pink), ink (black), accent (white), tintA (lilac).
|
|
1240
|
+
// Text set 6: r the tab labels, g captions, b the ring line.
|
|
1241
|
+
float dkRing(vec2 q, vec2 ctr, float Rm, float band, float rot) {
|
|
1242
|
+
vec2 d = q - ctr;
|
|
1243
|
+
float r = length(d);
|
|
1244
|
+
float a = atan(d.y, d.x) / 6.28318 + 0.5 + rot;
|
|
1245
|
+
float k = scS.y / RENDERSIZE.y;
|
|
1246
|
+
vec2 sp = vec2(fract(a) * 6.28318 * Rm / k, 0.9 * RENDERSIZE.y + (Rm + 0.5 * band - r) / k);
|
|
1247
|
+
return sheetC(sp, 2) * step(abs(r - Rm), 0.5 * band);
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
void sceneDeck(vec2 q, vec2 S, vec4 clk, inout vec3 col) {
|
|
1251
|
+
vec2 c = q / scU;
|
|
1252
|
+
float A = S.x / S.y;
|
|
1253
|
+
vec4 hit = stHit();
|
|
1254
|
+
vec3 ink = inkColor.rgb;
|
|
1255
|
+
vec3 white = accentColor.rgb;
|
|
1256
|
+
vec3 lil = tintA.rgb;
|
|
1257
|
+
col = groundColor.rgb;
|
|
1258
|
+
float cut = floor(clk.x);
|
|
1259
|
+
// octagon window with the plate
|
|
1260
|
+
vec2 lo = vec2(0.40, 0.08);
|
|
1261
|
+
vec2 hi = vec2(1.38, 0.74);
|
|
1262
|
+
float dO = sdChamfer(c, lo, hi, 0.2);
|
|
1263
|
+
vec3 f = scPlate(q, lo * scU, hi * scU);
|
|
1264
|
+
col = mix(col, clamp((f - 0.1) * 1.3, 0.0, 1.0), scAA(dO));
|
|
1265
|
+
col = mix(col, ink, scLine(dO, 2.0));
|
|
1266
|
+
col = mix(col, ink, scLine(sdChamfer(c, lo - 0.014, hi + 0.014, 0.23), 1.0));
|
|
1267
|
+
// particle cloud box (left), scatters on the onset
|
|
1268
|
+
vec2 pl = vec2(0.03, 0.46);
|
|
1269
|
+
vec2 ph = vec2(0.33, 0.9);
|
|
1270
|
+
float inBox = scBox(c, pl, ph);
|
|
1271
|
+
col = mix(col, lil, inBox);
|
|
1272
|
+
col = mix(col, ink, scLine(sdBox(c, pl, ph), 1.0));
|
|
1273
|
+
if (inBox > 0.5) {
|
|
1274
|
+
float dots = 0.0;
|
|
1275
|
+
for (int i = 0; i < 70; i++) {
|
|
1276
|
+
vec2 h = hash22(vec2(float(i), 3.7));
|
|
1277
|
+
float t = (h.x - 0.5) * 1.6;
|
|
1278
|
+
vec2 p = vec2(0.18, 0.68) + vec2(t * 0.1, -t * 0.12) + (hash22(vec2(float(i), 9.1)) - 0.5) * 0.07;
|
|
1279
|
+
p += (hash22(vec2(float(i), clk.z)) - 0.5) * 0.12 * step(0.45, hit.x);
|
|
1280
|
+
dots = max(dots, scAA(length(c - p) - 0.0035));
|
|
1281
|
+
}
|
|
1282
|
+
col = mix(col, ink, dots);
|
|
1283
|
+
}
|
|
1284
|
+
// starburst glyph, top right, one notch per beat
|
|
1285
|
+
vec2 sb = vec2(1.58, 0.2);
|
|
1286
|
+
col = mix(col, ink, scBurst(c - sb, 0.12, 0.012, cut * 0.2618, 36.0));
|
|
1287
|
+
col = mix(col, white, scAA(sdBox(c, sb - 0.008, sb + 0.008)));
|
|
1288
|
+
// text ring, bottom right, a notch per onset
|
|
1289
|
+
vec2 rc = vec2(1.58, 0.52);
|
|
1290
|
+
col = mix(col, ink, dkRing(q, rc * scU, 0.11 * scU, 0.03 * scU, clk.z * 0.04));
|
|
1291
|
+
col = mix(col, ink, scLine(length(c - rc) - 0.075, 1.0));
|
|
1292
|
+
// contour map box, bottom right, terrain shifts on the beat
|
|
1293
|
+
vec2 ml = vec2(0.98, 0.78);
|
|
1294
|
+
vec2 mh = vec2(1.72, 0.96);
|
|
1295
|
+
float inM = scBox(c, ml, mh);
|
|
1296
|
+
col = mix(col, lil, inM);
|
|
1297
|
+
float v = fbm(c * vec2(5.0, 7.0) + cut * 0.9, 4) * 9.0;
|
|
1298
|
+
float iso = clamp(1.0 - abs(fract(v) - 0.5) * 2.0 / max(fwidth(v) * 1.5, 1e-3), 0.0, 1.0);
|
|
1299
|
+
col = mix(col, ink, iso * inM * 0.9);
|
|
1300
|
+
col = mix(col, ink, scLine(sdBox(c, ml, mh), 1.0));
|
|
1301
|
+
float cell = scCell();
|
|
1302
|
+
col = mix(col, ink, numTxt(q, vec2(0.98, 0.745) * scU, cell, mod(cut * 37.0 + 1275.0, 10000.0), 4));
|
|
1303
|
+
// ruler strip, bottom left
|
|
1304
|
+
float rk = (c.x - 0.03) / 0.3 * 25.0;
|
|
1305
|
+
float major = step(abs(rk - floor(rk / 5.0 + 0.5) * 5.0), 0.2) * step(0.0, rk) * step(rk, 25.2);
|
|
1306
|
+
float minor = step(abs(rk - floor(rk + 0.5)), 0.2) * step(0.0, rk) * step(rk, 25.2);
|
|
1307
|
+
col = mix(col, ink, max(major * step(0.93, c.y) * step(c.y, 0.975), minor * step(0.93, c.y) * step(c.y, 0.953)));
|
|
1308
|
+
float amp = waveI(floor(clamp(rk, 0.0, 25.0) / 25.0 * 255.0) * 2.0) * scopeGain * 0.03;
|
|
1309
|
+
col = mix(col, ink, scLine(c.y - 0.915 - amp, 1.2) * step(0.0, rk) * step(rk, 25.0));
|
|
1310
|
+
// labels in tab boxes, captions
|
|
1311
|
+
col = mix(col, ink, scSheet(q, 0));
|
|
1312
|
+
col = mix(col, ink, scSheet(q, 1));
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1315
|
+
// Scene 7, bootlog: phosphor green on near-black. A typed boot log (the engine types it over the clip), a dot-matrix terminal icon,
|
|
1316
|
+
// a boot progress bar that fills a step on every beat, a big Hangul word, the plate as a single-tone phosphor CRT with raster
|
|
1317
|
+
// lines and a ghost, a roll bar, and data streaks along the bottom whose length is the spectrum. Every beat inverts one log row.
|
|
1318
|
+
// Palette: ground (near-black), ink (phosphor), accent (white-green), tintA (dim green). Text set 7: r the log, g Hangul.
|
|
1319
|
+
const int BL_ICON[8] = int[8](2047, 1025, 1281, 1153, 1281, 1081, 1025, 2047);
|
|
1320
|
+
|
|
1321
|
+
void sceneBootlog(vec2 q, vec2 S, vec4 clk, inout vec3 col) {
|
|
1322
|
+
vec2 c = q / scU;
|
|
1323
|
+
float A = S.x / S.y;
|
|
1324
|
+
vec4 hit = stHit();
|
|
1325
|
+
vec3 ph = inkColor.rgb;
|
|
1326
|
+
vec3 hot = accentColor.rgb;
|
|
1327
|
+
vec3 dim = tintA.rgb;
|
|
1328
|
+
float cut = floor(clk.x);
|
|
1329
|
+
col = groundColor.rgb;
|
|
1330
|
+
// CRT window: single-tone phosphor plate, raster lines, a ghost one pixel line to the right, roll bar
|
|
1331
|
+
vec2 lo = vec2(0.98, 0.14);
|
|
1332
|
+
vec2 hi = vec2(1.72, 0.80);
|
|
1333
|
+
float inW = scAA(sdBox(c, lo, hi) - 0.02 + 0.02);
|
|
1334
|
+
float l = luma(scPlate(q, lo * scU, hi * scU));
|
|
1335
|
+
float lg = luma(scPlate(q - vec2(3.0, 0.0), lo * scU, hi * scU));
|
|
1336
|
+
float ras = 0.72 + 0.28 * step(0.5, fract(q.y / 3.0));
|
|
1337
|
+
float roll = smoothstep(0.06, 0.0, abs(fract(c.y * 1.3 - cut * 0.11) - 0.5) - 0.44);
|
|
1338
|
+
float tone = clamp((max(l, lg * 0.6) - 0.05) * 1.7, 0.0, 1.0) * ras;
|
|
1339
|
+
col = mix(col, mix(dim * 0.4, ph, tone) + hot * 0.25 * roll * tone, scBox(c, lo, hi));
|
|
1340
|
+
col = mix(col, ph, scLine(sdBox(c, lo - 0.012, hi + 0.012), 1.0));
|
|
1341
|
+
for (int i = 0; i < 4; i++) {
|
|
1342
|
+
vec2 k = vec2(i < 2 ? lo.x - 0.012 : hi.x + 0.012, (i & 1) == 0 ? lo.y - 0.012 : hi.y + 0.012);
|
|
1343
|
+
col = mix(col, ph, scPlus(c, k, 0.02));
|
|
1344
|
+
}
|
|
1345
|
+
// dot-matrix terminal icon and the boot progress bar
|
|
1346
|
+
vec2 ig = floor((c - vec2(0.05, 0.84)) / 0.0125);
|
|
1347
|
+
float icon = 0.0;
|
|
1348
|
+
if (ig.x >= 0.0 && ig.x < 11.0 && ig.y >= 0.0 && ig.y < 8.0) { icon = float((BL_ICON[int(ig.y)] >> (10 - int(ig.x))) & 1); }
|
|
1349
|
+
float blink = step(0.5, fract(TIME * 2.0));
|
|
1350
|
+
col = mix(col, ph, icon);
|
|
1351
|
+
col = mix(col, ph, scBox(c, vec2(0.0 + 0.05 + 0.032, 0.845 + 0.0125 * 5.0), vec2(0.05 + 0.032 + 0.0125 * 3.0, 0.845 + 0.0125 * 6.0)) * blink * (1.0 - icon));
|
|
1352
|
+
vec2 pg = (c - vec2(0.24, 0.865)) / vec2(0.016, 0.05);
|
|
1353
|
+
float seg = step(0.0, pg.x) * step(pg.x, 40.0) * step(0.0, pg.y) * step(pg.y, 1.0) * step(mod(pg.x, 1.0), 0.7);
|
|
1354
|
+
float filled = step(pg.x, min(cut * 3.0 + 2.0, 40.0));
|
|
1355
|
+
col = mix(col, mix(dim, ph, filled), seg);
|
|
1356
|
+
col = mix(col, ph, scLine(sdBox(c, vec2(0.235, 0.855), vec2(0.24 + 40.0 * 0.016 + 0.005, 0.925)), 1.0));
|
|
1357
|
+
float cell = scCell();
|
|
1358
|
+
col = mix(col, ph, numTxt(q, vec2(0.24, 0.945) * scU, cell, min(cut * 3.0 + 2.0, 40.0) * 2.5, 3));
|
|
1359
|
+
// data streaks along the bottom: length is the spectrum, jump on the onset
|
|
1360
|
+
for (int i = 0; i < 6; i++) {
|
|
1361
|
+
float y = 0.955 + 0.007 * float(i);
|
|
1362
|
+
float len = 0.1 + 0.9 * bandAt(0.08 + 0.15 * float(i));
|
|
1363
|
+
float x0 = (0.3 + 1.2 * hash12(vec2(float(i), clk.z))) ;
|
|
1364
|
+
float s = scLine(c.y - y, 1.0) * step(x0 - len * 0.5, c.x) * step(c.x, x0 + len * 0.5);
|
|
1365
|
+
col = mix(col, ph, s * (0.35 + 0.65 * smoothstep(x0 - len * 0.5, x0 + len * 0.5, c.x)));
|
|
1366
|
+
}
|
|
1367
|
+
// typed log, Hangul word; the row picked by the beat is inverted
|
|
1368
|
+
float logRow = floor((c.y - 0.31) / 0.0364);
|
|
1369
|
+
float pick = step(0.0, logRow) * step(abs(logRow - mod(cut * 3.0, 12.0)), 0.5) * step(c.x, 0.93);
|
|
1370
|
+
col = mix(col, ph, pick * 0.9);
|
|
1371
|
+
float lg2 = scSheet(q, 0);
|
|
1372
|
+
col = mix(col, mix(ph, groundColor.rgb, pick), lg2);
|
|
1373
|
+
col = mix(col, hot, scSheet(q, 1));
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1376
|
+
// Scene 8, tunnel: a pixel checker tunnel in electric blue on black that jumps one ring deeper and turns half a step on
|
|
1377
|
+
// every beat; the plate sits in a curved letterbox window at its vanishing point; a white-hot horizontal eye bar flares on the
|
|
1378
|
+
// onset; a black block with a giant Monument Extended word and live depth numbers. Palette: ground (black), ink (white-hot),
|
|
1379
|
+
// accent (electric blue), tintA (deep blue). Text set 8: r the word, g captions.
|
|
1380
|
+
void sceneTunnel(vec2 q, vec2 S, vec4 clk, inout vec3 col) {
|
|
1381
|
+
vec2 c = q / scU;
|
|
1382
|
+
float A = S.x / S.y;
|
|
1383
|
+
vec4 hit = stHit();
|
|
1384
|
+
vec3 hotc = inkColor.rgb;
|
|
1385
|
+
vec3 blue = accentColor.rgb;
|
|
1386
|
+
vec3 deep = tintA.rgb;
|
|
1387
|
+
float cut = floor(clk.x);
|
|
1388
|
+
vec2 ctr = vec2(0.5 * A, 0.5);
|
|
1389
|
+
float px = scPx();
|
|
1390
|
+
vec2 d = ((floor(q / px) + 0.5) * px) / scU - ctr;
|
|
1391
|
+
float r = length(d);
|
|
1392
|
+
float a = atan(d.y, d.x) / 6.28318;
|
|
1393
|
+
float z = 0.16 / max(r, 0.02);
|
|
1394
|
+
float ring = floor(z * 2.2 + cut);
|
|
1395
|
+
float seg = floor(a * 20.0 + cut * 0.5);
|
|
1396
|
+
float chk = mod(ring + seg, 2.0);
|
|
1397
|
+
float shade = smoothstep(0.05, 0.4, r);
|
|
1398
|
+
col = groundColor.rgb;
|
|
1399
|
+
col = mix(col, mix(deep, blue, 0.5 + 0.5 * step(1.5, mod(ring, 4.0))), chk * shade);
|
|
1400
|
+
col = mix(col, hotc, chk * step(0.5, mod(ring * 7.0 + seg, 29.0) - 27.5) * shade * step(1.2, z));
|
|
1401
|
+
// plate in the curved letterbox: the half height grows toward the sides
|
|
1402
|
+
float halfH = 0.17 + 0.2 * pow(abs(d.x) / (0.5 * A), 2.0);
|
|
1403
|
+
float inWin = scAA(abs(d.y) - halfH) * step(abs(d.x), 0.5 * A * 0.8);
|
|
1404
|
+
vec3 f = scPlate(q, vec2(0.1 * A, 0.2) * scU, vec2(0.9 * A, 0.8) * scU);
|
|
1405
|
+
vec3 tint = mix(vec3(luma(f)), f, 0.6) * vec3(0.7, 0.85, 1.25);
|
|
1406
|
+
col = mix(col, clamp(tint * 1.1, 0.0, 1.0), inWin);
|
|
1407
|
+
float edge = max(scLine(abs(d.y) - halfH, 1.5), 0.0) * step(abs(d.x), 0.5 * A * 0.8);
|
|
1408
|
+
col = mix(col, hotc, edge);
|
|
1409
|
+
// eye bar
|
|
1410
|
+
float bar = 0.003 + 0.028 * hit.x;
|
|
1411
|
+
float glow = smoothstep(0.1, 0.0, abs(d.y)) * 0.18 * (0.4 + hit.x);
|
|
1412
|
+
col = mix(col, blue, glow);
|
|
1413
|
+
col = mix(col, hotc, scAA(abs(d.y) - bar) * (0.55 + 0.45 * step(0.2, hit.x)));
|
|
1414
|
+
// block with the word, crosshairs, live depth
|
|
1415
|
+
col = mix(col, vec3(0.0), scAA(sdBox(c, vec2(-0.1, 0.78), vec2(0.98, 1.1))));
|
|
1416
|
+
col = mix(col, vec3(0.0), scAA(sdBox(c, vec2(1.1, 0.84), vec2(A + 0.1, 1.1))));
|
|
1417
|
+
col = mix(col, hotc, scSheet(q, 0));
|
|
1418
|
+
col = mix(col, hotc, scPlus(c, vec2(0.05, 0.05), 0.02));
|
|
1419
|
+
col = mix(col, hotc, scPlus(c, vec2(A - 0.05, 0.05), 0.02));
|
|
1420
|
+
float cell = scCell();
|
|
1421
|
+
col = mix(col, hotc, numTxt(q, vec2(A - 0.2, 0.9) * scU, cell * 2.0, mod(cut * 7.0, 1000.0), 3));
|
|
1422
|
+
col = mix(col, blue, scSheet(q, 1));
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1425
|
+
// Scene 9, runner: the plate as a grey monotone under scanline bands (a few bands slide sideways on every onset), glowing
|
|
1426
|
+
// white-hot data streaks whose length is the spectrum and which jump on the onset, and a vermilion bar carrying a heavy Arial Black
|
|
1427
|
+
// word that swaps to the next of three words and slams to a new left edge on every beat. Black pixel crosses, MesloLGS NF captions.
|
|
1428
|
+
// Palette: ground (black), ink (white-hot), accent (vermilion), tintA (black), tintB (light grey). Text set 9: r, g, b are
|
|
1429
|
+
// the three words (same place), the captions are on r above the bar.
|
|
1430
|
+
void sceneRunner(vec2 q, vec2 S, vec4 clk, inout vec3 col) {
|
|
1431
|
+
vec2 c = q / scU;
|
|
1432
|
+
float A = S.x / S.y;
|
|
1433
|
+
vec4 hit = stHit();
|
|
1434
|
+
vec3 hotc = inkColor.rgb;
|
|
1435
|
+
vec3 verm = accentColor.rgb;
|
|
1436
|
+
vec3 blk = tintA.rgb;
|
|
1437
|
+
vec3 sky = tintB.rgb;
|
|
1438
|
+
float cut = floor(clk.x);
|
|
1439
|
+
float band = floor(q.y / (4.0 * max(U * 3.0, 1.0)));
|
|
1440
|
+
float slide = step(0.9, hash12(vec2(band, clk.z))) * (hash12(vec2(band, clk.z + 7.0)) - 0.5) * 0.12 * scU;
|
|
1441
|
+
float l = clamp((luma(scPlate(q + vec2(slide, 0.0), vec2(0.0), S)) - 0.06) * 1.6, 0.0, 1.0);
|
|
1442
|
+
float stripe = 0.78 + 0.22 * step(0.5, fract(band * 0.5));
|
|
1443
|
+
col = mix(groundColor.rgb, sky, smoothstep(0.0, 1.0, l)) * stripe;
|
|
1444
|
+
// streaks
|
|
1445
|
+
for (int i = 0; i < 16; i++) {
|
|
1446
|
+
float fi = float(i);
|
|
1447
|
+
float y = 0.04 + 0.92 * hash12(vec2(fi, 1.3));
|
|
1448
|
+
float len = 0.12 + 0.55 * bandAt(hash12(vec2(fi, 2.9)));
|
|
1449
|
+
float x0 = A * hash12(vec2(fi, clk.z));
|
|
1450
|
+
float u = clamp((c.x - (x0 - len)) / len, 0.0, 1.0);
|
|
1451
|
+
float s = scLine(c.y - y, 1.3) * step(x0 - len, c.x) * step(c.x, x0);
|
|
1452
|
+
col = mix(col, hotc, s * u * u * 0.9);
|
|
1453
|
+
}
|
|
1454
|
+
// the bar: its left edge slams to one of three places on the beat, the word swaps
|
|
1455
|
+
float pos = mod(cut, 3.0);
|
|
1456
|
+
float x0 = pos < 0.5 ? 0.0 : (pos < 1.5 ? 0.22 : 0.08);
|
|
1457
|
+
col = mix(col, verm, scAA(sdBox(c, vec2(x0, 0.6), vec2(A + 0.1, 0.79))));
|
|
1458
|
+
float w = pos < 0.5 ? scSheet(q, 0) : (pos < 1.5 ? scSheet(q, 1) : scSheet(q, 2));
|
|
1459
|
+
col = mix(col, blk, w * step(x0, c.x) * step(0.58, c.y) * step(c.y, 0.8));
|
|
1460
|
+
col = mix(col, blk, max(scPlus(c, vec2(x0 + 0.04, 0.6), 0.015), scPlus(c, vec2(A - 0.05, 0.79), 0.015)));
|
|
1461
|
+
float cell = scCell();
|
|
1462
|
+
col = mix(col, hotc, numTxt(q, vec2(0.06, 0.1) * scU, cell * 2.0, mod(cut * 11.0, 1000.0), 3));
|
|
1463
|
+
col = mix(col, hotc, scSheet(q, 0) * step(c.y, 0.5) * step(0.2, c.y));
|
|
1464
|
+
vec2 ck = floor((c - vec2(A - 0.34, 0.86)) / 0.025);
|
|
1465
|
+
col = mix(col, blk, step(0.0, ck.x) * step(ck.x, 9.0) * step(0.0, ck.y) * step(ck.y, 2.0) * step(1.0, mod(ck.x + ck.y, 2.0)));
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1468
|
+
// Scene 0, ascii: the plate drawn as ASCII, one character per cell from the pixel font by tone (mint, the lightest cells lilac);
|
|
1469
|
+
// after every onset a hot column sweeps across it and lifts the characters it passes; a contour-map box with its terrain shifting
|
|
1470
|
+
// on the beat, a particle cloud box that scatters on the onset, live readouts and a big Hangul word. Palette: ground (dark teal),
|
|
1471
|
+
// ink (mint), accent (white mint), tintA (lilac). Text set 10 (Pretendard).
|
|
1472
|
+
float asciiChar(vec2 q, vec2 lo, vec2 hi, vec4 clk, vec4 hit, out float lit) {
|
|
1473
|
+
float cell = scCell();
|
|
1474
|
+
vec2 adv = vec2(4.0, 6.0) * cell;
|
|
1475
|
+
vec2 id = floor((q - lo) / adv);
|
|
1476
|
+
vec2 org = lo + id * adv;
|
|
1477
|
+
vec2 mid = org + vec2(2.0, 3.0) * cell;
|
|
1478
|
+
float l = pow(scTone(mid, lo, hi, 1.5, 0.04), 0.7);
|
|
1479
|
+
float age = float(FRAMEINDEX) - clk.w;
|
|
1480
|
+
float sweepX = lo.x + (hi.x - lo.x) * (age / 9.0);
|
|
1481
|
+
float sw = step(abs(mid.x - sweepX), 18.0 * U + 8.0) * step(0.0, age) * step(age, 9.5) * step(0.5, clk.z);
|
|
1482
|
+
l = clamp(l + 0.35 * sw, 0.0, 1.0);
|
|
1483
|
+
int k = int(floor(l * 7.99));
|
|
1484
|
+
int ch = k == 0 ? 0 : (k == 1 ? 46 : (k == 2 ? 58 : (k == 3 ? 45 : (k == 4 ? 43 : (k == 5 ? 47 : (k == 6 ? 37 : 56))))));
|
|
1485
|
+
lit = step(0.8, l) + sw;
|
|
1486
|
+
return glyphAt(q - org, ch, cell) * step(lo.x, q.x) * step(q.x, hi.x) * step(lo.y, q.y) * step(q.y, hi.y);
|
|
1487
|
+
}
|
|
1488
|
+
|
|
1489
|
+
void sceneAscii(vec2 q, vec2 S, vec4 clk, inout vec3 col) {
|
|
1490
|
+
vec2 c = q / scU;
|
|
1491
|
+
float A = S.x / S.y;
|
|
1492
|
+
vec4 hit = stHit();
|
|
1493
|
+
vec3 mint = inkColor.rgb;
|
|
1494
|
+
vec3 whit = accentColor.rgb;
|
|
1495
|
+
vec3 lil = tintA.rgb;
|
|
1496
|
+
float cut = floor(clk.x);
|
|
1497
|
+
col = groundColor.rgb;
|
|
1498
|
+
float lit;
|
|
1499
|
+
float g = asciiChar(q, vec2(0.05, 0.07) * scU, vec2(1.12, 0.77) * scU, clk, hit, lit);
|
|
1500
|
+
col = mix(col, mix(mint, lil, step(0.8, lit)), g);
|
|
1501
|
+
col = mix(col, whit, g * step(1.5, lit));
|
|
1502
|
+
col = mix(col, mint, scLine(sdBox(c, vec2(0.04, 0.06), vec2(1.13, 0.78)), 1.0) * 0.6);
|
|
1503
|
+
// contour map box
|
|
1504
|
+
vec2 ml = vec2(1.22, 0.07);
|
|
1505
|
+
vec2 mh = vec2(1.72, 0.37);
|
|
1506
|
+
float v = fbm(c * vec2(6.0, 8.0) + cut * 0.7, 4) * 10.0;
|
|
1507
|
+
float iso = clamp(1.0 - abs(fract(v) - 0.5) * 2.0 / max(fwidth(v) * 1.5, 1e-3), 0.0, 1.0);
|
|
1508
|
+
float major = clamp(1.0 - abs(fract(v * 0.2) - 0.5) * 2.0 / max(fwidth(v * 0.2) * 2.5, 1e-3), 0.0, 1.0);
|
|
1509
|
+
float inM = scBox(c, ml, mh);
|
|
1510
|
+
col = mix(col, mint, iso * inM * 0.7);
|
|
1511
|
+
col = mix(col, lil, major * inM);
|
|
1512
|
+
col = mix(col, mint, scLine(sdBox(c, ml, mh), 1.0));
|
|
1513
|
+
// particle cloud box
|
|
1514
|
+
vec2 pl = vec2(1.22, 0.42);
|
|
1515
|
+
vec2 ph = vec2(1.72, 0.72);
|
|
1516
|
+
col = mix(col, mint, scLine(sdBox(c, pl, ph), 1.0));
|
|
1517
|
+
if (scBox(c, pl, ph) > 0.5) {
|
|
1518
|
+
float dots = 0.0;
|
|
1519
|
+
for (int i = 0; i < 80; i++) {
|
|
1520
|
+
vec2 h = hash22(vec2(float(i), 5.3));
|
|
1521
|
+
vec2 p = vec2(1.47, 0.57) + (h - 0.5) * vec2(0.4, 0.22) * (0.4 + 0.6 * h.y);
|
|
1522
|
+
p += (hash22(vec2(float(i), clk.z + 3.0)) - 0.5) * 0.14 * step(0.45, hit.x);
|
|
1523
|
+
dots = max(dots, scAA(length(c - p) - 0.0035));
|
|
1524
|
+
}
|
|
1525
|
+
col = mix(col, lil, dots);
|
|
1526
|
+
}
|
|
1527
|
+
// readouts and the Hangul word
|
|
1528
|
+
float cell = scCell();
|
|
1529
|
+
col = mix(col, mint, max(txt4(q, vec2(1.22, 0.76) * scU, cell, 88, 0, 0, 0), numTxt(q, vec2(1.28, 0.76) * scU, cell, mod(cut * 37.0 + 714.0, 10000.0), 4)));
|
|
1530
|
+
col = mix(col, mint, max(txt4(q, vec2(1.22, 0.8) * scU, cell, 89, 0, 0, 0), numTxt(q, vec2(1.28, 0.8) * scU, cell, floor(stLevel().a * 999.0), 4)));
|
|
1531
|
+
col = mix(col, lil, scSheet(q, 0));
|
|
1532
|
+
col = mix(col, mint, scSheet(q, 1));
|
|
1533
|
+
}
|
|
1534
|
+
|
|
1535
|
+
// Scene 10 (variant 0, rot 1), cube-wall: a salmon field and a 4 x 3 wall of cubes. On every beat every cube turns to its next face in
|
|
1536
|
+
// three frames (even columns slide round sideways, odd columns upward); a face is a cobalt rounded tile with a cream letter, a cream
|
|
1537
|
+
// tile with a cobalt letter, a cobalt Bayer dither of the plate, or a dot grid whose dot radius is the bass. Each onset swaps the letter
|
|
1538
|
+
// of one cube. Palette: ground (salmon), ink (cream), accent (cobalt), tintA (dark salmon). Text set 11: r the four face letters
|
|
1539
|
+
// (Big Shoulders Display Black, C U B E at 0, 0.2, 0.4, 0.6 of the sheet width), g the caption (MesloLGS NF).
|
|
1540
|
+
float cwRound(vec2 p, float s, float r) { return length(max(abs(p) - (s - r), 0.0)) - r; }
|
|
1541
|
+
|
|
1542
|
+
vec4 cwFace(vec2 q, vec2 ctr, vec2 p, float s, int kind, int letter, float bass) {
|
|
1543
|
+
vec3 cobalt = accentColor.rgb;
|
|
1544
|
+
vec3 cream = inkColor.rgb;
|
|
1545
|
+
float cov = scAA(cwRound(p, s, 0.05));
|
|
1546
|
+
vec3 f = kind == 0 ? cobalt : (kind == 3 ? tintA.rgb : cream);
|
|
1547
|
+
float cx = (float(letter) * 0.2) * RENDERSIZE.x + 0.1167 * RENDERSIZE.y;
|
|
1548
|
+
vec2 sp = vec2(cx, 0.2361 * RENDERSIZE.y) + p / s * 0.1833 * RENDERSIZE.y;
|
|
1549
|
+
float m = crisp(sheetC(sp, 0), 1.0);
|
|
1550
|
+
if (kind == 0) { f = mix(f, cream, m); }
|
|
1551
|
+
if (kind == 1) { f = mix(f, cobalt, m); }
|
|
1552
|
+
if (kind == 2) {
|
|
1553
|
+
float px = scPx();
|
|
1554
|
+
vec2 pix = floor(q / px);
|
|
1555
|
+
float l = scTone((pix + 0.5) * px, (ctr - s) * scU, (ctr + s) * scU, 1.5, 0.08);
|
|
1556
|
+
f = mix(cream, cobalt, step(scBayer(pix), 1.0 - l));
|
|
1557
|
+
}
|
|
1558
|
+
if (kind == 3) {
|
|
1559
|
+
vec2 g = (p / s * 0.5 + 0.5) * 6.0;
|
|
1560
|
+
float dt = scAA((length(fract(g) - 0.5) - (0.12 + 0.34 * bass)) * s / 3.0);
|
|
1561
|
+
f = mix(f, cream, dt);
|
|
1562
|
+
}
|
|
1563
|
+
return vec4(f, cov);
|
|
1564
|
+
}
|
|
1565
|
+
|
|
1566
|
+
void sceneCubeWall(vec2 q, vec2 S, vec4 clk, inout vec3 col) {
|
|
1567
|
+
vec2 c = q / scU;
|
|
1568
|
+
float A = S.x / S.y;
|
|
1569
|
+
vec3 cobalt = accentColor.rgb;
|
|
1570
|
+
vec3 cream = inkColor.rgb;
|
|
1571
|
+
float beat = floor(clk.x);
|
|
1572
|
+
float cut = floor(beat * 0.5);
|
|
1573
|
+
float age = float(FRAMEINDEX) - clk.y;
|
|
1574
|
+
float u = (cut < 0.5 || mod(beat, 2.0) > 0.5) ? 1.0 : clamp((age + 1.0) / 3.0, 0.0, 1.0);
|
|
1575
|
+
col = groundColor.rgb;
|
|
1576
|
+
vec2 o = vec2(0.5 * A - 0.6, 0.05);
|
|
1577
|
+
vec2 g = (c - o) / 0.3;
|
|
1578
|
+
vec2 id = floor(g);
|
|
1579
|
+
col = mix(col, tintA.rgb, scAA(sdBox(c, o - 0.01, o + vec2(1.2, 0.9) + 0.01)) * 0.5);
|
|
1580
|
+
if (id.x >= 0.0 && id.x < 4.0 && id.y >= 0.0 && id.y < 3.0) {
|
|
1581
|
+
vec2 ctr = o + (id + 0.5) * 0.3;
|
|
1582
|
+
vec2 p = c - ctr;
|
|
1583
|
+
float s = 0.135;
|
|
1584
|
+
bool horiz = mod(id.x, 2.0) < 0.5;
|
|
1585
|
+
float pitch = 2.0 * s + 0.03;
|
|
1586
|
+
float off = pitch * u;
|
|
1587
|
+
vec2 pPrev = horiz ? p + vec2(off, 0.0) : p + vec2(0.0, off);
|
|
1588
|
+
vec2 pNew = horiz ? p - vec2(pitch - off, 0.0) : p - vec2(0.0, pitch - off);
|
|
1589
|
+
float idx = id.x + 4.0 * id.y;
|
|
1590
|
+
float turns = floor((clk.z + 11.0 - idx) / 12.0);
|
|
1591
|
+
int letter = int(mod(idx + turns, 4.0));
|
|
1592
|
+
int kNew = int(mod(cut + id.x + 2.0 * id.y, 4.0));
|
|
1593
|
+
int kPrev = int(mod(cut + 3.0 + id.x + 2.0 * id.y, 4.0));
|
|
1594
|
+
bool inPrev = abs(horiz ? pPrev.x : pPrev.y) < s && abs(horiz ? pPrev.y : pPrev.x) < s;
|
|
1595
|
+
bool inNew = abs(horiz ? pNew.x : pNew.y) < s && abs(horiz ? pNew.y : pNew.x) < s;
|
|
1596
|
+
float bass = stLevel().r;
|
|
1597
|
+
if (u >= 0.99) {
|
|
1598
|
+
vec4 f2 = cwFace(q, ctr, p, s, kNew, letter, bass);
|
|
1599
|
+
col = mix(col, f2.rgb, f2.a);
|
|
1600
|
+
} else if (inNew) {
|
|
1601
|
+
vec4 fn = cwFace(q, ctr, pNew, s, kNew, letter, bass);
|
|
1602
|
+
col = mix(col, fn.rgb * (0.65 + 0.35 * u), fn.a);
|
|
1603
|
+
} else if (inPrev) {
|
|
1604
|
+
vec4 fp = cwFace(q, ctr, pPrev, s, kPrev, letter, bass);
|
|
1605
|
+
col = mix(col, fp.rgb * (1.0 - 0.35 * u), fp.a);
|
|
1606
|
+
}
|
|
1607
|
+
}
|
|
1608
|
+
// margins: cobalt bar with the caption, rules, crosses
|
|
1609
|
+
col = mix(col, cobalt, scAA(sdBox(c, vec2(0.0, 0.88), vec2(o.x - 0.03, 0.95))));
|
|
1610
|
+
col = mix(col, cream, scSheet(q, 1) * scBox(c, vec2(0.0, 0.88), vec2(o.x - 0.03, 0.95)));
|
|
1611
|
+
col = mix(col, cream, scLine(c.x - (o.x + 1.23), 1.0) * step(0.05, c.y) * step(c.y, 0.95) * 0.9);
|
|
1612
|
+
col = mix(col, cobalt, max(scPlus(c, vec2(0.08, 0.08), 0.02), scPlus(c, vec2(A - 0.08, 0.92), 0.02)));
|
|
1613
|
+
col = mix(col, cobalt, numTxt(q, vec2(A - 0.25, 0.08) * scU, scCell() * 2.0, mod(cut, 100.0), 2));
|
|
1614
|
+
}
|
|
1615
|
+
|
|
1616
|
+
// Scene 11 (variant 1, rot 1), vortex-count: a blue-grey field whose log-polar rings of text spiral out of the centre (white and navy
|
|
1617
|
+
// rings alternate, the spiral steps a little on every beat), a round window at the vanishing point holding the plate as white
|
|
1618
|
+
// halftone dots (dot size follows the bass), and a ring of 24 countdown ticks that loses one tick on every beat. Palette: ground
|
|
1619
|
+
// (blue-grey), ink (white), accent (navy), tintA (pale blue-grey). Text set 12: r the spiral line (Bebas Neue), g the caption (Futura).
|
|
1620
|
+
void sceneVortex(vec2 q, vec2 S, vec4 clk, inout vec3 col) {
|
|
1621
|
+
vec2 c = q / scU;
|
|
1622
|
+
float A = S.x / S.y;
|
|
1623
|
+
vec4 hit = stHit();
|
|
1624
|
+
vec3 white = inkColor.rgb;
|
|
1625
|
+
vec3 navy = accentColor.rgb;
|
|
1626
|
+
float cut = floor(clk.x);
|
|
1627
|
+
vec2 ctr = vec2(0.5 * A, 0.5);
|
|
1628
|
+
vec2 d = c - ctr;
|
|
1629
|
+
float r = length(d);
|
|
1630
|
+
float th = atan(d.y, d.x);
|
|
1631
|
+
col = groundColor.rgb;
|
|
1632
|
+
// spiral text
|
|
1633
|
+
float w = log(max(r, 0.001) / 0.2) * 3.0;
|
|
1634
|
+
float n = floor(w);
|
|
1635
|
+
float tt = fract(th / 6.28318 + n * 0.173 + cut * 0.012);
|
|
1636
|
+
float k = RENDERSIZE.y;
|
|
1637
|
+
vec2 sp = vec2(tt * 0.97 * RENDERSIZE.x, (0.004 + (1.0 - fract(w)) * 0.076) * k);
|
|
1638
|
+
float m = crisp(sheetC(sp, 0), 1.0) * step(0.0, w) * step(r, 1.4);
|
|
1639
|
+
col = mix(col, mod(n, 2.0) < 0.5 ? white : navy, m);
|
|
1640
|
+
col = mix(col, white, 0.1 * step(0.0, w) * step(fract(w), 0.03));
|
|
1641
|
+
// round window with the plate as halftone, and the countdown ring
|
|
1642
|
+
float R = 0.19;
|
|
1643
|
+
float lv = stLevel().r;
|
|
1644
|
+
vec2 lo = (ctr - R) * scU;
|
|
1645
|
+
vec2 hi = (ctr + R) * scU;
|
|
1646
|
+
float dots = scDots(q, lo, hi, max(3.0, 11.0 * U), 1.0 + 1.6 * lv, 0.05, 0.0);
|
|
1647
|
+
col = mix(col, navy, scAA(r - R));
|
|
1648
|
+
col = mix(col, white, dots * scAA(r - R + 0.004));
|
|
1649
|
+
col = mix(col, white, scLine(r - R, 1.5));
|
|
1650
|
+
float left = 24.0 - mod(cut, 25.0);
|
|
1651
|
+
float a24 = (th / 6.28318 + 0.5) * 24.0;
|
|
1652
|
+
float tick = step(0.2, fract(a24)) * step(fract(a24), 0.8) * step(R + 0.012, r) * step(r, R + 0.045);
|
|
1653
|
+
float lit = step(floor(a24) + 0.5, left);
|
|
1654
|
+
col = mix(col, mix(tintA.rgb, white, lit), tick);
|
|
1655
|
+
// numeral, caption, crosses
|
|
1656
|
+
float cell = scCell();
|
|
1657
|
+
col = mix(col, white, numTxt(q, vec2(ctr.x + 0.08, ctr.y + 0.11) * scU, cell * 2.0, left, 2));
|
|
1658
|
+
col = mix(col, navy, scAA(sdBox(c, vec2(0.0, 0.84), vec2(0.4, 1.0))));
|
|
1659
|
+
col = mix(col, white, scSheet(q, 1));
|
|
1660
|
+
col = mix(col, white, max(scPlus(c, vec2(0.06, 0.06), 0.02), scPlus(c, vec2(A - 0.06, 0.06), 0.02)));
|
|
1661
|
+
}
|
|
1662
|
+
|
|
1663
|
+
// Scene 12 (variant 2, rot 1), sticker-slap: a black field and a pile of cream stickers. Every beat a new sticker slaps on with an
|
|
1664
|
+
// overshoot (scale 1.35, 1.12, 0.97, 1); the pile keeps the last eight. Every onset flips one sticker over to a 1-bit dither of the plate.
|
|
1665
|
+
// Stickers are filled Impact words, outlined Impact words, round Georgia tags, dither plates and small mustard pills (mustard stays under
|
|
1666
|
+
// about 15 percent); two rows of Impact text run along the top, filled and outlined in turn. Palette: ground (black), ink (cream),
|
|
1667
|
+
// accent (mustard), tintA (lilac). Text set 13: r the sticker words (centred anchors), g the two rows.
|
|
1668
|
+
vec2 stRot(vec2 p, float a) { float cs = cos(a); float sn = sin(a); return vec2(cs * p.x + sn * p.y, -sn * p.x + cs * p.y); }
|
|
1669
|
+
|
|
1670
|
+
vec4 stSticker(vec2 q, vec2 c, float j, float cut, float age, float A, float flipJ) {
|
|
1671
|
+
vec2 h1 = hash22(vec2(j, 1.7));
|
|
1672
|
+
vec2 h2 = hash22(vec2(j, 8.3));
|
|
1673
|
+
vec2 pos = vec2(0.22 + (A - 0.44) * h1.x, 0.22 + 0.56 * h1.y);
|
|
1674
|
+
float rot = (h2.x - 0.5) * 0.6;
|
|
1675
|
+
float sz = 0.17 + 0.1 * h2.y;
|
|
1676
|
+
int type = int(floor(hash12(vec2(j, 4.4)) * 5.0));
|
|
1677
|
+
if (j == flipJ) { type = 3; }
|
|
1678
|
+
float sc = 1.0;
|
|
1679
|
+
if (j == cut) { sc = age < 0.5 ? 1.35 : (age < 1.5 ? 1.12 : (age < 2.5 ? 0.97 : 1.0)); }
|
|
1680
|
+
vec2 p = stRot(c - pos, rot) / sc;
|
|
1681
|
+
vec3 cream = inkColor.rgb;
|
|
1682
|
+
vec3 blk = groundColor.rgb;
|
|
1683
|
+
vec2 hs = vec2(sz, sz * 0.62);
|
|
1684
|
+
float cov = 0.0;
|
|
1685
|
+
vec3 f = cream;
|
|
1686
|
+
float k = RENDERSIZE.y;
|
|
1687
|
+
if (type == 2) {
|
|
1688
|
+
cov = scAA(length(p) - sz * 0.8);
|
|
1689
|
+
f = tintA.rgb;
|
|
1690
|
+
float m = crisp(sheetC(vec2(0.25 * RENDERSIZE.x, 0.774 * k) + p * (0.34 * k / (sz * 0.8)), 0), 1.0);
|
|
1691
|
+
f = mix(f, blk, m);
|
|
1692
|
+
f = mix(f, blk, scLine(length(p) - sz * 0.68, 1.5));
|
|
1693
|
+
} else if (type == 4) {
|
|
1694
|
+
vec2 hm = vec2(sz * 0.55, sz * 0.3);
|
|
1695
|
+
cov = scAA(sdBox(p, -hm, hm) - 0.03);
|
|
1696
|
+
f = accentColor.rgb;
|
|
1697
|
+
f = mix(f, blk, step(0.5, fract(p.x * 14.0)) * 0.9 * step(abs(p.y), hm.y * 0.5));
|
|
1698
|
+
} else {
|
|
1699
|
+
cov = scAA(sdBox(p, -hs, hs) - 0.03);
|
|
1700
|
+
if (type == 0 || type == 1) {
|
|
1701
|
+
vec2 anchor = type == 0 ? vec2(0.25 * RENDERSIZE.x, 0.252 * k) : vec2(0.75 * RENDERSIZE.x, 0.252 * k);
|
|
1702
|
+
float m = crisp(sheetC(anchor + p * (0.34 * k / sz), 0), 1.0);
|
|
1703
|
+
f = mix(f, blk, m);
|
|
1704
|
+
}
|
|
1705
|
+
if (type == 3) {
|
|
1706
|
+
float px = scPx();
|
|
1707
|
+
vec2 pix = floor(q / px);
|
|
1708
|
+
float l = scTone((pix + 0.5) * px, (pos - hs) * scU, (pos + hs) * scU, 1.6, 0.05);
|
|
1709
|
+
f = mix(blk, cream, step(scBayer(pix), l));
|
|
1710
|
+
}
|
|
1711
|
+
}
|
|
1712
|
+
return vec4(f, cov);
|
|
1713
|
+
}
|
|
1714
|
+
|
|
1715
|
+
void sceneSticker(vec2 q, vec2 S, vec4 clk, inout vec3 col) {
|
|
1716
|
+
vec2 c = q / scU;
|
|
1717
|
+
float A = S.x / S.y;
|
|
1718
|
+
float beat = floor(clk.x);
|
|
1719
|
+
float cut = floor(beat * 0.5);
|
|
1720
|
+
float age = mod(beat, 2.0) < 0.5 ? float(FRAMEINDEX) - clk.y : 9.0;
|
|
1721
|
+
vec3 cream = inkColor.rgb;
|
|
1722
|
+
col = groundColor.rgb;
|
|
1723
|
+
// two rows of Impact text, filled then outlined
|
|
1724
|
+
float rows = scSheet(q, 2);
|
|
1725
|
+
col = mix(col, cream, rows * step(c.y, 0.17));
|
|
1726
|
+
float flipJ = cut - mod(floor(clk.z / 3.0), 4.0);
|
|
1727
|
+
for (int i = 7; i >= 0; i--) {
|
|
1728
|
+
float j = cut - float(i);
|
|
1729
|
+
vec4 s = stSticker(q, c, j, cut, age, A, flipJ);
|
|
1730
|
+
col = mix(col, s.rgb, s.a);
|
|
1731
|
+
}
|
|
1732
|
+
col = mix(col, cream, max(scPlus(c, vec2(0.06, 0.94), 0.02), scPlus(c, vec2(A - 0.06, 0.94), 0.02)));
|
|
1733
|
+
col = mix(col, cream, numTxt(q, vec2(A - 0.2, 0.9) * scU, scCell() * 2.0, mod(cut, 100.0), 2));
|
|
1734
|
+
}
|
|
1735
|
+
|
|
1736
|
+
// (the scene dispatcher is in 66-scene-main.glsl so it sorts after every scene file)
|
|
1737
|
+
|
|
1738
|
+
// Scene 13 (variant 3, rot 1), ribbon-rays: an ochre field with a fan of white hairline rays (the ray count grows on every beat,
|
|
1739
|
+
// every third ray is a thin wedge), and a twisted ribbon that crosses the frame: its front face is black with a heavy condensed word
|
|
1740
|
+
// flowing along it (the flow steps on every beat), its back face is an ochre duotone of the plate; four echo copies trail behind in
|
|
1741
|
+
// colour steps. One DIN Condensed label sits at the root of the rays. Palette: ground (ochre), ink (white), accent (black),
|
|
1742
|
+
// tintA (dark ochre), tintB (pale ochre). Text set 14: r the ribbon line (Avenir Next Condensed), g the label.
|
|
1743
|
+
float rbY(float x, float ph) { return 0.5 + 0.2 * sin(x * 2.6 + ph); }
|
|
1744
|
+
float rbTw(float x) { return cos(x * 1.9 + 0.6); }
|
|
1745
|
+
|
|
1746
|
+
void sceneRibbon(vec2 q, vec2 S, vec4 clk, inout vec3 col) {
|
|
1747
|
+
vec2 c = q / scU;
|
|
1748
|
+
float A = S.x / S.y;
|
|
1749
|
+
vec3 white = inkColor.rgb;
|
|
1750
|
+
vec3 blk = accentColor.rgb;
|
|
1751
|
+
float cut = floor(clk.x);
|
|
1752
|
+
col = groundColor.rgb;
|
|
1753
|
+
// rays from the lower left, one more pair on every beat
|
|
1754
|
+
vec2 ro = vec2(0.14, 0.9);
|
|
1755
|
+
vec2 dr = c - ro;
|
|
1756
|
+
float a = atan(dr.y, dr.x);
|
|
1757
|
+
float nr = 6.0 + mod(cut, 14.0) * 2.0;
|
|
1758
|
+
float ra = a * nr / 6.28318;
|
|
1759
|
+
float da = (fract(ra) - 0.5) * 6.28318 / nr;
|
|
1760
|
+
float ray = scLine(da * length(dr), 1.0);
|
|
1761
|
+
float wedge = step(mod(floor(ra), 3.0), 0.5) * step(abs(da * length(dr)), 0.006 + 0.012 * length(dr));
|
|
1762
|
+
col = mix(col, white, max(ray * 0.85, wedge * 0.9));
|
|
1763
|
+
// the ribbon and its echoes, back to front
|
|
1764
|
+
float flow = cut * 0.07;
|
|
1765
|
+
for (int e = 4; e >= 0; e--) {
|
|
1766
|
+
float fe = float(e);
|
|
1767
|
+
float ph = cut * 0.35 - fe * 0.2;
|
|
1768
|
+
float yy = rbY(c.x, ph) + fe * 0.03;
|
|
1769
|
+
float tw = rbTw(c.x - fe * 0.08);
|
|
1770
|
+
float wd = 0.02 + 0.11 * abs(tw);
|
|
1771
|
+
float dy = c.y - yy;
|
|
1772
|
+
float inside = scAA(abs(dy) - wd);
|
|
1773
|
+
if (e > 0) {
|
|
1774
|
+
vec3 ec = e == 4 ? tintA.rgb : (e == 3 ? tintB.rgb : (e == 2 ? blk : white));
|
|
1775
|
+
col = mix(col, ec, scLine(abs(dy) - wd, 1.5) * 0.9);
|
|
1776
|
+
continue;
|
|
1777
|
+
}
|
|
1778
|
+
vec3 face;
|
|
1779
|
+
if (tw > 0.0) {
|
|
1780
|
+
float m = crisp(sheetC(vec2(fract(c.x * 0.45 + flow) * 0.96 * RENDERSIZE.x, (0.012 + (0.5 + 0.5 * dy / max(wd, 0.004)) * 0.07) * RENDERSIZE.y), 0), 1.0);
|
|
1781
|
+
face = mix(blk, white, m);
|
|
1782
|
+
} else {
|
|
1783
|
+
float l = clamp((luma(scPlate(q, vec2(0.0), S)) - 0.05) * 1.8, 0.0, 1.0);
|
|
1784
|
+
face = mix(blk, vec3(1.0, 0.82, 0.38), l);
|
|
1785
|
+
}
|
|
1786
|
+
col = mix(col, face, inside);
|
|
1787
|
+
col = mix(col, white, scLine(abs(dy) - wd, 1.0) * 0.9);
|
|
1788
|
+
}
|
|
1789
|
+
col = mix(col, blk, scAA(length(c - ro) - 0.012));
|
|
1790
|
+
col = mix(col, blk, scSheet(q, 1));
|
|
1791
|
+
col = mix(col, blk, max(scPlus(c, vec2(A - 0.07, 0.08), 0.02), scPlus(c, vec2(0.45 * A, 0.94), 0.02)));
|
|
1792
|
+
}
|
|
1793
|
+
|
|
1794
|
+
// Scene 14 (variant 4, rot 1), slab-shear: a concrete-grey field with a giant Futura word that flows on a sine wave (the wave steps on
|
|
1795
|
+
// every beat) and is cut into nine horizontal slabs; on every beat some slabs slide sideways and two become safety-blue slabs holding
|
|
1796
|
+
// the plate as a 1-bit Bayer dither with the word in white; a typed Menlo label sits on a seam, with a crosshair target and ticks.
|
|
1797
|
+
// Palette: ground (concrete), ink (white), accent (safety blue), tintA (black). Text set 15: r the giant word, g the typed label.
|
|
1798
|
+
void sceneSlab(vec2 q, vec2 S, vec4 clk, inout vec3 col) {
|
|
1799
|
+
vec2 c = q / scU;
|
|
1800
|
+
float A = S.x / S.y;
|
|
1801
|
+
vec3 blue = accentColor.rgb;
|
|
1802
|
+
vec3 blk = tintA.rgb;
|
|
1803
|
+
float cut = floor(clk.x);
|
|
1804
|
+
float slab = floor(c.y / 0.1111);
|
|
1805
|
+
float h = hash12(vec2(slab, cut));
|
|
1806
|
+
float shift = (step(0.55, h) * (fract(h * 9.0) - 0.5)) * 0.2 * scU;
|
|
1807
|
+
float isBlue = step(0.82, hash12(vec2(slab, cut + 31.0)));
|
|
1808
|
+
float wave = 0.045 * sin(c.x * 7.0 + cut * 0.9) * scU;
|
|
1809
|
+
float grain = fbm(c * 40.0, 3);
|
|
1810
|
+
col = groundColor.rgb * (0.88 + 0.2 * grain);
|
|
1811
|
+
vec2 sq = q + vec2(shift, wave);
|
|
1812
|
+
float m = crisp(sheetC(sq * (RENDERSIZE / scS), 0), 1.0);
|
|
1813
|
+
if (isBlue > 0.5) {
|
|
1814
|
+
float px = scPx();
|
|
1815
|
+
vec2 pix = floor(q / px);
|
|
1816
|
+
float l = scTone((pix + 0.5) * px, vec2(0.0), S, 1.6, 0.05);
|
|
1817
|
+
col = mix(blk, blue, step(scBayer(pix), l));
|
|
1818
|
+
col = mix(col, inkColor.rgb, m);
|
|
1819
|
+
} else {
|
|
1820
|
+
col = mix(col, blk, m);
|
|
1821
|
+
}
|
|
1822
|
+
// seams between slabs and a typed label on one of them
|
|
1823
|
+
float seam = scLine(fract(c.y / 0.1111 + 0.5) * 0.1111 - 0.0555, 1.0);
|
|
1824
|
+
col = mix(col, blk, seam * 0.35);
|
|
1825
|
+
col = mix(col, blk, step(mod(q.x, 0.03 * scU), 1.0) * step(abs(c.y - 0.2222), 0.008));
|
|
1826
|
+
col = mix(col, blk, scSheet(q, 1));
|
|
1827
|
+
vec2 t = vec2(A - 0.2, 0.5);
|
|
1828
|
+
float rr = length(c - t);
|
|
1829
|
+
col = mix(col, blk, max(scLine(rr - 0.09, 1.2), max(scLine(rr - 0.04, 1.0), max(scLine(c.x - t.x, 1.0) * step(abs(c.y - t.y), 0.12), scLine(c.y - t.y, 1.0) * step(abs(c.x - t.x), 0.12)))));
|
|
1830
|
+
col = mix(col, blk, numTxt(q, vec2(0.04, 0.93) * scU, scCell() * 2.0, mod(cut * 14.0, 1000.0), 3));
|
|
1831
|
+
}
|
|
1832
|
+
|
|
1833
|
+
// Scene 15 (variant 5, rot 1), frame-loop-dial: a dark aubergine field with a line of Georgia text that runs round the border of the
|
|
1834
|
+
// frame (every onset jumps it ahead, a quick double speed); an arch window with the plate as a peach Bayer dither; a dial of 60 ticks
|
|
1835
|
+
// filled up on every beat with a split-flap countdown in its middle (the top half of the old digit folds away in 3 frames); a typed Menlo
|
|
1836
|
+
// input line. Palette: ground (aubergine), ink (off-white), accent (peach), tintA (plum). Text set 16: r the border line and the
|
|
1837
|
+
// MesloLGS NF atlas, g the typed line.
|
|
1838
|
+
float fdFlap(vec2 q, vec2 lo, vec2 sz, float oldD, float newD, float u) {
|
|
1839
|
+
float fs = sz.y * 0.8;
|
|
1840
|
+
vec2 org = lo + vec2((sz.x - 0.602 * fs) * 0.5, (sz.y - fs) * 0.5);
|
|
1841
|
+
float mid = lo.y + 0.5 * sz.y;
|
|
1842
|
+
vec2 pn = q - org * scU;
|
|
1843
|
+
float dn = aNum(pn, fs * scU, newD, 1);
|
|
1844
|
+
float dOld = 0.0;
|
|
1845
|
+
float v = 0.0;
|
|
1846
|
+
if (q.y >= mid * scU) {
|
|
1847
|
+
v = u < 0.66 ? aNum(q - org * scU, fs * scU, oldD, 1) : dn;
|
|
1848
|
+
} else {
|
|
1849
|
+
float vis = 1.0 - u;
|
|
1850
|
+
float yy = mid * scU - (mid * scU - q.y) / max(vis, 0.001);
|
|
1851
|
+
if (u < 1.0 && (mid * scU - q.y) < 0.5 * sz.y * scU * vis) { v = aNum(vec2(q.x, yy) - org * scU, fs * scU, oldD, 1); }
|
|
1852
|
+
else if (u < 1.0) { v = dn; }
|
|
1853
|
+
else { v = dn; }
|
|
1854
|
+
}
|
|
1855
|
+
return crisp(v, 4.0);
|
|
1856
|
+
}
|
|
1857
|
+
|
|
1858
|
+
void sceneFrameDial(vec2 q, vec2 S, vec4 clk, inout vec3 col) {
|
|
1859
|
+
vec2 c = q / scU;
|
|
1860
|
+
float A = S.x / S.y;
|
|
1861
|
+
vec3 off = inkColor.rgb;
|
|
1862
|
+
vec3 peach = accentColor.rgb;
|
|
1863
|
+
vec3 plum = tintA.rgb;
|
|
1864
|
+
float cut = floor(clk.x);
|
|
1865
|
+
float age = float(FRAMEINDEX) - clk.y;
|
|
1866
|
+
float u = cut < 0.5 ? 1.0 : clamp((age + 1.0) / 3.0, 0.0, 1.0);
|
|
1867
|
+
col = groundColor.rgb;
|
|
1868
|
+
// text round the border
|
|
1869
|
+
float bnd = 0.055;
|
|
1870
|
+
vec4 dd = vec4(c.y, A - c.x, 1.0 - c.y, c.x);
|
|
1871
|
+
float mn = min(min(dd.x, dd.y), min(dd.z, dd.w));
|
|
1872
|
+
float perim = 2.0 * A + 2.0;
|
|
1873
|
+
float s;
|
|
1874
|
+
float depth = mn;
|
|
1875
|
+
if (mn == dd.x) { s = c.x; }
|
|
1876
|
+
else if (mn == dd.y) { s = A + c.y; }
|
|
1877
|
+
else if (mn == dd.z) { s = A + 1.0 + (A - c.x); }
|
|
1878
|
+
else { s = 2.0 * A + 1.0 + (1.0 - c.y); }
|
|
1879
|
+
float tflow = TIME * 0.06 * perim + clk.z * 0.06;
|
|
1880
|
+
float k = RENDERSIZE.y;
|
|
1881
|
+
float ux = mod((s - tflow) * k, 5.0 * 101.8 * k / 360.0);
|
|
1882
|
+
float m = crisp(sheetC(vec2(ux, (0.012 + depth / bnd * 0.056) * k), 0), 1.0) * step(depth, bnd);
|
|
1883
|
+
col = mix(col, plum, step(depth, bnd));
|
|
1884
|
+
col = mix(col, peach, m);
|
|
1885
|
+
col = mix(col, peach, scLine(depth - bnd, 1.0) * 0.8);
|
|
1886
|
+
// arch window with a peach dither of the plate
|
|
1887
|
+
vec2 lo = vec2(0.17, 0.14);
|
|
1888
|
+
vec2 hi = vec2(0.84, 0.88);
|
|
1889
|
+
float px = scPx();
|
|
1890
|
+
vec2 pix = floor(q / px);
|
|
1891
|
+
float l = scTone((pix + 0.5) * px, lo * scU, hi * scU, 1.6, 0.06);
|
|
1892
|
+
col = mix(col, mix(plum, peach, step(scBayer(pix), l)), scAA(sdArch(c, lo, hi)));
|
|
1893
|
+
col = mix(col, off, scLine(sdArch(c, lo - 0.012, hi + 0.012), 1.0));
|
|
1894
|
+
// dial of 60 ticks and the split-flap countdown
|
|
1895
|
+
vec2 ctr = vec2(1.3, 0.5);
|
|
1896
|
+
float rr = length(c - ctr);
|
|
1897
|
+
float ang = (atan(c.y - ctr.y, c.x - ctr.x) / 6.28318 + 0.5) * 60.0;
|
|
1898
|
+
float tk = step(0.25, fract(ang)) * step(fract(ang), 0.75) * step(0.3, rr) * step(rr, 0.3 + 0.03 + 0.02 * step(mod(floor(ang), 5.0), 0.5));
|
|
1899
|
+
float on = step(floor(ang) + 0.5, mod(cut, 60.0));
|
|
1900
|
+
col = mix(col, mix(plum * 1.6, peach, on), tk);
|
|
1901
|
+
float val = mod(60.0 - cut, 100.0);
|
|
1902
|
+
float cw = 0.17;
|
|
1903
|
+
float v1 = fdFlap(q, vec2(ctr.x - 0.185, ctr.y - 0.13), vec2(cw, 0.26), floor(mod(60.0 - cut + 1.0, 100.0) / 10.0), floor(val / 10.0), u);
|
|
1904
|
+
float v2 = fdFlap(q, vec2(ctr.x + 0.015, ctr.y - 0.13), vec2(cw, 0.26), mod(60.0 - cut + 1.0, 10.0), mod(val, 10.0), u);
|
|
1905
|
+
col = mix(col, off, scAA(sdBox(c, vec2(ctr.x - 0.185, ctr.y - 0.13), vec2(ctr.x - 0.015, ctr.y + 0.13)) - 0.02));
|
|
1906
|
+
col = mix(col, off, scAA(sdBox(c, vec2(ctr.x + 0.015, ctr.y - 0.13), vec2(ctr.x + 0.185, ctr.y + 0.13)) - 0.02));
|
|
1907
|
+
col = mix(col, groundColor.rgb, min(v1 + v2, 1.0));
|
|
1908
|
+
col = mix(col, groundColor.rgb, scLine(c.y - ctr.y, 2.0) * scBox(c, vec2(ctr.x - 0.185, 0.0), vec2(ctr.x + 0.185, 1.0)));
|
|
1909
|
+
col = mix(col, peach, scSheet(q, 1));
|
|
1910
|
+
col = mix(col, off, max(scPlus(c, vec2(1.0, 0.18), 0.02), scPlus(c, vec2(1.6, 0.82), 0.02)));
|
|
1911
|
+
}
|
|
1912
|
+
|
|
1913
|
+
// Scene 16 (variant 6, rot 1), tilt-tiles: a lemon field tilted about 14 degrees into rows of Rockwell word tiles. Neighbouring rows flow
|
|
1914
|
+
// the other way and each beat every row jumps a different distance; filled and outlined rows alternate, and each onset swaps the kind
|
|
1915
|
+
// of one row. A tilted window holds the plate as a three-tone posterize (black, lemon, white); a white caption box, a numbered black disc.
|
|
1916
|
+
// Palette: ground (lemon), ink (black), accent (white), tintA (deep green). Text set 17: r filled word, g outlined word, b caption.
|
|
1917
|
+
void sceneTilt(vec2 q, vec2 S, vec4 clk, inout vec3 col) {
|
|
1918
|
+
vec2 c = q / scU;
|
|
1919
|
+
float A = S.x / S.y;
|
|
1920
|
+
vec3 blk = inkColor.rgb;
|
|
1921
|
+
vec3 wht = accentColor.rgb;
|
|
1922
|
+
float cut = floor(clk.x * 0.5);
|
|
1923
|
+
col = groundColor.rgb;
|
|
1924
|
+
vec2 pr = stRot(c - vec2(0.5 * A, 0.5), 0.24);
|
|
1925
|
+
float rowH = 0.14;
|
|
1926
|
+
float n = floor(pr.y / rowH);
|
|
1927
|
+
float v = pr.y - n * rowH;
|
|
1928
|
+
float dir = mod(n, 2.0) < 0.5 ? 1.0 : -1.0;
|
|
1929
|
+
float off = dir * cut * (0.14 + 0.05 * mod(abs(n), 3.0));
|
|
1930
|
+
float u = mod(pr.x + off, 0.92);
|
|
1931
|
+
float k = RENDERSIZE.y;
|
|
1932
|
+
float swp = step(abs(mod(n, 7.0) - mod(clk.z, 7.0)), 0.5);
|
|
1933
|
+
int ch = mod(n + swp, 2.0) < 0.5 ? 0 : 1;
|
|
1934
|
+
float m = crisp(sheetC(vec2(u * 0.5 * k, (0.0478 + (v - 0.07) * 0.5) * k), ch), 1.0);
|
|
1935
|
+
col = mix(col, blk, m);
|
|
1936
|
+
col = mix(col, blk, scLine(v, 1.0) * 0.6);
|
|
1937
|
+
// tilted window with the posterized plate
|
|
1938
|
+
vec2 wc = vec2(0.04, 0.0);
|
|
1939
|
+
vec2 wh = vec2(0.5, 0.25);
|
|
1940
|
+
float inW = scAA(sdBox(pr, wc - wh, wc + wh));
|
|
1941
|
+
float l = scTone(q, vec2(0.0), S, 1.5, 0.05);
|
|
1942
|
+
vec3 pz = l < 0.3 ? blk : (l < 0.62 ? groundColor.rgb : wht);
|
|
1943
|
+
col = mix(col, pz, inW);
|
|
1944
|
+
col = mix(col, blk, scLine(sdBox(pr, wc - wh, wc + wh), 3.0));
|
|
1945
|
+
// caption box, numbered disc
|
|
1946
|
+
col = mix(col, wht, scAA(sdBox(c, vec2(0.04, 0.86), vec2(0.7, 0.97))));
|
|
1947
|
+
col = mix(col, blk, scSheet(q, 2) * scBox(c, vec2(0.04, 0.86), vec2(0.7, 0.97)));
|
|
1948
|
+
vec2 dc = vec2(A - 0.14, 0.15);
|
|
1949
|
+
col = mix(col, blk, scAA(length(c - dc) - 0.09));
|
|
1950
|
+
col = mix(col, wht, numTxt(q, (dc - vec2(0.035, 0.03)) * scU, scCell() * 2.0, mod(cut, 100.0), 2));
|
|
1951
|
+
col = mix(col, tintA.rgb, scLine(length(c - dc) - 0.115, 2.0));
|
|
1952
|
+
}
|
|
1953
|
+
|
|
1954
|
+
// Scene 17 (variant 7, rot 1), marquee-stack: a teal field of six stacked word rows. Every beat each row jumps its own distance in its own
|
|
1955
|
+
// direction (a marquee that moves in steps, not a scroll); each row has three echo copies trailing in colour steps (dark teal,
|
|
1956
|
+
// tangerine, cream shade); the last row is Hangul. A cream-framed window holds the plate as a coarse four-colour mosaic. Palette: ground
|
|
1957
|
+
// (teal), ink (cream), accent (tangerine), tintA (dark teal). Text set 18: r the word (Gill Sans Bold), g the Hangul word, b the caption.
|
|
1958
|
+
void sceneMarquee(vec2 q, vec2 S, vec4 clk, inout vec3 col) {
|
|
1959
|
+
vec2 c = q / scU;
|
|
1960
|
+
float A = S.x / S.y;
|
|
1961
|
+
vec3 cream = inkColor.rgb;
|
|
1962
|
+
vec3 tang = accentColor.rgb;
|
|
1963
|
+
vec3 deep = tintA.rgb;
|
|
1964
|
+
float cut = floor(clk.x);
|
|
1965
|
+
col = groundColor.rgb;
|
|
1966
|
+
float n = floor((c.y - 0.05) / 0.15);
|
|
1967
|
+
float v = (c.y - 0.05) - n * 0.15;
|
|
1968
|
+
float k = RENDERSIZE.y;
|
|
1969
|
+
if (n >= 0.0 && n < 6.0) {
|
|
1970
|
+
float dk = n < 0.5 ? 0.25 : (n < 1.5 ? 0.42 : (n < 2.5 ? 0.6 : (n < 3.5 ? 0.33 : (n < 4.5 ? 0.5 : 0.7))));
|
|
1971
|
+
float dir = mod(n, 2.0) < 0.5 ? 1.0 : -1.0;
|
|
1972
|
+
float off = dir * (cut * dk + clk.z * 0.02 * dk);
|
|
1973
|
+
int ch = n > 4.5 ? 1 : 0;
|
|
1974
|
+
for (int e = 3; e >= 0; e--) {
|
|
1975
|
+
float oe = off + dir * float(e) * 0.07;
|
|
1976
|
+
float u = mod(c.x + oe, 0.95);
|
|
1977
|
+
float m = crisp(sheetC(vec2(u * 0.5 * k, (0.0478 + (v - 0.075) * 0.5) * k), ch), 1.0);
|
|
1978
|
+
vec3 ec = e == 3 ? deep : (e == 2 ? tang : (e == 1 ? cream * 0.78 : cream));
|
|
1979
|
+
col = mix(col, ec, m);
|
|
1980
|
+
}
|
|
1981
|
+
}
|
|
1982
|
+
col = mix(col, cream, scLine(fract((c.y - 0.05) / 0.15) * 0.15, 1.0) * 0.0);
|
|
1983
|
+
// mosaic window
|
|
1984
|
+
vec2 lo = vec2(1.1, 0.2);
|
|
1985
|
+
vec2 hi = vec2(1.64, 0.8);
|
|
1986
|
+
float blk = 0.022 * scU;
|
|
1987
|
+
vec2 mq = (floor(q / blk) + 0.5) * blk;
|
|
1988
|
+
float l = pow(scTone(mq, lo * scU, hi * scU, 1.5, 0.02), 0.6);
|
|
1989
|
+
vec3 mc = l < 0.25 ? deep : (l < 0.5 ? groundColor.rgb * 1.25 : (l < 0.75 ? tang : cream));
|
|
1990
|
+
col = mix(col, mc, scAA(sdBox(c, lo, hi)));
|
|
1991
|
+
col = mix(col, cream, scLine(sdBox(c, lo - 0.012, hi + 0.012), 3.0));
|
|
1992
|
+
// caption bar, disc, crosses
|
|
1993
|
+
col = mix(col, cream, scAA(sdBox(c, vec2(0.04, 0.955), vec2(0.8, 1.01))));
|
|
1994
|
+
col = mix(col, deep, scSheet(q, 2) * scBox(c, vec2(0.04, 0.955), vec2(0.8, 1.01)));
|
|
1995
|
+
col = mix(col, tang, scAA(length(c - vec2(A - 0.12, 0.88)) - 0.07));
|
|
1996
|
+
col = mix(col, deep, numTxt(q, vec2(A - 0.155, 0.855) * scU, scCell() * 2.0, mod(cut, 100.0), 2));
|
|
1997
|
+
col = mix(col, cream, max(scPlus(c, vec2(1.05, 0.15), 0.02), scPlus(c, vec2(1.69, 0.85), 0.02)));
|
|
1998
|
+
}
|
|
1999
|
+
|
|
2000
|
+
// Scene 18 (variant 8, rot 1), lens-wrap: an olive field; the plate wrapped on a sphere (longitude / latitude mapping, a red-blue lens
|
|
2001
|
+
// fringe, a specular patch) whose size swells with the bass; a perspective floor of pink tile lines that steps toward you on every beat;
|
|
2002
|
+
// a 4 x 3 block of small panels that each turn a quarter on every third onset; Didot and Courier New type. Palette: ground (olive),
|
|
2003
|
+
// ink (pink), accent (black), tintA (dark olive), tintB (cream). Text set 19: r the word (Didot), g the caption (Courier New).
|
|
2004
|
+
void sceneLens(vec2 q, vec2 S, vec4 clk, inout vec3 col) {
|
|
2005
|
+
vec2 c = q / scU;
|
|
2006
|
+
float A = S.x / S.y;
|
|
2007
|
+
vec3 pink = inkColor.rgb;
|
|
2008
|
+
vec3 blk = accentColor.rgb;
|
|
2009
|
+
vec3 cream = tintB.rgb;
|
|
2010
|
+
float cut = floor(clk.x);
|
|
2011
|
+
col = groundColor.rgb;
|
|
2012
|
+
// perspective floor
|
|
2013
|
+
float hy = 0.58;
|
|
2014
|
+
float t = 0.1 / max(c.y - hy + 0.004, 0.004);
|
|
2015
|
+
float wx = (c.x - 0.5 * A) * t * 1.2;
|
|
2016
|
+
float wz = t * 1.2 + cut * 0.5;
|
|
2017
|
+
float gx = 1.0 - clamp((0.5 - abs(fract(wx) - 0.5)) / max(fwidth(wx) * 1.2, 1e-3), 0.0, 1.0);
|
|
2018
|
+
float gz = 1.0 - clamp((0.5 - abs(fract(wz) - 0.5)) / max(fwidth(wz) * 1.2, 1e-3), 0.0, 1.0);
|
|
2019
|
+
float below = step(hy, c.y);
|
|
2020
|
+
col = mix(col, tintA.rgb, 0.6 * below);
|
|
2021
|
+
col = mix(col, pink, max(gx, gz) * smoothstep(0.0, 0.08, c.y - hy) * 0.9 * below);
|
|
2022
|
+
col = mix(col, pink, scLine(c.y - hy, 1.0) * 0.8);
|
|
2023
|
+
// sphere
|
|
2024
|
+
vec2 ctr = vec2(0.62, 0.45);
|
|
2025
|
+
float R = 0.3 + 0.05 * stLevel().r;
|
|
2026
|
+
vec2 d = (c - ctr) / R;
|
|
2027
|
+
float r2 = dot(d, d);
|
|
2028
|
+
float z = sqrt(max(1.0 - r2, 0.0));
|
|
2029
|
+
vec2 uv = vec2(0.5 + atan(d.x, max(z, 0.001)) / 3.0, 0.5 + asin(clamp(d.y, -1.0, 1.0)) / 3.0);
|
|
2030
|
+
vec3 f = vec3(scPlate((uv - 0.5) * S + 0.5 * S, vec2(0.0), S).r, scPlate((uv - 0.5) * 1.025 * S + 0.5 * S, vec2(0.0), S).g, scPlate((uv - 0.5) * 1.05 * S + 0.5 * S, vec2(0.0), S).b);
|
|
2031
|
+
f = clamp((f - 0.06) * 1.3, 0.0, 1.0) * (0.35 + 0.65 * z);
|
|
2032
|
+
float spec = smoothstep(0.28, 0.0, length((d - vec2(-0.38, -0.42)) * vec2(1.0, 1.6)));
|
|
2033
|
+
f = mix(f, cream, spec * 0.55);
|
|
2034
|
+
col = mix(col, f, scAA((sqrt(r2) - 1.0) * R));
|
|
2035
|
+
col = mix(col, pink, scLine((sqrt(r2) - 1.0) * R, 2.0));
|
|
2036
|
+
col = mix(col, pink, scLine(length((c - ctr) * vec2(1.0, 3.2)) - 0.46, 1.0) * 0.8);
|
|
2037
|
+
// small panels that turn
|
|
2038
|
+
vec2 g = (c - vec2(A - 0.62, 0.06)) / 0.14;
|
|
2039
|
+
vec2 pid = floor(g);
|
|
2040
|
+
if (pid.x >= 0.0 && pid.x < 4.0 && pid.y >= 0.0 && pid.y < 3.0) {
|
|
2041
|
+
float i = pid.x + 4.0 * pid.y;
|
|
2042
|
+
vec2 p = (fract(g) - 0.5) * 0.14;
|
|
2043
|
+
if (abs(p.x) < 0.055 && abs(p.y) < 0.055) {
|
|
2044
|
+
p = stRot(p, floor((clk.z + i) / 3.0) * 1.5708);
|
|
2045
|
+
float bars = 0.0;
|
|
2046
|
+
for (int j = 0; j < 3; j++) {
|
|
2047
|
+
float h = 0.02 + 0.07 * hash12(vec2(i, float(j)));
|
|
2048
|
+
bars = max(bars, step(abs(p.x - (-0.03 + 0.03 * float(j))), 0.009) * step(-0.045, p.y) * step(p.y, -0.045 + h));
|
|
2049
|
+
}
|
|
2050
|
+
col = mix(cream, blk, bars);
|
|
2051
|
+
}
|
|
2052
|
+
}
|
|
2053
|
+
col = mix(col, cream, scSheet(q, 0));
|
|
2054
|
+
col = mix(col, cream, scSheet(q, 1));
|
|
2055
|
+
col = mix(col, blk, numTxt(q, vec2(0.05, 0.92) * scU, scCell() * 2.0, mod(cut * 3.0, 1000.0), 3));
|
|
2056
|
+
}
|
|
2057
|
+
|
|
2058
|
+
// Scene 19 (variant 9, rot 1), liquid-type: a sky-blue field; the plate blurred and thresholded into ink-blot shapes (mid blue, one
|
|
2059
|
+
// orange blot in the brightest part); a big Bodoni 72 word on a double sine ripple whose phase steps on every beat; a typed American
|
|
2060
|
+
// Typewriter note and a crosshair reticle that jumps to a new place on every beat. Palette: ground (sky), ink (navy), accent (orange),
|
|
2061
|
+
// tintA (pale), tintB (mid blue). Text set 20: r the word (Bodoni 72), g the typed note (American Typewriter).
|
|
2062
|
+
void sceneLiquid(vec2 q, vec2 S, vec4 clk, inout vec3 col) {
|
|
2063
|
+
vec2 c = q / scU;
|
|
2064
|
+
float A = S.x / S.y;
|
|
2065
|
+
vec4 hit = stHit();
|
|
2066
|
+
vec3 navy = inkColor.rgb;
|
|
2067
|
+
vec3 org = accentColor.rgb;
|
|
2068
|
+
float cut = floor(clk.x);
|
|
2069
|
+
col = groundColor.rgb;
|
|
2070
|
+
// ink blots: blurred plate luma thresholded
|
|
2071
|
+
float b = 0.0;
|
|
2072
|
+
float r = 7.0 * U * 3.0;
|
|
2073
|
+
for (int i = 0; i < 8; i++) {
|
|
2074
|
+
float a = float(i) * 0.7854;
|
|
2075
|
+
b += luma(scPlate(q + r * vec2(cos(a), sin(a)), vec2(0.0), S));
|
|
2076
|
+
}
|
|
2077
|
+
b = b / 8.0;
|
|
2078
|
+
float thr = 0.3 - 0.05 * hit.y;
|
|
2079
|
+
col = mix(col, tintB.rgb, smoothstep(thr, thr + 0.025, b));
|
|
2080
|
+
col = mix(col, org, smoothstep(0.5, 0.53, b));
|
|
2081
|
+
// liquid word
|
|
2082
|
+
float ph = cut * 0.9;
|
|
2083
|
+
vec2 sq = q + scU * vec2(0.02 * sin(c.y * 14.0 + ph), 0.03 * sin(c.x * 6.0 + ph * 1.3));
|
|
2084
|
+
float m = crisp(sheetC(sq * (RENDERSIZE / scS), 0), 1.0);
|
|
2085
|
+
col = mix(col, navy, m);
|
|
2086
|
+
// reticle
|
|
2087
|
+
vec2 rp = vec2(0.3 + (A - 0.6) * hash12(vec2(cut, 2.0)), 0.25 + 0.5 * hash12(vec2(cut, 5.0)));
|
|
2088
|
+
col = mix(col, navy, max(scLine(length(c - rp) - 0.06, 1.2), max(scLine(c.x - rp.x, 1.0) * step(abs(c.y - rp.y), 0.1) * step(0.03, abs(c.y - rp.y)), scLine(c.y - rp.y, 1.0) * step(abs(c.x - rp.x), 0.1) * step(0.03, abs(c.x - rp.x)))));
|
|
2089
|
+
col = mix(col, navy, numTxt(q, (rp + vec2(0.07, 0.06)) * scU, scCell(), mod(cut * 17.0, 1000.0), 3));
|
|
2090
|
+
col = mix(col, navy, scSheet(q, 1));
|
|
2091
|
+
col = mix(col, navy, max(scPlus(c, vec2(0.06, 0.06), 0.02), scPlus(c, vec2(A - 0.06, 0.94), 0.02)));
|
|
2092
|
+
}
|
|
2093
|
+
|
|
2094
|
+
// Scene 20 (variant 0, rot 2), panel-grid: an ice-white sheet with a 6 x 4 grid of small square panels, each a thin-line instrument
|
|
2095
|
+
// (plate isolines, spectrum comb, bass gauge, big number, starburst, waveform, checker, reticle). On every onset one panel (in turn)
|
|
2096
|
+
// swings a quarter turn in three frames and shows its next instrument. Brick accents; Optima and SF Mono type. Palette: ground (ice),
|
|
2097
|
+
// ink (black), accent (brick), tintA (grey). Text set 21: r the Optima caption, g the SF Mono caption.
|
|
2098
|
+
vec2 pgPanel(int kind, vec2 p, vec2 ctr, vec4 clk) {
|
|
2099
|
+
float h = 0.1;
|
|
2100
|
+
vec2 pp = (p + h) * scU;
|
|
2101
|
+
float cell = scCell();
|
|
2102
|
+
if (kind == 0) {
|
|
2103
|
+
float l = scTone((ctr + p) * scU, (ctr - h) * scU, (ctr + h) * scU, 1.4, 0.05);
|
|
2104
|
+
return vec2(smoothstep(0.38, 0.46, abs(fract(l * 7.0) - 0.5)), 0.0);
|
|
2105
|
+
}
|
|
2106
|
+
if (kind == 1) {
|
|
2107
|
+
float i = floor((p.x + h) / (2.0 * h) * 12.0);
|
|
2108
|
+
float lv = bandAt((i + 0.5) / 12.0);
|
|
2109
|
+
float bar = step(abs(fract((p.x + h) / (2.0 * h) * 12.0) - 0.5), 0.3) * step(h - lv * 2.0 * h * 0.9, p.y + h) * step(p.y, h * 0.9);
|
|
2110
|
+
return vec2(bar * step(0.3, lv + 0.2), bar * step(0.7, lv));
|
|
2111
|
+
}
|
|
2112
|
+
if (kind == 2) {
|
|
2113
|
+
float r = length(p);
|
|
2114
|
+
float a = atan(p.x, -p.y);
|
|
2115
|
+
float na = -2.3 + 4.6 * stLevel().r;
|
|
2116
|
+
float needle = scLine(sdSeg(p, vec2(0.0), 0.075 * vec2(sin(na), -cos(na))), 1.5);
|
|
2117
|
+
float tk = step(abs(fract(a * 3.8197) - 0.5), 0.12) * step(0.065, r) * step(r, 0.085) * step(abs(a), 2.4);
|
|
2118
|
+
return vec2(max(scLine(r - 0.085, 1.0), tk), needle);
|
|
2119
|
+
}
|
|
2120
|
+
if (kind == 3) { return vec2(numTxt(pp, vec2(0.04, 0.07) * scU, cell * 2.0, mod(clk.x * 7.0, 100.0), 2), 0.0); }
|
|
2121
|
+
if (kind == 4) { return vec2(scBurst(p, 0.09, 0.012, 0.0, 24.0), scAA(length(p) - 0.01)); }
|
|
2122
|
+
if (kind == 5) {
|
|
2123
|
+
float y = waveI((p.x + h) / (2.0 * h) * 400.0) * scopeGain * 0.3;
|
|
2124
|
+
return vec2(scLine(p.y - y, 1.2) * step(abs(p.x), 0.09), scLine(p.y, 1.0) * 0.0);
|
|
2125
|
+
}
|
|
2126
|
+
if (kind == 6) {
|
|
2127
|
+
vec2 g = floor(p / 0.033);
|
|
2128
|
+
return vec2(step(1.0, mod(g.x + g.y, 2.0)) * step(abs(p.x), 0.09) * step(abs(p.y), 0.09), 0.0);
|
|
2129
|
+
}
|
|
2130
|
+
float rr = length(p);
|
|
2131
|
+
return vec2(max(max(scLine(rr - 0.05, 1.0), scLine(p.x, 1.0) * step(abs(p.y), 0.085)), scLine(p.y, 1.0) * step(abs(p.x), 0.085)), 0.0);
|
|
2132
|
+
}
|
|
2133
|
+
|
|
2134
|
+
void scenePanelGrid(vec2 q, vec2 S, vec4 clk, inout vec3 col) {
|
|
2135
|
+
vec2 c = q / scU;
|
|
2136
|
+
float A = S.x / S.y;
|
|
2137
|
+
vec3 ink = inkColor.rgb;
|
|
2138
|
+
vec3 brick = accentColor.rgb;
|
|
2139
|
+
col = groundColor.rgb;
|
|
2140
|
+
vec2 o = vec2((A - 1.38) * 0.5, 0.04);
|
|
2141
|
+
vec2 g = (c - o) / 0.23;
|
|
2142
|
+
vec2 id = floor(g);
|
|
2143
|
+
if (id.x >= 0.0 && id.x < 6.0 && id.y >= 0.0 && id.y < 4.0) {
|
|
2144
|
+
vec2 ctr = o + (id + 0.5) * 0.23;
|
|
2145
|
+
vec2 p = c - ctr;
|
|
2146
|
+
float i = id.x + 6.0 * id.y;
|
|
2147
|
+
if (abs(p.x) < 0.105 && abs(p.y) < 0.105) {
|
|
2148
|
+
float mine = mod(clk.z, 24.0) == i ? 1.0 : 0.0;
|
|
2149
|
+
float age = float(FRAMEINDEX) - clk.w;
|
|
2150
|
+
float u = (mine > 0.5 && clk.z > 0.5) ? clamp((age + 1.0) / 3.0, 0.0, 1.0) : 1.0;
|
|
2151
|
+
float turns = floor((clk.z + 24.0 - i) / 24.0);
|
|
2152
|
+
float ang = (turns - (1.0 - u)) * 1.5708;
|
|
2153
|
+
float tcount = u < 0.5 ? turns - 1.0 : turns;
|
|
2154
|
+
int kind = int(floor(hash12(vec2(i, 3.3 + tcount)) * 8.0));
|
|
2155
|
+
vec2 pr = stRot(p, ang);
|
|
2156
|
+
vec2 res = pgPanel(kind, pr, ctr, clk);
|
|
2157
|
+
col = mix(col, tintA.rgb * 1.5, 0.0);
|
|
2158
|
+
col = mix(col, ink, res.x * step(abs(pr.x), 0.1) * step(abs(pr.y), 0.1));
|
|
2159
|
+
col = mix(col, brick, res.y);
|
|
2160
|
+
}
|
|
2161
|
+
col = mix(col, ink, scLine(sdBox(p, vec2(-0.105), vec2(0.105)), 1.0));
|
|
2162
|
+
}
|
|
2163
|
+
col = mix(col, brick, scAA(sdBox(c, vec2(0.0, 0.04), vec2(o.x - 0.04, 0.14))));
|
|
2164
|
+
col = mix(col, ink, scLine(c.x - (o.x - 0.02), 1.0) * step(0.2, c.y) * step(c.y, 0.96) * 0.7);
|
|
2165
|
+
col = mix(col, ink, scSheet(q, 0));
|
|
2166
|
+
col = mix(col, ink, scSheet(q, 1));
|
|
2167
|
+
col = mix(col, brick, scLine(c.y - 0.975, 2.0) * step(0.0, c.x) * step(c.x, A * (0.2 + 0.8 * stLevel().a)));
|
|
2168
|
+
}
|
|
2169
|
+
|
|
2170
|
+
// Scene 21 (variant 1, rot 2), mirror-track: a violet field and a central window holding the plate mirrored about its vertical axis and
|
|
2171
|
+
// solarized into navy / brick / cream. Five outline target squares with tiny number labels jump to new places on every beat and are
|
|
2172
|
+
// mirrored with the plate; a barcode strip re-seeds on every beat; a file-lookup text block with struck-through rows (D2Coding) and a big
|
|
2173
|
+
// Phosphate word. Palette: ground (dusty violet), ink (cream), accent (brick red), tintA (indigo), tintB (pale violet). Text set 22: r the word, g the file block.
|
|
2174
|
+
void sceneMirror(vec2 q, vec2 S, vec4 clk, inout vec3 col) {
|
|
2175
|
+
vec2 c = q / scU;
|
|
2176
|
+
float A = S.x / S.y;
|
|
2177
|
+
vec4 hit = stHit();
|
|
2178
|
+
vec3 cream = inkColor.rgb;
|
|
2179
|
+
vec3 navy = accentColor.rgb;
|
|
2180
|
+
vec3 dk = tintA.rgb;
|
|
2181
|
+
float cut = floor(clk.x);
|
|
2182
|
+
col = groundColor.rgb;
|
|
2183
|
+
vec2 lo = vec2(0.34, 0.08);
|
|
2184
|
+
vec2 hi = vec2(A - 0.06, 0.8);
|
|
2185
|
+
float wc = 0.5 * (lo.x + hi.x);
|
|
2186
|
+
vec2 qm = vec2(wc * scU + abs(q.x - wc * scU), q.y);
|
|
2187
|
+
float l = scTone(qm, lo * scU, hi * scU, 1.4, 0.05);
|
|
2188
|
+
float s = abs(l - (0.4 + 0.05 * mod(cut, 3.0))) * 2.0;
|
|
2189
|
+
vec3 sol = s < 0.22 ? navy : (s < 0.55 ? dk : cream);
|
|
2190
|
+
col = mix(col, sol, scAA(sdBox(c, lo, hi)));
|
|
2191
|
+
col = mix(col, cream, scLine(sdBox(c, lo - 0.01, hi + 0.01), 1.5));
|
|
2192
|
+
col = mix(col, cream, scLine(c.x - wc, 1.0) * step(lo.y, c.y) * step(c.y, hi.y) * 0.8);
|
|
2193
|
+
// targets, mirrored
|
|
2194
|
+
for (int i = 0; i < 5; i++) {
|
|
2195
|
+
float fi = float(i);
|
|
2196
|
+
vec2 h = hash22(vec2(fi + 1.0, cut));
|
|
2197
|
+
vec2 tp = vec2(mix(lo.x + 0.05, wc, h.x), mix(lo.y + 0.06, hi.y - 0.06, h.y));
|
|
2198
|
+
float sz = 0.03 + 0.03 * hash12(vec2(fi, 9.0));
|
|
2199
|
+
for (int sd = 0; sd < 2; sd++) {
|
|
2200
|
+
vec2 tq = sd == 0 ? tp : vec2(2.0 * wc - tp.x, tp.y);
|
|
2201
|
+
float box = scLine(sdBox(c, tq - sz, tq + sz), 1.2);
|
|
2202
|
+
vec2 br = abs(c - tq) - sz;
|
|
2203
|
+
col = mix(col, cream, max(box, 0.0));
|
|
2204
|
+
col = mix(col, cream, numTxt(q, (tq + vec2(sz + 0.01, -sz)) * scU, scCell(), mod(fi * 37.0 + cut * 11.0, 1000.0), 3));
|
|
2205
|
+
}
|
|
2206
|
+
}
|
|
2207
|
+
// barcode
|
|
2208
|
+
float bx = floor(c.x / 0.004);
|
|
2209
|
+
float bar = step(0.5, hash12(vec2(bx, cut))) * step(0.04, c.x) * step(c.x, 0.3) * step(0.86, c.y) * step(c.y, 0.96);
|
|
2210
|
+
col = mix(col, cream, bar);
|
|
2211
|
+
// file block with struck-through rows
|
|
2212
|
+
float row = floor((c.y - 0.1) / 0.034);
|
|
2213
|
+
float strike = step(0.0, row) * step(mod(row, 3.0), 1.5) * step(0.5, mod(row, 3.0)) * step(abs(c.y - (0.1 + (row + 0.5) * 0.034)), 0.0012) * step(0.04, c.x) * step(c.x, 0.3);
|
|
2214
|
+
col = mix(col, cream, scSheet(q, 1));
|
|
2215
|
+
col = mix(col, cream, strike);
|
|
2216
|
+
col = mix(col, cream, scSheet(q, 0));
|
|
2217
|
+
col = mix(col, navy, scAA(sdBox(c, vec2(0.04, 0.03), vec2(0.04 + 0.26 * stLevel().a, 0.045))));
|
|
2218
|
+
}
|
|
2219
|
+
|
|
2220
|
+
// Scene dispatcher: variant 1..9 and 0 are the first ten scenes, rot 1 adds 10 (variant 0..5 + 10 are the round 9 scenes).
|
|
2221
|
+
void drawScene(int v, vec2 q, vec2 S, vec4 clk, inout vec3 col) {
|
|
2222
|
+
scS = S;
|
|
2223
|
+
scU = S.y;
|
|
2224
|
+
if (v == 1) { sceneSpecimen(q, S, clk, col); }
|
|
2225
|
+
if (v == 2) { sceneWiring(q, S, clk, col); }
|
|
2226
|
+
if (v == 3) { sceneFieldCut(q, S, clk, col); }
|
|
2227
|
+
if (v == 4) { scenePattern(q, S, clk, col); }
|
|
2228
|
+
if (v == 5) { sceneAnatomy(q, S, clk, col); }
|
|
2229
|
+
if (v == 6) { sceneDeck(q, S, clk, col); }
|
|
2230
|
+
if (v == 7) { sceneBootlog(q, S, clk, col); }
|
|
2231
|
+
if (v == 8) { sceneTunnel(q, S, clk, col); }
|
|
2232
|
+
if (v == 9) { sceneRunner(q, S, clk, col); }
|
|
2233
|
+
if (v == 0) { sceneAscii(q, S, clk, col); }
|
|
2234
|
+
if (v == 10) { sceneCubeWall(q, S, clk, col); }
|
|
2235
|
+
if (v == 11) { sceneVortex(q, S, clk, col); }
|
|
2236
|
+
if (v == 12) { sceneSticker(q, S, clk, col); }
|
|
2237
|
+
if (v == 13) { sceneRibbon(q, S, clk, col); }
|
|
2238
|
+
if (v == 14) { sceneSlab(q, S, clk, col); }
|
|
2239
|
+
if (v == 15) { sceneFrameDial(q, S, clk, col); }
|
|
2240
|
+
if (v == 16) { sceneTilt(q, S, clk, col); }
|
|
2241
|
+
if (v == 17) { sceneMarquee(q, S, clk, col); }
|
|
2242
|
+
if (v == 18) { sceneLens(q, S, clk, col); }
|
|
2243
|
+
if (v == 19) { sceneLiquid(q, S, clk, col); }
|
|
2244
|
+
if (v == 20) { scenePanelGrid(q, S, clk, col); }
|
|
2245
|
+
if (v == 21) { sceneMirror(q, S, clk, col); }
|
|
2246
|
+
}
|
|
2247
|
+
|
|
2248
|
+
vec3 panelBody(int role, vec2 q, vec2 S, float hs, vec4 clk) {
|
|
2249
|
+
if (role == 1) { return vec3(0.0); }
|
|
2250
|
+
if (role == 2) { return pSpectrum(q, S); }
|
|
2251
|
+
if (role == 3) { return pScope(q, S); }
|
|
2252
|
+
if (role == 4) { return pMeter(q, S); }
|
|
2253
|
+
if (role == 5) { return pReadout(q, S, clk); }
|
|
2254
|
+
if (role == 6) { return pCross(q, S, clk); }
|
|
2255
|
+
return pFiller(role, q, S, hs, clk);
|
|
2256
|
+
}
|
|
2257
|
+
|
|
2258
|
+
// the old boxed panel (frame "tile"): gutter inset, opaque ground, header strip, hairline frame
|
|
2259
|
+
void drawTile(int role, float hs, vec2 q, vec2 S, vec4 clk, float snap, inout vec3 col) {
|
|
2260
|
+
vec3 cov3 = vec3(0.0);
|
|
2261
|
+
bool plate = role == 8 && hs < 0.6 && plateAmount > 0.5;
|
|
2262
|
+
col = groundColor.rgb;
|
|
2263
|
+
if (role == 1 && q.y > HEAD * U && HAS_INPUT) { col = footageBody(q, S, HEAD * U, 0); }
|
|
2264
|
+
if (role == 1 && !HAS_INPUT) {
|
|
2265
|
+
vec2 dd = (q - vec2(0.0, HEAD * U));
|
|
2266
|
+
vec2 body = S - vec2(0.0, HEAD * U);
|
|
2267
|
+
cov3.x = max(hl((dd.x * body.y - dd.y * body.x) / length(body)), hl((dd.x * body.y - (body.y - dd.y) * body.x) / length(body))) * 0.35 * step(0.0, dd.y);
|
|
2268
|
+
}
|
|
2269
|
+
cov3 = max(cov3, panelBody(role, q, S, hs, clk));
|
|
2270
|
+
if (plate) {
|
|
2271
|
+
cov3.x = 0.0;
|
|
2272
|
+
cov3.y = 1.0;
|
|
2273
|
+
cov3.z = panelBody(role, q, S, hs, clk).z;
|
|
2274
|
+
} else {
|
|
2275
|
+
vec3 head = panelHead(role, hs, q, S, clk, snap);
|
|
2276
|
+
cov3.x = max(cov3.x, head.x);
|
|
2277
|
+
cov3.y = max(cov3.y, head.y);
|
|
2278
|
+
}
|
|
2279
|
+
col = mix(col, inkColor.rgb, cov3.x);
|
|
2280
|
+
col = mix(col, accentColor.rgb, cov3.y);
|
|
2281
|
+
col = mix(col, groundColor.rgb, cov3.z);
|
|
2282
|
+
}
|
|
2283
|
+
|
|
2284
|
+
// an editorial cell: optional solid fill, then the role drawn straight onto what is below it, then the frame
|
|
2285
|
+
void drawEditorial(int role, vec4 sty, vec4 aux, int ch, vec2 q, vec2 S, vec4 clk, inout vec3 col) {
|
|
2286
|
+
int v = int(sty.x + 0.5);
|
|
2287
|
+
int tone = int(sty.w + 0.5);
|
|
2288
|
+
int fill = int(sty.z + 0.5);
|
|
2289
|
+
vec3 cInk = tone == 1 ? groundColor.rgb : (tone == 2 ? accentColor.rgb : inkColor.rgb);
|
|
2290
|
+
vec3 cHot = tone == 2 ? inkColor.rgb : accentColor.rgb;
|
|
2291
|
+
if (fill == 1) { col = groundColor.rgb; }
|
|
2292
|
+
if (fill == 2) { col = inkColor.rgb; }
|
|
2293
|
+
if (fill == 3) { col = accentColor.rgb; }
|
|
2294
|
+
vec3 cov = vec3(0.0);
|
|
2295
|
+
if (role == 1) {
|
|
2296
|
+
if (HAS_INPUT) { col = footageBody(q, S, 0.0, v); }
|
|
2297
|
+
else { cov.x = max(hl((q.x * S.y - q.y * S.x) / length(S)), hl((q.x * S.y - (S.y - q.y) * S.x) / length(S))) * 0.35; }
|
|
2298
|
+
}
|
|
2299
|
+
if (role == 2) { cov = v == 0 ? pSpectrum(q, S) : pSpecHair(q, S, v); }
|
|
2300
|
+
if (role == 3) { cov = v == 0 ? pScope(q, S) : pScopeLine(q, S, v); }
|
|
2301
|
+
if (role == 4) { cov = v == 0 ? pMeter(q, S) : pMeterEd(q, S); }
|
|
2302
|
+
if (role == 5) { cov = v == 0 ? pReadout(q, S, clk) : pReadEd(q, S, v, clk); }
|
|
2303
|
+
if (role == 6) { cov = v == 0 ? pCross(q, S, clk) : pRegMark(q, S, clk); }
|
|
2304
|
+
if (role >= 7 && role <= 9) { cov = pFiller(role, q, S, role == 9 ? 0.5 : 0.0, clk); }
|
|
2305
|
+
if (role == 11) { cov = pType(q, S, v, int(aux.x + 0.5), vec3(aux.yz, aux.w), ch, clk); }
|
|
2306
|
+
if (role == 12) { cov = pRule(q, S, v); }
|
|
2307
|
+
if (role == 13) { drawTypeFx(v, aux, ch, tone, q, S, clk, cInk, cHot, col); }
|
|
2308
|
+
if (role == 14) { drawScene(v + 10 * int(aux.x + 0.5), q, S, clk, col); }
|
|
2309
|
+
cov.x = max(cov.x, frameCov(int(sty.y + 0.5), q, S));
|
|
2310
|
+
col = mix(col, cInk, cov.x);
|
|
2311
|
+
col = mix(col, cHot, cov.y);
|
|
2312
|
+
}
|
|
2313
|
+
|
|
2314
|
+
void main() {
|
|
2315
|
+
vec2 res = RENDERSIZE;
|
|
2316
|
+
U = res.y / 1080.0;
|
|
2317
|
+
HW = max(lineWidth * U, 1.0);
|
|
2318
|
+
vec2 P = vec2(vUv.x, 1.0 - vUv.y) * res;
|
|
2319
|
+
gP = P;
|
|
2320
|
+
if (sheetDebug) {
|
|
2321
|
+
vec2 cellPx = res / vec2(32.0, 18.0);
|
|
2322
|
+
vec2 gd = (fract(P / cellPx + 0.5) - 0.5) * cellPx;
|
|
2323
|
+
vec3 c = mix(groundColor.rgb, inkColor.rgb, max(hl(gd.x), hl(gd.y)) * 0.18);
|
|
2324
|
+
vec3 tm = texture(TEXTMASK, vUv).rgb;
|
|
2325
|
+
if (soloPanel > 0) { tm *= vec3(soloPanel == 1 ? 1.0 : 0.0, soloPanel == 2 ? 1.0 : 0.0, soloPanel == 3 ? 1.0 : 0.0); }
|
|
2326
|
+
c = mix(c, inkColor.rgb, tm.r);
|
|
2327
|
+
c = mix(c, accentColor.rgb, tm.g * 0.8);
|
|
2328
|
+
c = mix(c, vec3(0.25, 0.55, 1.0), tm.b * 0.8);
|
|
2329
|
+
fragColor = vec4(c, 1.0);
|
|
2330
|
+
return;
|
|
2331
|
+
}
|
|
2332
|
+
float m = margin * U;
|
|
2333
|
+
vec2 un = (res - 2.0 * m) / vec2(32.0, 18.0);
|
|
2334
|
+
UN = un;
|
|
2335
|
+
vec2 g = (P - vec2(m)) / un;
|
|
2336
|
+
vec4 clk = stClock();
|
|
2337
|
+
float snap = (layoutMode == 1 && construction && clk.x > 0.5 && float(FRAMEINDEX) - clk.y < 2.0) ? 1.0 : 0.0;
|
|
2338
|
+
float gut = gutter * U * 0.5;
|
|
2339
|
+
|
|
2340
|
+
vec3 col = groundColor.rgb;
|
|
2341
|
+
float bg = cov(length((fract(g + 0.5) - 0.5) * un) - 1.1 * U) * gridDots * 0.45;
|
|
2342
|
+
for (int k = 0; k < MAXL; k++) {
|
|
2343
|
+
vec4 r = texelFetch(state, ivec2(k, 3), 0);
|
|
2344
|
+
if (r.z < 0.5 || texelFetch(state, ivec2(k, 5), 0).y > 0.5) { continue; }
|
|
2345
|
+
for (int c = 0; c < 4; c++) {
|
|
2346
|
+
vec2 corner = vec2(m) + vec2((c & 1) == 0 ? r.x : r.z, (c & 2) == 0 ? r.y : r.w) * un;
|
|
2347
|
+
bg = max(bg, plusAt(P, corner, 6.0 * U));
|
|
2348
|
+
}
|
|
2349
|
+
}
|
|
2350
|
+
col = mix(col, inkColor.rgb, bg);
|
|
2351
|
+
for (int k = 0; k < MAXL; k++) {
|
|
2352
|
+
vec4 r = texelFetch(state, ivec2(k, 3), 0);
|
|
2353
|
+
if (r.z < 0.5) { continue; }
|
|
2354
|
+
vec4 meta = texelFetch(state, ivec2(k, 4), 0);
|
|
2355
|
+
vec4 sty = texelFetch(state, ivec2(k, 5), 0);
|
|
2356
|
+
bool tile = sty.y < 0.5;
|
|
2357
|
+
vec2 plo = vec2(m) + r.xy * un + (tile ? vec2(gut) : vec2(0.0));
|
|
2358
|
+
vec2 S = vec2(m) + r.zw * un - (tile ? vec2(gut) : vec2(0.0)) - plo;
|
|
2359
|
+
vec2 q = P - plo;
|
|
2360
|
+
if (q.x < 0.0 || q.y < 0.0 || q.x > S.x || q.y > S.y) { continue; }
|
|
2361
|
+
int role = int(meta.x + 0.5);
|
|
2362
|
+
if (tile) { drawTile(role, meta.y, q, S, clk, snap, col); }
|
|
2363
|
+
else { drawEditorial(role, sty, texelFetch(state, ivec2(k, 6), 0), int(meta.y + 0.5), q, S, clk, col); }
|
|
2364
|
+
}
|
|
2365
|
+
float n = hash12(gl_FragCoord.xy + float(FRAMEINDEX) * 13.37) - 0.5;
|
|
2366
|
+
fragColor = vec4(max(col + n * grain, vec3(0.0)), 1.0);
|
|
2367
|
+
}
|