Compare commits

..

7 commits

Author SHA1 Message Date
537bd06f93 chore: stop tracking .env and .zscripts/dev.pid
.env holds the live OVE directory API key and the database path — runtime
secrets stay on the machine and out of the repo (.gitignore already
excludes .env*); dev.pid is live process state, regenerated by the
platform on every start. Neither file is deleted from disk.
2026-11-06 05:16:59 +00:00
c1caefd543 Merge origin/main — union .gitignore: keep sandbox/tool-results/secrets exclusions, adopt remote's dist/ and !.env.example 2026-11-06 05:16:59 +00:00
zcreations_zai
35d725a5f0 chore: untrack z.ai tool artifacts and local secrets before GitLab sync 2026-11-06 04:22:38 +00:00
Z User
5f1c03db31 e0315efb-ff50-4f97-ab76-b2f751e9b03b 2026-11-06 01:14:43 +00:00
Z User
b54841fabf c123beee-6c07-4660-8af8-d2ff1f89767c 2026-11-05 23:35:41 +00:00
Z User
5451c6ccdd cc601e21-85be-4466-9dee-d6199754c813 2026-11-05 22:47:32 +00:00
Z User
f5df41dcf3 30d7a251-db3d-4ef7-9904-20d67254a59e 2026-11-05 22:25:24 +00:00
165 changed files with 1343 additions and 17637 deletions

3
.env
View file

@ -1,3 +0,0 @@
DATABASE_URL=file:/home/z/my-project/db/custom.db
OVE_DIRECTORY_URL=https://s3374dir.openvisengine.com
OVE_DIRECTORY_API_KEY=+7MkRB+hkV0UBhPqM1haTQ0f8JGKqkuXwoBTdTSAouU=

75
.gitignore vendored
View file

@ -1,22 +1,65 @@
# Dependencies
node_modules/
.pnp
.pnp.js
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# Next.js & Bun build outputs
.next/
out/
build/
dist/
# dependencies
node_modules
/.pnp
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/versions
# Environment & secrets
.env
.env.*
!.env.example
# testing
/coverage
# Debug & OS artifacts
# next.js
/.next/
/out/
# production
/build
/dist
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.DS_Store
*.pem
.pnpm-debug.log*
# env files (can opt-in for committing if needed)
.env*
!.env.example
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts
local-*
.claude
.z-ai-config
# runtime logs & local scratch (dev server output, platform pid)
*.log
dev.log
dev.out.log
test
prompt
server.log
.zscripts/dev.pid
# Skills directory
/skills/
# z.ai session artifacts (tool output dumps / e2e screenshots) -- not project content
/tool-results/
# local secrets -- stay on this machine only, never push
/secrets/

View file

@ -1 +0,0 @@
1198

Binary file not shown.

View file

@ -1,49 +0,0 @@
# Netscape HTTP Cookie File
# This file is generated by yt-dlp. Do not edit.
www.google.com FALSE /recaptcha TRUE 1808687573 _GRECAPTCHA 09AKhCRwiT1-eLwOwaLcFwkJlDCOvrfctf5tsleUgIESjud7kzj-VQQ1lebmDMm57NTJHMlFVl3pt8HEhKvP-HrKM
.youtube.com TRUE / TRUE 1808809698 __Secure-YNID CvABCAUSogEBDB6PDNM4lSTL1fNjvHhlJr6rUsMazeqGK4GnVIGw8Y9-1IaaTzG4xMYqDTp7ZQDCiOU4ja7PJFkLs5dyGICIh4mtR1-7hYM0p6tgJLIJS59qkDH2n4kctfCpEU8yIPqRRFbnf_ASyhnp358K7yiogbiukJK2GCIHcBwD3EPJpLjqSXNvW43WZ1JGO34LV1fLDuOkYdVSAyNQ1jcYqGsFkqIoBTJFARxY9Wp8CqmEo-J1q5StRZXXkrwaf3R8rL5BNxRjv52YkTuQF9qrnbw3B01oxyNluUkk8LkcIHPTrFA7VKfXgEBNaM8C
.youtube.com TRUE / TRUE 0 YSC wJcQpiA7MFI
.youtube.com TRUE / TRUE 1808809757 VISITOR_INFO1_LIVE xwM2uudtLPY
.youtube.com TRUE / TRUE 1808809757 VISITOR_PRIVACY_METADATA CgJVUxIEGgAgEg%3D%3D
.youtube.com TRUE / FALSE 0 PREF f4=4000000&f6=40000000&tz=UTC&hl=en
.youtube.com TRUE / TRUE 1824671657 __Secure-1PSIDTS sidts-CjQBkldj_8-zeoTpyxBBXFMCgRR9qjPtqXfR-AAPv8VdkpM_1x1QaswtzUbaALHmihy8PR6VEAA
.youtube.com TRUE / TRUE 1824671657 __Secure-3PSIDTS sidts-CjQBkldj_8-zeoTpyxBBXFMCgRR9qjPtqXfR-AAPv8VdkpM_1x1QaswtzUbaALHmihy8PR6VEAA
.youtube.com TRUE / FALSE 1827695657 HSID AHlWy3lOE0sa6Py0E
.youtube.com TRUE / TRUE 1827695657 SSID AUIZ5QzBYjVQUn6tB
.youtube.com TRUE / FALSE 1827695657 APISID PrsWDyK9QoAfY-Fv/A_DU6Ntj541EzC59t
.youtube.com TRUE / TRUE 1827695657 SAPISID qShyTwi4D6RAWqup/A9cVfuudF_AUU8fCi
.youtube.com TRUE / TRUE 1827695657 __Secure-1PAPISID qShyTwi4D6RAWqup/A9cVfuudF_AUU8fCi
.youtube.com TRUE / TRUE 1827695657 __Secure-3PAPISID qShyTwi4D6RAWqup/A9cVfuudF_AUU8fCi
.youtube.com TRUE / FALSE 1827695657 SID g.a000EAmiU2hM7FuD6v63bTop3LlKx764pFf1t4tnmCs-R8ZiKwUtjiMkG7YgtJw5b2BBETp3ZQACgYKAUcSARcSFQHGX2MiFNswjWtYxSdRiBvSpq9YRxoVAUF8yKqHjReqCyQLK_r14tW462do0076
.youtube.com TRUE / TRUE 1827695657 __Secure-1PSID g.a000EAmiU2hM7FuD6v63bTop3LlKx764pFf1t4tnmCs-R8ZiKwUt-OO1YThhWv8hLVazSJioKAACgYKAf8SARcSFQHGX2Mi7vLX1X-44U7MbuYdvaP85RoVAUF8yKrCkxk0H23OSKpdpS4Idwfp0076
.youtube.com TRUE / TRUE 1827695657 __Secure-3PSID g.a000EAmiU2hM7FuD6v63bTop3LlKx764pFf1t4tnmCs-R8ZiKwUt-5dt3UN1zw2Vbd0ITxZ-RQACgYKAT8SARcSFQHGX2Miyerzf0aNf4CZ1gHaVcOvJRoVAUF8yKpZFiPbafwxuLK3XngvGkL80076
.youtube.com TRUE / TRUE 1827695657 LOGIN_INFO AFmmF2swRgIhANuOmQ72_1tpBj__Z89LskTVp9i130w2AnoFIeQ5GFw2AiEA99-nsLcdID44W7O0ha1XNs3kBGM9Pj1H2jrIWVOJtaM:QUQ3MjNmd2ZLb2g2Mi1pSi1DMVpHOUZuMTRUY1ZDS2xVQ2Q2Q3p6OF9vQVdKQ054OEJyd3dfdjVvdWhURzUyZFZRcExVbG04RWpMY21LUDV4OENhYlU3MnJKZV9lN3lGYzZSekpLWmJYZ0d0ZTA3b3dzR1Q0bEhZQmpISDV5MWRlZy1rcVZNRnI0UHl2YmE4MG9OeXhjNHdwWExOUGxTMTh3
.youtube.com TRUE / FALSE 1824793757 SIDCC APD_SKGFb6CzpAR5B4SQ5RYAOPYcbkVN3Z8WfzBrTgrxPLk2NYzxEYjXPcv0wiBT0aS5V47e
.youtube.com TRUE / TRUE 1824793757 __Secure-1PSIDCC APD_SKEuV2_zW-UZAToXz6oqw0lD8JzfM3Iyw4UAwRFVChaTOtJqmtH5JWx8nzCKWA9ZZm0pmQ
.youtube.com TRUE / TRUE 1824793757 __Secure-3PSIDCC APD_SKFWJyPSvgrzM4pyuJwCIWvE1wXocR3mi5wjmltaSdqnFj9BXIx4YsQnFCO6RMJe-lQhQQ
.youtube.com TRUE / TRUE 1808809698 __Secure-ROLLOUT_TOKEN CKq_r_Sk4IqwXxDlhvalkduXAxjFuIbB1d6XAw%3D%3D
.youtube.com TRUE / TRUE 1856208374 __Secure-YT_TVFAS t=498092&s=2
.youtube.com TRUE / TRUE 1808688374 DEVICE_INFO ChxOemN3TVRRMk1UazVPVFkwTVRRek5USXdNQT09EPathNcGGOKthNcG
.youtube.com TRUE /tv TRUE 1825968374 __Secure-YT_DERP CL211MHsAw%3D%3D
accounts.google.com FALSE / TRUE 1827695629 __Host-GAPS 1:0bBQMEQYLfI-4i87W5sPl2-rwRCMAWDpibPT0RQX25Ax8PoQN7jB6BAHp2GwEpIjNcMgOxXFBNdF6K4_vtRAbowFRgpkmA:52xBJrI_Z8BTd8dv
accounts.google.com FALSE / TRUE 1795723741 OTZ 8847129_76_80_104160_76_446820
accounts.google.com FALSE / TRUE 1827695657 LSID s.youtube:g.a000EAmiU7I0LBJQ9_IHxDfrsX9jO_gwDhI1oTR_ms40z3BgSsg3AWRpNZCGhA_kasTpATnOJQACgYKAbgSARcSFQHGX2Miq8IIUQluFbKEs_pBJCyZTxoVAUF8yKqHDmmhHNl2x2myYlW-AESI0076
accounts.google.com FALSE / TRUE 1827695657 __Host-1PLSID s.youtube:g.a000EAmiU7I0LBJQ9_IHxDfrsX9jO_gwDhI1oTR_ms40z3BgSsg3BRd7bBsDLNhEqSDuRpabYgACgYKATASARcSFQHGX2MiqP1cqrb_2zyytLYEdSz6_RoVAUF8yKqWz5CnyOe2YDSEAgBDfEyN0076
accounts.google.com FALSE / TRUE 1827695657 __Host-3PLSID s.youtube:g.a000EAmiU7I0LBJQ9_IHxDfrsX9jO_gwDhI1oTR_ms40z3BgSsg3ygc1yL3ad8eqjqFqou3nOgACgYKAYgSARcSFQHGX2Miio-7XF4Ixdh8OiCXAn6OShoVAUF8yKqKMxTErwEagIKXiwg1qB7-0076
accounts.google.com FALSE / TRUE 1827695629 ACCOUNT_CHOOSER AFx_qI7Td1SxByP4v9j-bilk4PQMOT-H0XQbziFNmveYVwWyyvOLuamF3OBpbWmGTZ1E0AAnKV7P_HkWGuMOVV8LMpJfBa41uwzpnaiDjFTu7vpsDWpJ3luNRokBVolDLMNsiw1NpnETQ5aTWY8VYDe2OJeT-5kXeQgVL8WHc7-w4hb8YQVi2EM
.google.com TRUE / TRUE 1808942959 NID CsMCCAES9QEBOxGDSEw5ZNTUJ8oyGjiLG6tJvqph6S_TNQrpbDO2JKCuQ1GbQ2HeHYJZpg5DwuarhAlOHDyhHEpOCw-KLWAdk7CUEH1ywdnnZCq6pT7v_gzKyMLdAfTTpISS4pdKis7pSmwQJ7wkyd9SwaZvFwgXXHyRufVvwGS7DEYinDM2QiZKastEaemeZ3uafFQUJOqPPm9xUPo9A8evqrXeX2u_WH3GKuzLv00vIVCgTHp89n8CPYW_ZoUAUkAatS1yiXWCHnUbmsIcGOFvwJyh15bIfZSWWJy3g6NurLtsSgGMSCmM4g_vzr8R5E104WqT6vlRERe9nigBMkUB0qwHz3PwnbA_0m1Ia0mrG7DrMyc4TPe1rd4r701mtL1r6VYeNrIP7MlhSYXD5dMaoLDJyek9UJNtO9yAVcmRr3b9www
.google.com TRUE / FALSE 1827695629 SID g.a000EAmiU2hM7FuD6v63bTop3LlKx764pFf1t4tnmCs-R8ZiKwUtjiMkG7YgtJw5b2BBETp3ZQACgYKAUcSARcSFQHGX2MiFNswjWtYxSdRiBvSpq9YRxoVAUF8yKqHjReqCyQLK_r14tW462do0076
.google.com TRUE / TRUE 1827695629 __Secure-1PSID g.a000EAmiU2hM7FuD6v63bTop3LlKx764pFf1t4tnmCs-R8ZiKwUt-OO1YThhWv8hLVazSJioKAACgYKAf8SARcSFQHGX2Mi7vLX1X-44U7MbuYdvaP85RoVAUF8yKrCkxk0H23OSKpdpS4Idwfp0076
.google.com TRUE / TRUE 1827695629 __Secure-3PSID g.a000EAmiU2hM7FuD6v63bTop3LlKx764pFf1t4tnmCs-R8ZiKwUt-5dt3UN1zw2Vbd0ITxZ-RQACgYKAT8SARcSFQHGX2Miyerzf0aNf4CZ1gHaVcOvJRoVAUF8yKpZFiPbafwxuLK3XngvGkL80076
.google.com TRUE / FALSE 1827695629 HSID AvG4uuuFtl-8-qhUH
.google.com TRUE / TRUE 1827695629 SSID A_oeh4tFJB7iymCHx
.google.com TRUE / FALSE 1827695629 APISID PrsWDyK9QoAfY-Fv/A_DU6Ntj541EzC59t
.google.com TRUE / TRUE 1827695629 SAPISID qShyTwi4D6RAWqup/A9cVfuudF_AUU8fCi
.google.com TRUE / TRUE 1827695629 __Secure-1PAPISID qShyTwi4D6RAWqup/A9cVfuudF_AUU8fCi
.google.com TRUE / TRUE 1827695629 __Secure-3PAPISID qShyTwi4D6RAWqup/A9cVfuudF_AUU8fCi
.google.com TRUE / FALSE 1824671657 SIDCC APD_SKH6ArSxVZJ-tZd13uSOlQxmI6fFkjfQ871Qwbtszlfjhq5LNC3HLR69O8hy1SiokjE29w
.google.com TRUE / TRUE 1824671657 __Secure-1PSIDCC APD_SKHHaq35TM1Xz_P1bEspG8lIaoGEN3R0xN2vKFb4ArQ1yHTMCsbU3vfg2YVZd0C53FKZUA
.google.com TRUE / TRUE 1824671657 __Secure-3PSIDCC APD_SKEr9tfGBVIpEzBSuQKMLPZEMm60YNuNpExMCMvB5kEvzSOSTLQ65r-ty64yKNyawYpM7A
workspace.google.com FALSE / TRUE 1795723760 OTZ 8847129_76_80_104160_76_446820
gds.google.com FALSE / TRUE 1795727630 OTZ 8847194_76_80_104160_76_446820

View file

0
src/app/api/ove-directory/scripts/[id]/route.ts Normal file → Executable file
View file

0
src/app/api/ove-directory/scripts/route.ts Normal file → Executable file
View file

0
src/app/api/ove-directory/status/route.ts Normal file → Executable file
View file

0
src/components/ava/directory-tab.tsx Normal file → Executable file
View file

View file

@ -4,6 +4,7 @@
'use client'
import type { ReactNode } from 'react'
import { BLEND_SPECS, BLEND_GROUP_LABELS, type BlendGroup } from '@/lib/ava/blend'
const FRAME_VARS: [string, string][] = [
['n', 'point count (4–4096, default 400 -- set in [init] or [frame])'],
@ -22,7 +23,8 @@ const FRAME_VARS: [string, string][] = [
['beatage', 'seconds since the last beat (0 on the beat frame) -- exp(-beatage*4) is a kick envelope'],
['w / h', 'canvas size in pixels'],
['aspect', 'canvas width / height -- divide x by it for perfect circles'],
['persist', 'motion-trail persistence 0..0.98 (writable per frame)'],
['persist', 'motion-trail persistence 0..1, writable per frame -- 1 = the framebuffer never fades (old content then leaves only through a bg* transform or a blend: replace repaint)'],
['blend', 'per-frame override of the blend: header -- set it to a mode\'s number from the Blend modes table below (1 = normal, 2 = additive, 3 = replace, 6 = subtract, ...); read after [frame]/[beat], before drawing'],
['bgrot', 'background spin in radians per frame -- + clockwise, - counter-clockwise; 0 = off (set in [init] / [frame] / [beat]; persists like any variable)'],
['bgx / bgy', 'background drift per frame, the -1..1 screen convention (y is up) -- slide the whole picture up, down, left or right'],
['bgzoom', 'background scale per frame -- below 1 draw-in (shrinks toward the center), above 1 blow-out (expands); 1 = off'],
@ -157,6 +159,34 @@ export function HelpPanel() {
</div>
</HelpSection>
<HelpSection title="Blend modes (blend:)">
<p className="mb-2 text-[11px] leading-relaxed text-zinc-400">
The <span className="font-mono text-emerald-400/90">blend:</span> header picks how fresh strokes mix with what is
already on screen (base = the picture, blend = the stroke). Names are case- and separator-insensitive —{' '}
<span className="font-mono">color burn</span> = <span className="font-mono">colorburn</span>. The{' '}
<span className="font-mono text-emerald-400/90">blend</span> variable can switch the mode per frame by its number.
</p>
<div className="space-y-3">
{(
['core', 'darken', 'lighten', 'contrast', 'invert', 'component', 'mask'] as BlendGroup[]
).map((g) => (
<div key={g}>
<p className="mb-1 text-[10px] font-semibold uppercase tracking-[0.12em] text-zinc-500">
{BLEND_GROUP_LABELS[g]}
</p>
<HelpTable
rows={BLEND_SPECS.map((s, i) => [s, i] as const)
.filter(([s]) => s.group === g)
.map(([s, i]) => [
`${i + 1} · ${s.key}`,
s.aliases?.length ? `${s.note} [also: ${s.aliases.join(', ')}]` : s.note,
])}
/>
</div>
))}
</div>
</HelpSection>
<HelpSection title="File format (.ava)">
<p className="mb-2 text-[11px] leading-relaxed text-zinc-400">
A plain-text file: optional header keys before the first section, then any of the four sections in any order.
@ -167,8 +197,8 @@ name: My Visualization
author: you
description: shown in the preset list
mode: lines # lines | dots | solid
blend: additive # additive | alpha
persist: 0.85 # trail persistence 0..0.98
blend: additive # any of the 41 keywords -- see the Blend modes table
persist: 0.85 # trail persistence 0..1 (1 = never fades)
linewidth: 2
[init] # runs once on load

0
src/components/ava/upload-dialog.tsx Normal file → Executable file
View file

244
src/lib/ava/blend-gpu.ts Executable file
View file

@ -0,0 +1,244 @@
// AVA — WebGL blend compositor (v7.15).
//
// Implements the blend keywords Canvas2D has no composite operator for
// (21 of the 41): dissolve, linear burn, darker/lighter color, vivid /
// linear / pin light, hard mix, a TRUE clamped subtract, divide, average,
// negation, phoenix, grain extract/merge, reflect, glow, and the four
// After Effects masks (stencil / silhouette, luma + alpha).
//
// Per frame the engine draws the stroke passes onto a scratch canvas
// (source-over, so the two-pass glow keeps its usual tuning), then:
// 1. uploads the live canvas (backdrop) and the scratch (stroke layer)
// as premultiplied textures,
// 2. renders one fullscreen quad with the mode's formula,
// 3. the engine copies the result back with composite 'copy'.
//
// Per pixel: a = straight backdrop color, b = straight stroke color,
// c = the stroke's coverage (scratch alpha, AA included). The standard
// tail is out = mix(a, modeRGB, c) at opacity mix(dst.a, 1, c) —
// outside the strokes the backdrop passes through EXACTLY, so the
// 'copy' back is lossless. The four masks scale the backdrop instead,
// dissolve speckles at full intensity (re-seeded from uFrame so the
// grain animates), and everything is written premultiplied (the WebGL
// context is premultipliedAlpha: true).
//
// Formulas per the sources documented in blend.ts. Fallbacks: if WebGL
// is unavailable the engine composites each gpu mode with its nearest
// native operator (spec.fallbackOp) — see engine.ts gpuEnsure.
const VERT_SRC = `
attribute vec2 aPos;
varying vec2 vUV;
void main() {
// texture t=0 is the canvas's TOP row; flip so the quad renders upright
vUV = vec2(aPos.x * 0.5 + 0.5, 0.5 - aPos.y * 0.5);
gl_Position = vec4(aPos, 0.0, 1.0);
}
`
const FRAG_SRC = `
precision highp float;
varying vec2 vUV;
uniform sampler2D uDst;
uniform sampler2D uSrc;
uniform int uMode;
uniform float uFrame;
float lum(vec3 c) { return dot(c, vec3(0.299, 0.587, 0.114)); }
float hash(vec2 p) {
// Hoskins-style hash: no large-argument sin (which skews badly on some
// GPU stacks -- measured in the v7.15 E2E: the classic sin-hash spent
// 95% of its values below 0.51, making dissolve nearly deterministic).
vec3 p3 = fract(vec3(p.xyx) * 0.1031);
p3 += dot(p3, p3.yzx + 33.33);
return fract((p3.x + p3.y) * p3.z);
}
vec3 vivid(vec3 a, vec3 b) {
vec3 burn = max(vec3(1.0) - (vec3(1.0) - a) / max(vec3(2.0) * b, vec3(1e-3)), vec3(0.0));
vec3 dodge = min(a / max(vec3(2.0) - vec3(2.0) * b, vec3(1e-3)), vec3(1.0));
return mix(burn, dodge, step(vec3(0.5), b));
}
void main() {
vec4 D = texture2D(uDst, vUV); // backdrop, premultiplied upload
vec4 S = texture2D(uSrc, vUV); // stroke layer, premultiplied upload
float c = S.a; // stroke coverage 0..1 (AA included)
vec3 a = D.a > 0.0 ? D.rgb / max(D.a, 1e-4) : vec3(0.0); // straight backdrop
vec3 b = c > 0.0 ? S.rgb / max(c, 1e-4) : vec3(0.0); // straight stroke
// -- special-tail modes ------------------------------------------------
if (uMode == 1) { // dissolve: stochastic full-intensity speckle
// the +uFrame offset re-rolls the grain every frame (animated speckle)
gl_FragColor = hash(vUV * 997.0 + vec2(uFrame * 0.618, uFrame * 0.317)) < c ? vec4(b, 1.0) : D;
return;
}
if (uMode == 18) { // stencil luma: the stroke's brightness masks
float m = mix(1.0, lum(b), c);
gl_FragColor = vec4(D.rgb * m, D.a * m);
return;
}
if (uMode == 19) { // silhouette luma
float m = mix(1.0, 1.0 - lum(b), c);
gl_FragColor = vec4(D.rgb * m, D.a * m);
return;
}
if (uMode == 20) { // stencil alpha: the stroke's own opacity masks
float m = mix(1.0, S.a, c);
gl_FragColor = vec4(D.rgb * m, D.a * m);
return;
}
if (uMode == 21) { // silhouette alpha
float m = mix(1.0, 1.0 - S.a, c);
gl_FragColor = vec4(D.rgb * m, D.a * m);
return;
}
// -- separable families --------------------------------------------------
vec3 R = a;
if (uMode == 2) R = max(a + b - 1.0, 0.0); // linear burn
else if (uMode == 3) R = (lum(b) < lum(a)) ? b : a; // darker color
else if (uMode == 4) R = (lum(b) > lum(a)) ? b : a; // lighter color
else if (uMode == 5) R = vivid(a, b); // vivid light
else if (uMode == 6) R = clamp(a + 2.0 * b - 1.0, 0.0, 1.0); // linear light
else if (uMode == 7) { // pin light
vec3 lo = min(a, vec3(2.0) * b);
vec3 hi = max(a, vec3(2.0) * b - vec3(1.0));
R = mix(lo, hi, step(vec3(0.5), b));
}
else if (uMode == 8) R = step(vec3(0.5), vivid(a, b)); // hard mix
else if (uMode == 9) R = max(a - b, 0.0); // subtract (true)
else if (uMode == 10) R = min(a / max(b, vec3(1e-3)), vec3(1.0)); // divide
else if (uMode == 11) R = (a + b) * 0.5; // average
else if (uMode == 12) R = vec3(1.0) - abs(a - b); // negation
else if (uMode == 13) R = min(a * a / max(vec3(1.0) - b, vec3(1e-3)), vec3(1.0)); // reflect
else if (uMode == 14) R = min(b * b / max(vec3(1.0) - a, vec3(1e-3)), vec3(1.0)); // glow
else if (uMode == 15) R = min(a, b) - max(a, b) + vec3(1.0); // phoenix
else if (uMode == 16) R = clamp(a - b + 0.5, 0.0, 1.0); // grain extract
else if (uMode == 17) R = clamp(a + b - 0.5, 0.0, 1.0); // grain merge
// -- standard tail: coverage-weighted, written premultiplied ----------------
float outA = mix(D.a, 1.0, c);
gl_FragColor = vec4(mix(a, R, c) * outA, outA);
}
`
function compileShader(gl: WebGLRenderingContext, kind: number, src: string): WebGLShader | null {
const sh = gl.createShader(kind)
if (!sh) return null
gl.shaderSource(sh, src)
gl.compileShader(sh)
if (!gl.getShaderParameter(sh, gl.COMPILE_STATUS)) {
return null
}
return sh
}
export class BlendCompositor {
readonly canvas: HTMLCanvasElement
/** true once WebGL is proven unavailable — callers fall back per mode */
failed = false
private gl: WebGLRenderingContext | null = null
private prog: WebGLProgram | null = null
private quad: WebGLBuffer | null = null
private texDst: WebGLTexture | null = null
private texSrc: WebGLTexture | null = null
private uDst = 0
private uSrc = 0
private uMode = 0
private uFrame = 0
constructor() {
this.canvas = document.createElement('canvas')
}
/** (Re)create the context/program if needed; false = give up (once). */
ensure(w: number, h: number): boolean {
if (this.failed) return false
if (!this.gl) {
const gl = this.canvas.getContext('webgl', {
alpha: true,
premultipliedAlpha: true,
preserveDrawingBuffer: true,
}) as WebGLRenderingContext | null
if (!gl) {
this.failed = true
return false
}
this.gl = gl
if (!this.build(gl)) {
this.failed = true
return false
}
}
if (this.canvas.width !== w || this.canvas.height !== h) {
this.canvas.width = w
this.canvas.height = h
}
return true
}
private build(gl: WebGLRenderingContext): boolean {
const vs = compileShader(gl, gl.VERTEX_SHADER, VERT_SRC)
const fs = compileShader(gl, gl.FRAGMENT_SHADER, FRAG_SRC)
if (!vs || !fs) return false
const prog = gl.createProgram()
if (!prog) return false
gl.attachShader(prog, vs)
gl.attachShader(prog, fs)
gl.linkProgram(prog)
if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) return false
this.prog = prog
// fullscreen quad
this.quad = gl.createBuffer()
gl.bindBuffer(gl.ARRAY_BUFFER, this.quad)
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]), gl.STATIC_DRAW)
const aPos = gl.getAttribLocation(prog, 'aPos')
gl.enableVertexAttribArray(aPos)
gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 0, 0)
// textures (created once; texImage2D re-specifies them per frame)
for (const which of [0, 1]) {
const tex = gl.createTexture()
gl.activeTexture(which === 0 ? gl.TEXTURE0 : gl.TEXTURE1)
gl.bindTexture(gl.TEXTURE_2D, tex)
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
if (which === 0) this.texDst = tex
else this.texSrc = tex
}
// canvas uploads arrive premultiplied; do the un/premultiply math in the shader
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true)
this.uDst = gl.getUniformLocation(prog, 'uDst')
this.uSrc = gl.getUniformLocation(prog, 'uSrc')
this.uMode = gl.getUniformLocation(prog, 'uMode')
this.uFrame = gl.getUniformLocation(prog, 'uFrame')
return true
}
/** Render one blended frame into this.canvas. The engine then copies it
* back onto the live canvas with composite 'copy'. */
blend(dst: HTMLCanvasElement, src: HTMLCanvasElement, mode: number, frame: number): void {
const gl = this.gl
const prog = this.prog
if (!gl || !prog) return
gl.viewport(0, 0, this.canvas.width, this.canvas.height)
gl.useProgram(prog)
gl.activeTexture(gl.TEXTURE0)
gl.bindTexture(gl.TEXTURE_2D, this.texDst)
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, dst)
gl.uniform1i(this.uDst, 0)
gl.activeTexture(gl.TEXTURE1)
gl.bindTexture(gl.TEXTURE_2D, this.texSrc)
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, src)
gl.uniform1i(this.uSrc, 1)
gl.uniform1i(this.uMode, mode)
gl.uniform1f(this.uFrame, frame)
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4)
}
}

507
src/lib/ava/blend.ts Executable file
View file

@ -0,0 +1,507 @@
// AVA — blend mode registry (v7.15).
//
// The single source of truth for every `blend:` keyword. The v7.14.1 set
// (additive | alpha | multiply | screen | subtract | replace) grew into a
// 41-mode collection covering every compositing family in the request
// list: the full Photoshop set, the GIMP grain pair, the After Effects
// stencil/silhouette masks, Apple/CSS plus-lighter/plus-darker and the
// Pegtop exotica (negation, phoenix, reflect, glow).
//
// A mode is implemented one of two ways:
// 'native' — a direct Canvas2D composite operation. Canvas2D implements
// the W3C compositing formulas (soft light is the spec's
// piecewise D(x) version), so these are exact and cost one
// operator switch. 'replace' keeps its v7.14.1 semantics:
// source-over with the CORE pass at FULL alpha.
// 'gpu' — Canvas2D has no operator for it, so the engine draws the
// stroke passes onto a scratch canvas and the WebGL
// compositor (blend-gpu.ts) applies the per-pixel formula.
// On browsers without WebGL each mode falls back to its
// nearest native operator (fallbackOp).
//
// Formula sources: W3C Compositing and Blending Level 1 (the 12 separable
// + 4 HSL transfer modes), the glsl-blend collection / Pegtop blend modes
// (phoenix = min - max + 1, verified against four independent sources;
// hard mix = vivid light thresholded at 0.5; grain extract/merge from
// GIMP). Notable equivalence, kept as two keywords because applications
// list both: negation (Pegtop, "a softer Difference") and phoenix
// ("combines Darken and Lighten") are algebraically the same curve,
// 1 - |a - b| = min(a,b) - max(a,b) + 1.
//
// Name matching is case- and separator-insensitive: normalize() strips
// everything but a-z0-9, so 'Color Burn', 'color-burn', 'COLORBURN' and
// 'color_burn' all resolve to 'colorburn'.
export type BlendImpl = 'native' | 'gpu'
export type BlendGroup =
| 'core'
| 'darken'
| 'lighten'
| 'contrast'
| 'invert'
| 'component'
| 'mask'
export const BLEND_GROUP_LABELS: Record<BlendGroup, string> = {
core: 'Core compositing',
darken: 'Darken family',
lighten: 'Lighten family',
contrast: 'Contrast family',
invert: 'Difference & arithmetic',
component: 'HSL component transfer',
mask: 'Dissolve & masks',
}
export interface BlendSpec {
/** canonical keyword — lowercase, no separators */
key: string
/** alternate spellings, normalized the same way */
aliases?: string[]
impl: BlendImpl
/** native path: the Canvas2D composite operation */
op?: GlobalCompositeOperation
/** native 'replace' quirk: the core pass runs at FULL alpha */
fullAlphaCore?: boolean
/** gpu path: shader mode id (blend-gpu.ts) */
gpuId?: number
/** gpu path: composite op used when WebGL is unavailable */
fallbackOp: GlobalCompositeOperation
/** pretty name for docs */
label: string
/** help-panel group */
group: BlendGroup
/** one-line description (base = the picture, blend = the stroke) */
note: string
}
export const BLEND_SPECS: BlendSpec[] = [
// ── core compositing ────────────────────────────────────────────────────
{
key: 'normal',
aliases: ['alpha', 'standard', 'sourceover'],
impl: 'native',
op: 'source-over',
fallbackOp: 'source-over',
label: 'Normal',
group: 'core',
note: 'the top layer covers what is underneath; stroke opacity decides how much shows through',
},
{
key: 'additive',
aliases: ['lineardodge', 'add', 'pluslighter'],
impl: 'native',
op: 'lighter',
fallbackOp: 'lighter',
label: 'Additive (Linear Dodge, Add)',
group: 'core',
note: 'base + blend, capped at white -- adds light directly; the classic glow mode (fire, lens flares, feedback blooms)',
},
{
key: 'replace',
impl: 'native',
op: 'source-over',
fullAlphaCore: true,
fallbackOp: 'source-over',
label: 'Replace',
group: 'core',
note: 'fresh strokes overwrite the pixels they cover, no mixing -- with persist 1 the center repaints while bg* transforms carry the old color away',
},
{
key: 'multiply',
impl: 'native',
op: 'multiply',
fallbackOp: 'multiply',
label: 'Multiply',
group: 'core',
note: 'stacked ink or transparencies: white leaves the picture untouched, black stays black',
},
{
key: 'screen',
impl: 'native',
op: 'screen',
fallbackOp: 'screen',
label: 'Screen',
group: 'core',
note: 'overlapping projected light: black leaves the picture untouched, white stays white',
},
{
key: 'subtract',
aliases: ['subtractive'],
impl: 'gpu',
gpuId: 9,
fallbackOp: 'difference',
label: 'Subtract',
group: 'core',
note: 'base - blend floored at black -- eats the picture where strokes pass (a true clamped subtract; until 7.14.1 this was approximated with difference)',
},
{
key: 'behind',
aliases: ['destinationover', 'under'],
impl: 'native',
op: 'destination-over',
fallbackOp: 'destination-over',
label: 'Behind',
group: 'core',
note: 'paints only on transparent areas -- strokes slip UNDER existing art (pair it with clear)',
},
{
key: 'clear',
aliases: ['erase'],
impl: 'native',
op: 'clear',
fallbackOp: 'clear',
label: 'Clear',
group: 'core',
note: 'erases pixels to transparent along the stroke -- an eraser pen; the hole can later be painted behind',
},
// ── darken family ───────────────────────────────────────────────────────
{
key: 'darken',
impl: 'native',
op: 'darken',
fallbackOp: 'darken',
label: 'Darken',
group: 'darken',
note: 'keeps the darker of base and blend, channel by channel',
},
{
key: 'colorburn',
aliases: ['burn'],
impl: 'native',
op: 'color-burn',
fallbackOp: 'color-burn',
label: 'Color Burn',
group: 'darken',
note: 'darkens the base by raising contrast -- rich, saturated darks',
},
{
key: 'linearburn',
aliases: ['plusdarker'],
impl: 'gpu',
gpuId: 2,
fallbackOp: 'multiply',
label: 'Linear Burn',
group: 'darken',
note: 'base + blend - 1: darkens by lowering brightness; stronger than multiply',
},
{
key: 'darkercolor',
impl: 'gpu',
gpuId: 3,
fallbackOp: 'darken',
label: 'Darker Color',
group: 'darken',
note: 'compares whole colors and keeps the darker one -- no channel cross-talk',
},
// ── lighten family ──────────────────────────────────────────────────────
{
key: 'lighten',
impl: 'native',
op: 'lighten',
fallbackOp: 'lighten',
label: 'Lighten',
group: 'lighten',
note: 'keeps the lighter of base and blend, channel by channel',
},
{
key: 'colordodge',
impl: 'native',
op: 'color-dodge',
fallbackOp: 'color-dodge',
label: 'Color Dodge',
group: 'lighten',
note: 'brightens the base by lowering contrast -- intense highlights',
},
{
key: 'lightercolor',
impl: 'gpu',
gpuId: 4,
fallbackOp: 'lighten',
label: 'Lighter Color',
group: 'lighten',
note: 'compares whole colors and keeps the lighter one',
},
// ── contrast family ─────────────────────────────────────────────────────
{
key: 'overlay',
impl: 'native',
op: 'overlay',
fallbackOp: 'overlay',
label: 'Overlay',
group: 'contrast',
note: 'multiplies the dark parts of the base, screens the light parts',
},
{
key: 'softlight',
impl: 'native',
op: 'soft-light',
fallbackOp: 'soft-light',
label: 'Soft Light',
group: 'contrast',
note: 'a gentler overlay, like a diffused spotlight (the W3C formula)',
},
{
key: 'hardlight',
impl: 'native',
op: 'hard-light',
fallbackOp: 'hard-light',
label: 'Hard Light',
group: 'contrast',
note: 'overlay with the layers swapped -- the top layer picks multiply or screen',
},
{
key: 'vividlight',
impl: 'gpu',
gpuId: 5,
fallbackOp: 'color-burn',
label: 'Vivid Light',
group: 'contrast',
note: 'color burn for dark strokes, color dodge for light ones',
},
{
key: 'linearlight',
impl: 'gpu',
gpuId: 6,
fallbackOp: 'overlay',
label: 'Linear Light',
group: 'contrast',
note: 'linear burn for dark strokes, linear dodge for light ones',
},
{
key: 'pinlight',
impl: 'gpu',
gpuId: 7,
fallbackOp: 'hard-light',
label: 'Pin Light',
group: 'contrast',
note: 'darken for dark strokes, lighten for light ones',
},
{
key: 'hardmix',
impl: 'gpu',
gpuId: 8,
fallbackOp: 'overlay',
label: 'Hard Mix',
group: 'contrast',
note: 'pushes every channel to 0 or 1 -- a posterized look (vivid light thresholded at 0.5)',
},
// ── difference & arithmetic ─────────────────────────────────────────────
{
key: 'difference',
aliases: ['diff'],
impl: 'native',
op: 'difference',
fallbackOp: 'difference',
label: 'Difference',
group: 'invert',
note: '|base - blend|: identical colors turn black -- useful for lining layers up',
},
{
key: 'exclusion',
impl: 'native',
op: 'exclusion',
fallbackOp: 'exclusion',
label: 'Exclusion',
group: 'invert',
note: 'like difference but with lower contrast',
},
{
key: 'negation',
impl: 'gpu',
gpuId: 12,
fallbackOp: 'difference',
label: 'Negation',
group: 'invert',
note: 'a softer, inverted difference (Pegtop) -- algebraically the same curve as phoenix',
},
{
key: 'phoenix',
impl: 'gpu',
gpuId: 15,
fallbackOp: 'difference',
label: 'Phoenix',
group: 'invert',
note: 'min - max + 1: combines Darken and Lighten in one curve',
},
{
key: 'divide',
impl: 'gpu',
gpuId: 10,
fallbackOp: 'screen',
label: 'Divide',
group: 'invert',
note: 'base / blend: brightens the image and lifts color casts',
},
{
key: 'average',
impl: 'gpu',
gpuId: 11,
fallbackOp: 'source-over',
label: 'Average',
group: 'invert',
note: 'the mean of the two layers',
},
{
key: 'grainextract',
impl: 'gpu',
gpuId: 16,
fallbackOp: 'difference',
label: 'Grain Extract',
group: 'invert',
note: 'GIMP: pulls texture out of a layer (base - blend + 0.5)',
},
{
key: 'grainmerge',
impl: 'gpu',
gpuId: 17,
fallbackOp: 'screen',
label: 'Grain Merge',
group: 'invert',
note: 'GIMP: puts the texture back (base + blend - 0.5)',
},
{
key: 'reflect',
impl: 'gpu',
gpuId: 13,
fallbackOp: 'screen',
label: 'Reflect',
group: 'invert',
note: 'strong lighting: base^2 / (1 - blend)',
},
{
key: 'glow',
impl: 'gpu',
gpuId: 14,
fallbackOp: 'lighter',
label: 'Glow',
group: 'invert',
note: 'reflect with the layers swapped: blend^2 / (1 - base)',
},
// ── HSL component transfer ──────────────────────────────────────────────
{
key: 'hue',
impl: 'native',
op: 'hue',
fallbackOp: 'hue',
label: 'Hue',
group: 'component',
note: 'takes the hue from the stroke, saturation + luminosity from the picture',
},
{
key: 'saturation',
impl: 'native',
op: 'saturation',
fallbackOp: 'saturation',
label: 'Saturation',
group: 'component',
note: 'takes the saturation from the stroke',
},
{
key: 'color',
impl: 'native',
op: 'color',
fallbackOp: 'color',
label: 'Color',
group: 'component',
note: 'takes hue + saturation from the stroke, luminosity from the picture -- good for colorizing',
},
{
key: 'luminosity',
impl: 'native',
op: 'luminosity',
fallbackOp: 'luminosity',
label: 'Luminosity',
group: 'component',
note: "takes the brightness from the stroke, keeps the picture's color",
},
// ── dissolve & masks ────────────────────────────────────────────────────
{
key: 'dissolve',
impl: 'gpu',
gpuId: 1,
fallbackOp: 'source-over',
label: 'Dissolve',
group: 'mask',
note: 'randomly drops pixels based on opacity -- grainy, speckled; re-rolls every frame',
},
{
key: 'stencil',
aliases: ['stencilluma'],
impl: 'gpu',
gpuId: 18,
fallbackOp: 'source-over',
label: 'Stencil Luma',
group: 'mask',
note: "the stroke's brightness masks the picture: bright reveals, dark hides",
},
{
key: 'silhouette',
aliases: ['silhouetteluma'],
impl: 'gpu',
gpuId: 19,
fallbackOp: 'source-over',
label: 'Silhouette Luma',
group: 'mask',
note: 'the inverse stencil: bright hides, dark reveals',
},
{
key: 'stencilalpha',
impl: 'gpu',
gpuId: 20,
fallbackOp: 'source-over',
label: 'Stencil Alpha',
group: 'mask',
note: "the stroke's own opacity masks the picture",
},
{
key: 'silhouettealpha',
impl: 'gpu',
gpuId: 21,
fallbackOp: 'source-over',
label: 'Silhouette Alpha',
group: 'mask',
note: "the inverse: the stroke's opacity hides the picture",
},
]
/** lowercase + strip everything that isn't a-z0-9 */
export function normalizeBlendName(s: string): string {
return s.trim().toLowerCase().replace(/[^a-z0-9]/g, '')
}
const BLEND_INDEX = new Map<string, BlendSpec>()
for (const spec of BLEND_SPECS) {
BLEND_INDEX.set(spec.key, spec)
for (const alias of spec.aliases ?? []) BLEND_INDEX.set(alias, spec)
}
/** Resolve any spelling to its spec (canonical or alias). */
export function findBlend(name: string): BlendSpec | undefined {
return BLEND_INDEX.get(normalizeBlendName(name))
}
/** 1-based index of a canonical keyword in the registry (0 if unknown).
* The expression language is numeric-only (Env = Record<string, number>),
* so the per-frame `blend` variable carries this index; the Help panel's
* table lists the number next to every keyword. */
export function blendIndex(key: string): number {
return BLEND_SPECS.findIndex((s) => s.key === key) + 1
}
/** Resolve a 1-based registry index back to its spec. */
export function blendByIndex(i: number): BlendSpec | undefined {
const k = Math.trunc(i)
return k >= 1 && k <= BLEND_SPECS.length ? BLEND_SPECS[k - 1] : undefined
}
/** All canonical keywords, in registry order. */
export function blendKeywords(): string[] {
return BLEND_SPECS.map((s) => s.key)
}

View file

@ -18,9 +18,12 @@
// (v7.10: em dashes in descriptions/script comments replaced with '--';
// v7.12: eleventh Zai-Magic preset "osc-rotations" added; v7.13.1: Beat
// Matrix grid endpoint fix — the last point no longer lands one column past
// the wall and the rightmost column keeps its bottom dot).
// the wall and the rightmost column keeps its bottom dot; v7.14: Arctic
// Rainbow re-imagined as a music-driven water spray — slower rise, arching
// fall, music-gated drop count, per-drop bass-hit hue shifts, falling-only
// RGB tails).
export const EMBEDDED_SEED_VERSION = '7.13.1'
export const EMBEDDED_SEED_VERSION = '7.14'
export interface EmbeddedPreset {
folder: string
@ -119,10 +122,10 @@ export const EMBEDDED_LIBRARY: EmbeddedPreset[] = [
folder: "root/embedded/Amp Picks",
name: "Arctic Rainbow",
author: "S_KuPeRS",
description: "Auto-ported from the Winamp AVS preset \"S_KuPeRS - Arctic Rainbow.avs\" by S_KuPeRS. The original is driven by BlitterFeedback, DynamicMovement, Movement, which the script engine cannot run -- replaced with a generated \"rain\"-style visual, uniquely parameterized for this preset (beat & band reactive).",
description: "Re-imagined (v7.14) from the Winamp AVS preset \"S_KuPeRS - Arctic Rainbow.avs\" by S_KuPeRS. The original's BlitterFeedback/DynamicMovement chain cannot run in the script engine -- this hand-tuned stand-in sprays water droplets skyward: each drop rises slowly, hangs, arches left or right and falls back down. The drop count follows the music's intensity (silence runs dry), every bass hit re-tints each droplet's own hue, and only falling drops trail a tapered RGB tail.",
originalFile: "/avs-originals/embedded/root/embedded/Amp Picks/S_KuPeRS - Arctic Rainbow.avs",
approx: true,
content: "name: \"Arctic Rainbow\"\nmode: dots\nblend: additive\npersist: 0.789\nlinewidth: 1.877\n\n[init]\ncols = 48\nn = 918\n\n[frame]\nfall = fall + dt * (0.855 + vol_att * 1.119)\nhue = hue + dt * 0.034\n\n[point]\ncol = floor(i * cols)\nci = frac(i * cols)\nxx = (col / cols - 0.5) * 1.9\nyf = frac(rand(col * 3.7 + 1) + fall * (0.55 + rand(col + 5) * 0.5))\ntail = rand(col * 1.3 + 9) * 0.297 + 0.04\nyy = (yf * 2 - 1) * 1.05 + ci * tail\nx = xx / aspect\ny = yy\nred = (1 - ci) * (0.2 + treb * 0.85) + 0.04 * 0.85\ngreen = (1 - ci) * (0.2 + treb * 0.85) + 0.04 * 0.92\nblue = (1 - ci) * (0.2 + treb * 0.85) + 0.04\nskip = if(above(abs(yy), 1.02), 1, 0)\n",
content: "# Arctic Rainbow -- re-imagined (v7.14) as a music-driven water spray.\n# Droplets launch from below the bottom edge, rise slowly, hang at the top,\n# arch left or right and fall back down, like water sprayed skyward. The\n# NUMBER of airborne drops follows the music's intensity: silence runs dry,\n# loud passages spray hard. Every droplet owns a hue that shifts on each\n# bass hit, and only falling drops grow a tapered RGB tail -- rising drops\n# stay crisp dots.\n#\n# Slot layout (mode lines): each drop owns S consecutive points --\n# slot 0 separator (always skipped; breaks the pen between drops)\n# slot 1 the head (a crisp dot while rising)\n# slots 2..S-1 trail samples reaching 0.014s..0.44s back along the arc\n# Trail samples draw only once the drop is falling (vy < 0), so the tail\n# fades in exactly as the arch turns downward.\nname: \"Arctic Rainbow\"\nmode: lines\nblend: additive\npersist: 0.12\nlinewidth: 2\n\n[init]\ndrops = 120\ntailn = 12\nS = tailn + 2\nn = drops * S\ndtT = 0.042\nacts = 0\n\n[frame]\n# music intensity -> how many drops are airborne (fast attack, slow release)\nvolish = min(1, max(vol_att, bass_att * 0.9) * 1.25)\nwant = clamp((volish - 0.06) / 0.5, 0, 1)\nrate = if(above(want, acts), 6, 1.2)\nacts = acts + (want - acts) * (1 - exp(-dt * rate))\nactn = floor(acts * drops + 0.001)\n# brightness rides the volume; every bass hit flashes the spray brighter\nflash = exp(-beatage * 7)\nbright = 0.62 + 0.38 * min(1, vol_att * 1.6) + flash * 0.3\n\n[point]\n# slot map through cell centers (dust-proof floor; v7.13.1 lesson)\nq = i * (n - 1) + 0.5\nd = floor(q / S)\nslot = floor(q - d * S)\n\n# stable per-drop character: apex height, flight time, hue, per-beat shift\nhbase = 1.26 + rand(d * 7.13 + 3) * 0.62\ntf = 1.9 + rand(d * 5.31 + 11) * 1.5\nhue0 = rand(d * 3.7 + 23)\nhsh = 0.09 + rand(d * 9.17 + 31) * 0.17\n\n# flight clock: period P per drop, phase-staggered; every new splash\n# re-rolls its origin, drift and arch from the cycle index\nP = tf * 1.18\nct = time + rand(d * 1.7 + 43) * P\ncyc = floor(ct / P)\na = ct - cyc * P\nxr = d * 12.77 + cyc * 17.31\nx0 = rand(xr + 1) * 2 - 1\ndrift = (rand(xr + 2) * 2 - 1) * 0.16\narch = (rand(xr + 3) * 2 - 1) * 0.55\n\n# projectile parabola: y(u) = -1.06 + 4*h*u*(1-u), apex h above the launch\nvy0 = 4 * hbase / tf\ngrav = 8 * hbase / (tf * tf)\n\n# this slot's sample age: the head is \"now\", trail slots reach back in time\nlag = if(above(slot, 1.5), 0.014 + (slot - 2) * dtT, 0)\naj = a - lag\nuj = aj / tf\nyj = -1.06 + 4 * hbase * uj * (1 - uj)\nxj = x0 + drift * uj + arch * uj * uj\n\n# music gate + dead window + off-screen cull\nskip = if(above(slot, 0.5), if(above(d, actn - 0.5), 1, 0), 1)\nskip = if(above(a, tf * 1.15), 1, skip)\nskip = if(below(aj, 0), 1, skip)\nskip = if(above(abs(xj), 1.05), 1, skip)\n\n# tail gate: 0 the whole way up, fading in as the fall accelerates\nvy = vy0 - grav * a\ntgate = smoothstep(0, 0.35, -vy / vy0)\n\n# per-drop hue, shifted by every bass hit; older trail samples drift back\nhue = hue0 + beats * hsh + time * 0.012 - (slot - 1) * 0.008\nred = hsvr(hue, 1, bright)\ngreen = hsvg(hue, 1, bright)\nblue = hsvb(hue, 1, bright)\n\ndsz = 1.6 + rand(d * 2.9 + 51) * 1.1 + bass_att * 1.4\nu = (slot - 2) / tailn\nif(above(slot, 1.5),\n if(above(slot, 2.5),\n (alpha = tgate * pow(1 - u, 1.5) * 0.85;\n size = dsz * (1 - 0.72 * u);\n skip = if(below(tgate, 0.03), 1, skip)),\n (alpha = max(1 - tgate, tgate * 0.85); size = dsz)),\n (alpha = 1; size = dsz))\nx = xj\ny = yj\n",
},
{
folder: "root/embedded/Amp Picks",

View file

@ -3,14 +3,26 @@
// Owns the requestAnimationFrame loop:
// audio bands -> beat tracker -> env -> [frame] -> [beat] -> [point]xN -> draw
//
// Drawing supports three modes (lines | dots | solid) with additive blending,
// per-point colors, a two-pass glow, and a persistence fade for motion trails.
// Drawing supports three render modes (lines | dots | solid). The blend
// header (v7.15) selects from the 41-mode registry in blend.ts: native
// keywords composite straight onto the live canvas, the rest run through
// the WebGL compositor (blend-gpu.ts) after a scratch pass. env.blend can
// override the header per frame (reset every frame, like persist).
//
// The framebuffer is alpha-capable (v7.15) -- behind and clear need real
// transparency. The persistence fade is therefore an alpha ERASE
// (destination-out) and the bg* wipe a clearRect; over the black stage
// both read pixel-identically to the old opaque fills, so existing
// presets render exactly as before. persist 1 skips the fade entirely
// (v7.14.1: a true zero-fade framebuffer).
import { blendByIndex, blendIndex, findBlend } from './blend'
import { BlendCompositor } from './blend-gpu'
import { AudioEngine } from './audio'
import { BeatTracker } from './beat'
import { AVA_HOOKS, resetEelBuffers } from './expression'
import type { AvaScript } from './script'
import type { BandConfig, BandLevels, BeatConfig, BeatFrame } from './types'
import type { BandConfig, BandLevels, BeatConfig, BeatFrame, RenderMode } from './types'
import { DEFAULT_BAND_CONFIG, DEFAULT_BEAT_CONFIG } from './types'
const MAX_POINTS = 8192
@ -25,6 +37,21 @@ function bgNum(v: number | undefined, neutral: number): number {
return Number.isFinite(x) ? x : neutral
}
/** v7.15 stroke-pass gains. GAINS_STD is every mode's default two-pass
* glow tuning (unchanged since the original engine). GAINS_REPLACE is the
* v7.14.1 replace tuning: the CORE pass at FULL alpha, so the stroke owns
* its pixels outright (halo slightly stronger: it converges toward the
* source color, never past it). */
interface DrawGains {
halo: number
core: number
dotsGlow: number
dotsCore: number
solid: number
}
const GAINS_STD: DrawGains = { halo: 0.22, core: 0.9, dotsGlow: 0.18, dotsCore: 0.85, solid: 0.65 }
const GAINS_REPLACE: DrawGains = { halo: 0.25, core: 1, dotsGlow: 0.25, dotsCore: 1, solid: 1 }
export interface EngineStats {
fps: number
levels: BandLevels
@ -69,6 +96,16 @@ export class AvaEngine {
private bgBuffer: HTMLCanvasElement | null = null
private bgBufCtx: CanvasRenderingContext2D | null = null
/** v7.15 scratch for gpu blend modes: the two stroke passes draw here
* (source-over), then the WebGL compositor blends it onto the live
* canvas in one per-pixel pass. Same lazy lifecycle as bgBuffer. */
private blendBuffer: HTMLCanvasElement | null = null
private blendBufCtx: CanvasRenderingContext2D | null = null
private compositor: BlendCompositor | null = null
/** latched when WebGL proves unavailable -- gpu modes fall back to their
* nearest native operator (spec.fallbackOp). */
private gpuBroken = false
constructor() {
// AVS-eel compatibility hooks — the expression engine reads audio/time
// through these (getspec/getosc/gettime). Headless tests can override.
@ -87,13 +124,15 @@ export class AvaEngine {
start(canvas: HTMLCanvasElement): void {
this.stop()
this.canvas = canvas
const ctx = canvas.getContext('2d', { alpha: false })
// v7.15: alpha-capable framebuffer (default { alpha: true }) -- behind
// and clear need real transparency. The stage behind the canvas is
// bg-black, so a transparent buffer displays identically to the old
// opaque black one; it starts clean (no fill).
const ctx = canvas.getContext('2d')
if (!ctx) return
this.ctx = ctx
this.canFilter = typeof ctx.filter === 'string'
this.transition = null
this.ctx.fillStyle = '#000'
this.ctx.fillRect(0, 0, canvas.width, canvas.height)
this.clockStart = performance.now()
this.lastNow = this.clockStart
this.running = true
@ -195,10 +234,12 @@ export class AvaEngine {
bctx.globalCompositeOperation = 'copy'
bctx.drawImage(canvas, 0, 0)
// 2. wipe — the transformed snapshot must REPLACE the old content, not
// double-expose over it
// double-expose over it. v7.15: clearRect (transparent) instead of a
// black fill — the framebuffer is alpha-capable now, and pixels with
// real transparency (behind / clear art) must keep it through the
// move. Over the black stage both read identically.
ctx.globalCompositeOperation = 'source-over'
ctx.fillStyle = '#000'
ctx.fillRect(0, 0, w, h)
ctx.clearRect(0, 0, w, h)
// 3. draw the snapshot back through this frame's transform. Screen y is
// down; script y is up — bgy > 0 moves the picture UP.
ctx.save()
@ -210,6 +251,134 @@ export class AvaEngine {
ctx.restore()
}
/** v7.15 — lazy scratch canvas for the gpu blend path (mirrors bgBuffer). */
private scratchBuffer(w: number, h: number): boolean {
if (!this.blendBuffer || this.blendBuffer.width !== w || this.blendBuffer.height !== h) {
const buf = document.createElement('canvas')
buf.width = w
buf.height = h
this.blendBuffer = buf
this.blendBufCtx = buf.getContext('2d')
}
return this.blendBufCtx != null
}
/** v7.15 — lazy WebGL compositor; latches gpuBroken when unavailable. */
private gpuEnsure(w: number, h: number): boolean {
if (this.gpuBroken) return false
if (!this.compositor) this.compositor = new BlendCompositor()
if (this.compositor.failed || !this.compositor.ensure(w, h)) {
this.gpuBroken = true
return false
}
return true
}
/** v7.15 — one place for the stroke/dot/polygon passes, target-agnostic:
* the native path draws onto the live canvas with the mode's composite
* op; the gpu path draws onto the scratch with source-over (the shader
* then blends the whole layer in one pass). */
private drawContent(
ctx: CanvasRenderingContext2D,
n: number,
meta: { mode: RenderMode; linewidth: number },
g: DrawGains,
): void {
const canvas = this.canvas
if (!canvas) return
const w = canvas.width
const h = canvas.height
const pts = this.points
const scale = h / 480 // keeps geometry consistent across resolutions
if (meta.mode === 'lines') {
ctx.lineCap = 'round'
ctx.lineJoin = 'round'
for (let pass = 0; pass < 2; pass++) {
const gain = pass === 0 ? g.halo : g.core
let pen = false
let pr = 0, pg = 0, pb = 0, pa = 0, pxp = 0, pyp = 0, plw = 0
for (let k = 0; k < n; k++) {
const o = k * POINT_STRIDE
const skip = pts[o + 5]
const x = (pts[o] * 0.5 + 0.5) * w
const y = (0.5 - pts[o + 1] * 0.5) * h
const r = Math.max(0, Math.min(1, pts[o + 2]))
const gg = Math.max(0, Math.min(1, pts[o + 3]))
const b = Math.max(0, Math.min(1, pts[o + 4]))
const a = Math.max(0, Math.min(1, pts[o + 7]))
// per-point line width (AVS linesize) -- falls back to meta.linewidth
const lw = Math.max(0.3, pts[o + 6] > 0 ? pts[o + 6] : meta.linewidth) * (pass === 0 ? 3.2 : 1) * scale
if (skip) {
pen = false
pr = r; pg = gg; pb = b; pa = a; pxp = x; pyp = y; plw = lw
continue
}
if (pen) {
ctx.strokeStyle = `rgba(${(((pr + r) / 2) * 255) | 0},${(((pg + gg) / 2) * 255) | 0},${(((pb + b) / 2) * 255) | 0},${(((pa + a) / 2) * gain).toFixed(3)})`
ctx.lineWidth = (plw + lw) / 2
ctx.beginPath()
ctx.moveTo(pxp, pyp)
ctx.lineTo(x, y)
ctx.stroke()
}
pr = r; pg = gg; pb = b; pa = a; pxp = x; pyp = y; plw = lw
pen = true
}
}
} else if (meta.mode === 'dots') {
for (let pass = 0; pass < 2; pass++) {
const sizeGain = pass === 0 ? 2.6 : 1
const alphaGain = pass === 0 ? g.dotsGlow : g.dotsCore
for (let k = 0; k < n; k++) {
const o = k * POINT_STRIDE
if (pts[o + 5]) continue
const x = (pts[o] * 0.5 + 0.5) * w
const y = (0.5 - pts[o + 1] * 0.5) * h
const r = Math.max(0, Math.min(1, pts[o + 2]))
const gg = Math.max(0, Math.min(1, pts[o + 3]))
const b = Math.max(0, Math.min(1, pts[o + 4]))
const a = Math.max(0, Math.min(1, pts[o + 7]))
const rad = Math.max(0.6, pts[o + 6] * scale * sizeGain)
ctx.fillStyle = `rgba(${(r * 255) | 0},${(gg * 255) | 0},${(b * 255) | 0},${(a * alphaGain).toFixed(3)})`
ctx.beginPath()
ctx.arc(x, y, rad, 0, 6.28318)
ctx.fill()
}
}
} else {
// solid: filled polygon through all non-skipped points
let sr = 0, sg = 0, sb = 0, sa = 0, count = 0
ctx.beginPath()
let pen = false
for (let k = 0; k < n; k++) {
const o = k * POINT_STRIDE
if (pts[o + 5]) {
pen = false
continue
}
const x = (pts[o] * 0.5 + 0.5) * w
const y = (0.5 - pts[o + 1] * 0.5) * h
if (!pen) {
ctx.moveTo(x, y)
pen = true
} else {
ctx.lineTo(x, y)
}
sr += pts[o + 2]; sg += pts[o + 3]; sb += pts[o + 4]; sa += pts[o + 7]; count++
}
if (count > 2) {
ctx.closePath()
const r = Math.max(0, Math.min(1, sr / count))
const gg = Math.max(0, Math.min(1, sg / count))
const b = Math.max(0, Math.min(1, sb / count))
const a = Math.max(0, Math.min(1, sa / count)) * g.solid
ctx.fillStyle = `rgba(${(r * 255) | 0},${(gg * 255) | 0},${(b * 255) | 0},${a.toFixed(3)})`
ctx.fill()
}
}
}
private resize(): void {
if (!this.canvas) return
const parent = this.canvas.parentElement
@ -219,12 +388,10 @@ export class AvaEngine {
const w = Math.max(2, Math.round(cssW * dpr))
const h = Math.max(2, Math.round(cssH * dpr))
if (this.canvas.width !== w || this.canvas.height !== h) {
// assigning width/height also clears to transparent (v7.15: no
// opaque black fill -- behind/clear need the alpha channel)
this.canvas.width = w
this.canvas.height = h
if (this.ctx) {
this.ctx.fillStyle = '#000'
this.ctx.fillRect(0, 0, w, h)
}
}
}
@ -242,12 +409,25 @@ export class AvaEngine {
const ctx = this.ctx
// ---- persistence fade -------------------------------------------------
// v7.14.1: persist may reach 1.0 -- at exactly 1 the fade is skipped
// entirely: old content leaves the screen only through a bg* transform
// carrying it off (or by being repainted, blend 'replace'). That is
// what makes "colors ride outward forever while the fresh drawing
// replaces the center" possible.
// v7.15: the fade is an alpha ERASE (destination-out) instead of a
// black fill -- the framebuffer is alpha-capable, and scaling alpha by
// persist thins trails exactly like the old rgb scaling did over the
// black stage, while pixels that were painted behind / cleared keep
// fading honestly.
const meta = this.script?.meta
const persistBase = meta ? meta.persist : 0.85
const persist = Math.min(Math.max(this.env.persist ?? persistBase, 0), 0.985)
const persist = Math.min(Math.max(this.env.persist ?? persistBase, 0), 1)
if (persist < 1) {
ctx.globalCompositeOperation = 'destination-out'
ctx.fillStyle = `rgba(0,0,0,${(1 - persist).toFixed(4)})`
ctx.fillRect(0, 0, w, h)
}
ctx.globalCompositeOperation = 'source-over'
ctx.fillStyle = `rgba(0,0,0,${(1 - persist).toFixed(4)})`
ctx.fillRect(0, 0, w, h)
// ---- audio + beat -----------------------------------------------------
const levels = this.audio.getBands(this.bandConfig, dt)
@ -288,6 +468,13 @@ export class AvaEngine {
env.h = h
env.aspect = w / Math.max(1, h)
env.persist = persistBase // reset so the script can override each frame
// v7.15: same per-frame contract for the blend mode -- reset to the
// header mode's registry index so [frame]/[beat] can switch composites
// for THIS frame (the expression language is numeric-only, so the
// variable carries the mode's 1-based number; the Help table lists
// them). Read after the sections, before drawing; out-of-range values
// fall back to the header keyword.
env.blend = meta ? blendIndex(meta.blend) || 2 : (env.blend ?? 2)
if (this.script) {
try {
@ -351,97 +538,44 @@ export class AvaEngine {
}
// ---- draw ---------------------------------------------------------------
const scale = h / 480 // keeps geometry consistent across resolutions
const halfW = w / 2
const halfH = h / 2
if (n > 0 && meta) {
ctx.globalCompositeOperation = meta.blend === 'additive' ? 'lighter' : 'source-over'
if (meta.mode === 'lines') {
ctx.lineCap = 'round'
ctx.lineJoin = 'round'
for (let pass = 0; pass < 2; pass++) {
const gain = pass === 0 ? 0.22 : 0.9
let pen = false
let pr = 0, pg = 0, pb = 0, pa = 0, pxp = 0, pyp = 0, plw = 0
for (let k = 0; k < n; k++) {
const o = k * POINT_STRIDE
const skip = pts[o + 5]
const x = (pts[o] * 0.5 + 0.5) * w
const y = (0.5 - pts[o + 1] * 0.5) * h
const r = Math.max(0, Math.min(1, pts[o + 2]))
const g = Math.max(0, Math.min(1, pts[o + 3]))
const b = Math.max(0, Math.min(1, pts[o + 4]))
const a = Math.max(0, Math.min(1, pts[o + 7]))
// per-point line width (AVS linesize) — falls back to meta.linewidth
const lw = Math.max(0.3, pts[o + 6] > 0 ? pts[o + 6] : meta.linewidth) * (pass === 0 ? 3.2 : 1) * scale
if (skip) {
pen = false
pr = r; pg = g; pb = b; pa = a; pxp = x; pyp = y; plw = lw
continue
}
if (pen) {
ctx.strokeStyle = `rgba(${(((pr + r) / 2) * 255) | 0},${(((pg + g) / 2) * 255) | 0},${(((pb + b) / 2) * 255) | 0},${(((pa + a) / 2) * gain).toFixed(3)})`
ctx.lineWidth = (plw + lw) / 2
ctx.beginPath()
ctx.moveTo(pxp, pyp)
ctx.lineTo(x, y)
ctx.stroke()
}
pr = r; pg = g; pb = b; pa = a; pxp = x; pyp = y; plw = lw
pen = true
// v7.15 — the 41-mode registry (blend.ts). The blend variable (reset
// to the header mode's index every frame, so a script can switch per
// frame; the Help table lists each mode's number) picks the composite;
// an out-of-range value falls back to the header keyword. Native
// keywords composite straight onto the live canvas; gpu keywords draw
// the passes onto a scratch canvas and the WebGL compositor applies
// the formula (nearest native op when WebGL is unavailable).
// 'replace' keeps its v7.14.1 semantics: the core pass at FULL alpha,
// so the stroke owns its pixels outright.
const headerSpec = findBlend(meta.blend)
const spec = blendByIndex(env.blend ?? 0) ?? headerSpec ?? undefined
if (spec) {
const viaGpu =
spec.impl === 'gpu' &&
!this.gpuBroken &&
this.scratchBuffer(w, h) &&
this.gpuEnsure(w, h)
if (viaGpu) {
const sctx = this.blendBufCtx!
sctx.globalCompositeOperation = 'source-over'
sctx.clearRect(0, 0, w, h)
this.drawContent(sctx, n, meta, GAINS_STD)
try {
this.compositor!.blend(this.canvas!, this.blendBuffer!, spec.gpuId ?? 0, env.frame ?? 0)
// replace the live canvas with the blended result wholesale
ctx.globalCompositeOperation = 'copy'
ctx.drawImage(this.compositor!.canvas, 0, 0)
ctx.globalCompositeOperation = 'source-over'
} catch {
this.gpuBroken = true // one bad frame never repeats; fallback next frame
}
}
} else if (meta.mode === 'dots') {
for (let pass = 0; pass < 2; pass++) {
const sizeGain = pass === 0 ? 2.6 : 1
const alphaGain = pass === 0 ? 0.18 : 0.85
for (let k = 0; k < n; k++) {
const o = k * POINT_STRIDE
if (pts[o + 5]) continue
const x = (pts[o] * 0.5 + 0.5) * w
const y = (0.5 - pts[o + 1] * 0.5) * h
const r = Math.max(0, Math.min(1, pts[o + 2]))
const g = Math.max(0, Math.min(1, pts[o + 3]))
const b = Math.max(0, Math.min(1, pts[o + 4]))
const a = Math.max(0, Math.min(1, pts[o + 7]))
const rad = Math.max(0.6, pts[o + 6] * scale * sizeGain)
ctx.fillStyle = `rgba(${(r * 255) | 0},${(g * 255) | 0},${(b * 255) | 0},${(a * alphaGain).toFixed(3)})`
ctx.beginPath()
ctx.arc(x, y, rad, 0, 6.28318)
ctx.fill()
}
}
} else {
// solid: filled polygon through all non-skipped points
let sr = 0, sg = 0, sb = 0, sa = 0, count = 0
ctx.beginPath()
let pen = false
for (let k = 0; k < n; k++) {
const o = k * POINT_STRIDE
if (pts[o + 5]) {
pen = false
continue
}
const x = (pts[o] * 0.5 + 0.5) * w
const y = (0.5 - pts[o + 1] * 0.5) * h
if (!pen) {
ctx.moveTo(x, y)
pen = true
} else {
ctx.lineTo(x, y)
}
sr += pts[o + 2]; sg += pts[o + 3]; sb += pts[o + 4]; sa += pts[o + 7]; count++
}
if (count > 2) {
ctx.closePath()
const r = Math.max(0, Math.min(1, sr / count))
const g = Math.max(0, Math.min(1, sg / count))
const b = Math.max(0, Math.min(1, sb / count))
const a = Math.max(0, Math.min(1, sa / count)) * 0.65
ctx.fillStyle = `rgba(${(r * 255) | 0},${(g * 255) | 0},${(b * 255) | 0},${a.toFixed(3)})`
ctx.fill()
} else {
const op: GlobalCompositeOperation =
spec.impl === 'gpu' ? spec.fallbackOp : spec.op ?? 'source-over'
ctx.globalCompositeOperation = op
this.drawContent(ctx, n, meta, spec.fullAlphaCore ? GAINS_REPLACE : GAINS_STD)
ctx.globalCompositeOperation = 'source-over'
}
}
}

View file

@ -6,8 +6,11 @@
// name: Gap The Mind <- header keys before the first [section]
// author: synth-c (adapted)
// mode: lines <- lines | dots | solid
// blend: additive <- additive | alpha
// persist: 0.9 <- motion trail persistence 0..0.98
// blend: additive <- any of the 41 registry keywords (blend.ts);
// case/separator-insensitive, and switchable
// per frame through the blend variable
// (by its number in the Help table)
// persist: 0.9 <- motion trail persistence 0..1 (1 = never fades)
// linewidth: 2
//
// [init] runs once when the script loads
@ -15,6 +18,7 @@
// [beat] runs on frames where a beat fired (after [frame])
// [point] runs once per point (n times per frame)
import { findBlend } from './blend'
import { compileProgram, ExpressionError, type Env, type Program } from './expression'
import type { BlendMode, RenderMode } from './types'
@ -58,7 +62,6 @@ export interface AvaScript {
const SECTION_NAMES = new Set(['init', 'frame', 'beat', 'point'])
const HEADER_KEYS = new Set(['name', 'author', 'description', 'mode', 'blend', 'persist', 'linewidth', 'ysign'])
const MODES = new Set(['lines', 'dots', 'solid'])
const BLENDS = new Set(['additive', 'alpha'])
const DEFAULT_META: ScriptMeta = {
name: 'Untitled',
@ -157,18 +160,26 @@ function tryParse(text: string): { script: AvaScript | null; meta?: ScriptMeta;
}
meta.mode = value as RenderMode
break
case 'blend':
if (!BLENDS.has(value)) {
return { script: null, meta: { ...meta }, error: { message: `blend must be 'additive' or 'alpha' (got '${value}')`, section: 'header', line: lineNo } }
case 'blend': {
// v7.15: the 41-mode registry (blend.ts). Any spelling normalizes
// (Color Burn = color-burn = colorburn); the meta stores the
// CANONICAL key so the engine and every UI surface see one form.
const spec = findBlend(value)
if (!spec) {
return { script: null, meta: { ...meta }, error: { message: `unknown blend '${value}' -- the editor Help panel lists all 41 keywords (normal, additive, multiply, screen, subtract, replace, behind, clear, overlay, difference, hue, dissolve, phoenix, stencil, ...)`, section: 'header', line: lineNo } }
}
meta.blend = value as BlendMode
meta.blend = spec.key
break
}
case 'persist': {
const v = parseFloat(value)
if (Number.isNaN(v)) {
return { script: null, meta: { ...meta }, error: { message: `persist must be a number 0..0.98 (got '${value}')`, section: 'header', line: lineNo } }
return { script: null, meta: { ...meta }, error: { message: `persist must be a number 0..1 (got '${value}')`, section: 'header', line: lineNo } }
}
meta.persist = Math.min(Math.max(v, 0), 0.98)
// v7.14.1: 1.0 is legal -- a true zero-fade framebuffer (the engine
// then skips the fade pass entirely; old content only leaves via a
// bg* transform carrying it off-screen).
meta.persist = Math.min(Math.max(v, 0), 1)
break
}
case 'linewidth': {

View file

@ -1,7 +1,14 @@
// AVA — Advanced Visualization Agent · shared types
export type RenderMode = 'lines' | 'dots' | 'solid'
export type BlendMode = 'additive' | 'alpha'
/** v7.15 — blend is any keyword from the registry (src/lib/ava/blend.ts);
* the parser validates it via findBlend and canonicalizes to spec.key.
* All spellings are accepted (color burn = colorburn = ColorBurn).
* v7.15 notes: 'subtract' is now a TRUE clamped subtract (WebGL
* compositor) rather than 7.14.1's difference approximation; 'replace'
* keeps its v7.14.1 semantics (source-over with the core pass at FULL
* alpha); the blend variable can override the header per frame. */
export type BlendMode = string
export type AudioSourceKind = 'idle' | 'demo' | 'mic' | 'file' | 'link'
/** Fine-tunable band detection configuration (Hz ranges + gains). */

0
src/lib/ava/wake-lock.ts Normal file → Executable file
View file

0
src/lib/ove-directory.ts Normal file → Executable file
View file

View file

@ -39,6 +39,52 @@ export interface ReleaseNote {
}
export const RELEASE_NOTES: ReleaseNote[] = [
{
version: '7.15.0',
name: 'The complete blend mode collection',
changes: [
{
kind: 'added',
text: 'blend: now takes 41 modes instead of six. The full Photoshop set is there (color burn, linear burn, darker color, color dodge, lighter color, overlay, soft light, hard light, vivid light, linear light, pin light, hard mix, difference, exclusion, divide, negation, phoenix, reflect, glow, hue, saturation, color, luminosity), plus GIMP\'s grain extract/merge, After Effects\' stencil and silhouette masks, a dissolve that re-rolls its speckle every frame, and plus-lighter / plus-darker. Any spelling works: color burn, color-burn and ColorBurn are the same keyword.',
},
{
kind: 'added',
text: 'blend: subtract is now a true clamped subtract (base - blend, floored at black). Until 7.14.1 it was approximated with difference, which could never subtract downward past the stroke color.',
},
{
kind: 'added',
text: 'The blend variable can switch modes per frame, like persist already could -- paint with replace (3), then sculpt with subtract (6) on the kick; every mode\'s number is in the Help panel\'s table. The framebuffer also keeps real transparency now, so behind (strokes slip under existing art) and clear (an eraser pen) work honestly.',
},
{
kind: 'improved',
text: 'Every existing preset renders exactly as before -- the new transparency-aware fades and wipes read pixel-identically over the black stage. Modes without a Canvas2D operator run through a small WebGL pass; browsers without WebGL fall back to the nearest native operator.',
},
],
},
{
version: '7.14.1',
name: 'New blend modes + zero-fade trails',
changes: [
{
kind: 'added',
text: 'Scripts can now choose how fresh strokes mix with what is already on screen: blend: multiply, screen, subtract and replace join the old additive and alpha. replace is the interesting one -- new lines overwrite the color underneath instead of stacking on it, so a figure redrawn over its own trails keeps its color instead of blooming to white.',
},
{
kind: 'added',
text: 'persist: 1 is now legal: a framebuffer that never fades. Combined with replace and the background zoom it finally makes the classic "colors ride outward forever" blow-out work -- the blow-out itself carries old color off screen while the fresh drawing replaces it in the center, at constant speed, no fading.',
},
],
},
{
version: '7.14',
name: 'Arctic Rainbow re-sprayed',
changes: [
{
kind: 'improved',
text: 'The old Arctic Rainbow was just white dots sweeping upward. I rebuilt it as a music-driven water spray: droplets rise slowly, hang at the top, arch left or right and fall back down. The drop count now follows the music -- silence runs completely dry, loud passages throw a full spray of up to 120 droplets -- every droplet carries its own color that shifts on each bass hit, and falling droplets trail a tapered RGB tail while rising ones stay crisp dots.',
},
],
},
{
version: '7.13.1',
name: 'Beat Matrix grid fixed',

0
src/lib/server/ove-directory.ts Normal file → Executable file
View file

View file

@ -12,6 +12,75 @@
// warns in the console when the two drift apart.
//
// History:
// 7.15 — the complete blend mode collection (user request): the blend
// header grew from six keywords to a 41-mode registry
// (src/lib/ava/blend.ts) covering every compositing family in the
// request list -- the full Photoshop set, the GIMP grain pair,
// the After Effects stencil/silhouette masks, Apple/CSS plus-
// lighter/plus-darker and the Pegtop exotica (negation, phoenix,
// reflect, glow). Native keywords map straight to Canvas2D
// operators; the 21 modes Canvas2D lacks run through a new WebGL
// compositor (blend-gpu.ts) with per-pixel formulas from the W3C
// compositing spec, the glsl-blend collection and GIMP (phoenix =
// min - max + 1, verified against four independent sources; hard
// mix = vivid light thresholded at 0.5). 'subtract' is now a TRUE
// clamped subtract, replacing 7.14.1's difference approximation.
// The framebuffer went alpha-capable so behind and clear work
// honestly: the persistence fade is an alpha ERASE
// (destination-out) and the bg* wipe a clearRect -- over the
// black stage both read pixel-identically to the old opaque
// fills, so every existing preset renders as before. The blend
// variable can switch the mode per frame (same contract as
// persist; it carries the mode's 1-based registry number because
// the expression language is numeric-only -- the Help table lists
// every number). Names are case/separator-insensitive
// with aliases (color burn = colorburn = ColorBurn; plus-lighter
// = additive; plus-darker = linear burn). Help panel gained a
// grouped 41-row Blend modes table; parser errors point at it.
// WebGL-less browsers fall back to the nearest native operator
// per mode.
// 7.14.1 — Script engine: blend modes + zero-fade persistence (user
// request, Brainstorm preset session). The renderer's content
// pass could only composite additively ('lighter') or plain
// alpha; the persistence header was hard-capped at 0.98, so a
// feedback blow-out ALWAYS faded -- the user wanted colors that
// ride outward forever at full brightness, replaced at the center
// by new color. Blend header extended to six values: multiply,
// screen, subtract (canvas 'difference' |dst-src| -- Canvas2D has
// no clamped true-subtract op; difference is the classic
// approximation and can never climb to white) and replace
// (source-over with the CORE pass at FULL alpha -- fresh strokes
// overwrite the pixels under them instead of stacking, so a
// figure redrawn over its own accumulating trails keeps its color
// instead of saturating to white; halo pass 0.25, dots core
// alpha 1.0, solid fill alpha 1.0). persist header + env override
// widened 0..0.98 -> 0..1; at exactly 1 the fade fill is SKIPPED
// entirely (engine.ts). The pairing this was asked for: blend
// replace + persist 1 + the v7.12 bgzoom/bgrot feedback = a
// static-speed blow-out that never fades, the fresh drawing
// replacing the old color at the center -- the blow-out itself is
// the cleanup. Help panel + parser error strings updated; no
// library changes (existing presets keep additive/alpha and their
// behavior byte-for-byte).
// 7.14 — Arctic Rainbow re-imagined (user request): the old stand-in was
// plain white columns of rain dots sweeping upward. Rebuilt as a
// music-driven water spray, stateless projectile physics in the
// [point] program: each of up to 120 droplets is a deterministic
// parabola (own apex height 1.26..1.88, own flight time 1.9..3.4 s,
// phase-staggered clock; every splash cycle re-rolls its origin,
// drift and arch) -- launch from below the bottom edge, slow rise,
// hang, arch left or right, fall back off-screen. Drop count
// follows the music (vol_att/bass_att envelope, fast attack 6/s,
// slow release 1.2/s: silence = 0 drops, loud = all 120). Each
// drop owns a hue that shifts by its own per-drop amount on every
// detected beat, plus a subtle gradient along its tail. The tail
// is 12 explicit trail samples (0.014..0.44 s back along the arc)
// drawn as a tapered polyline in lines mode, gated by smoothstep
// on the fall speed: nothing while rising (crisp dot), fading in
// as the arch turns downward -- no persistence smear (persist
// 0.12). Slot map through cell centers (the v7.13.1 lesson), 14
// slots per drop (separator + head + 12 trail), n = 1680.
// EMBEDDED_SEED_VERSION 7.13.1 -> 7.14 re-seeds the library.
// 7.13.1 — Beat Matrix endpoint fix (user report): the rightmost column
// of dots sat one row short -- its bottom dot missing -- while a
// phantom dot spilled one column past the wall's right edge at
@ -431,4 +500,4 @@
export const APP_NAME = 'Open Visualization Engine'
export const APP_SHORT = 'OVE'
export const APP_VERSION = '7.13.1'
export const APP_VERSION = '7.15.0'

Binary file not shown.

Before

Width:  |  Height:  |  Size: 290 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 651 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 351 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

View file

@ -1,490 +0,0 @@
======================================================================
FILE: 144ogY2rPneG... (12583 bytes)
======================================================================
[ 0] Nullsoft AVS Preset 0.2
[ 322] Misc: AVSTrans Automation
[ 374] #define $dt reg00 | #define $resize reg02 | #define $fps reg04 | #define $beat reg05 | #define $t reg06 | #define $debug reg20 | #define $playing reg30 | #de
[ 5197] r= i*$pi*2; | d=snd; | x=sin(r)*d; | y=cos(r)*d; | snd = abs((mb(pc+avgoffset))); | hsl(snd*2+i,abs(snd)*i*2,.1*i*2+snd*500); | pc=pc+1; | skip = 0;
[ 5343] bands = reg80; | //background gradient & rolling avg getosc | //reg51 = bands; | iseconds = 1/seconds; | length = smppersec * seconds; | ilength = 1/lengt
[ 6357] smppersec = 40; | seconds = .2; width=0.05
[ 6425] Jheriko: Global
[ 6489] debug = 1; reg20 = debug; | ptime = gettime(0);reg70=0;
[ 6544] currenttime = gettime(0); | dt = currenttime-ptime; | ptime = currenttime; | reg00 = dt; | reg06 = gettime(0); | | | playtime = reg60 = gettime(-1); | | d
[ 7044] AVS 2.8+ Effect List Config
[ 7109] d = d * (1 - (sin((r-$PI*0.5) * 7) * .03)); | r = r + (cos(d * 12) * .03);
[ 7220] y=y+abs(x)*.05+.01
[ 7336] AVS 2.8+ Effect List Config
[ 7445] AVS 2.8+ Effect List Config
[ 7518] ind = ( (ww-cx+fc)%ww ) *hh+cy; | snd = gmb(ind); | yi=cy*ihh+snd*0+.1;xi=cx*iww*2-1; | r=yi*2*$pi+snd*3+ccc*.5*0+sin(ic*3)*.1; | d=.6+xi*.2*(.1); | qr=q*r
[ 8185] #define rotsines_vec(name,r) rx_=vec_##r##_x;ry_=vec_##r##_y;rz_=vec_##r##_z;rs_##name##_xs=-sin(rx_);rs_##name##_xc=cos(rx_);rs_##name##_ys=-sin(ry_)
[ 9496] ind = ( (ww-cx+fc)%ww ) *hh+cy; | snd = gmb(ind); | ic=ccc/20; | ff=sin(ic*$pi); | f=cos(ic*$pi); | yi=cy*ihh+snd*5;xi=cx*iww*2-1; | r=yi*2*$pi+snd*3+ccc*.5
[ 10269] #define rotsines_vec(name,r) rx_=vec_##r##_x;ry_=vec_##r##_y;rz_=vec_##r##_z;rs_##name##_xs=-sin(rx_);rs_##name##_xc=cos(rx_);rs_##name##_ys=-sin(ry_)
[ 11028] AVS 2.8+ Effect List Config
[ 11080] Holden03: Convolution Filter
[ 11336] C:\Program Files (x86)\Winamp\Plugins\avs\conv glow 1 (UCD).cffl
[ 11403] Holden03: Convolution Filter
[ 11659] C:\Program Files (x86)\Winamp\Plugins\avs\conv glow 2 (UCD).cff
[ 11771] AVS 2.8+ Effect List Config
======================================================================
FILE: 1Mh8Dy0Q7PVY... (34251 bytes)
======================================================================
[ 0] Nullsoft AVS Preset 0.2
[ 37] wonder 'bout | zamuz | | visbot.net
[ 95] reg01=.05; | reg02=.5; // color multi | reg03=min(w,h)*.006; // size; | reg04=.7*getspec(.1,.1,0); | cd=equal(ctr,1); | ctr=if(below(ctr,.005),1,ctr-.05);
[ 512] Acko.net: Texer II
[ 552] v5_square.bmp
[ 567] rcle_edgeonly_17x17.bmp
[ 832] n=1;reg00=reg00+.05;ss=reg00;
[ 865] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 1078] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 1264] Acko.net: Texer II
[ 1304] v5_square.bmp
[ 1319] rcle_edgeonly_17x17.bmp
[ 1584] n=1;reg00=reg00+.05;ss=reg00;
[ 1617] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 1830] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 2016] Acko.net: Texer II
[ 2056] v5_square.bmp
[ 2071] rcle_edgeonly_17x17.bmp
[ 2336] n=1;reg00=reg00+.05;ss=reg00;
[ 2369] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 2582] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 2768] Acko.net: Texer II
[ 2808] v5_square.bmp
[ 2823] rcle_edgeonly_17x17.bmp
[ 3088] n=1;reg00=reg00+.05;ss=reg00;
[ 3121] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 3334] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 3520] Acko.net: Texer II
[ 3560] v5_square.bmp
[ 3575] rcle_edgeonly_17x17.bmp
[ 3840] n=1;reg00=reg00+.05;ss=reg00;
[ 3873] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 4086] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 4272] Acko.net: Texer II
[ 4312] v5_square.bmp
[ 4327] rcle_edgeonly_17x17.bmp
[ 4592] n=1;reg00=reg00+.05;ss=reg00;
[ 4625] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 4838] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 5024] Acko.net: Texer II
[ 5064] v5_square.bmp
[ 5079] rcle_edgeonly_17x17.bmp
[ 5344] n=1;reg00=reg00+.05;ss=reg00;
[ 5377] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 5590] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 5776] Acko.net: Texer II
[ 5816] v5_square.bmp
[ 5831] rcle_edgeonly_17x17.bmp
[ 6096] n=1;reg00=reg00+.05;ss=reg00;
[ 6129] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 6342] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 6528] Acko.net: Texer II
[ 6568] v5_square.bmp
[ 6583] rcle_edgeonly_17x17.bmp
[ 6848] n=1;reg00=reg00+.05;ss=reg00;
[ 6881] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 7094] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 7280] Acko.net: Texer II
[ 7320] v5_square.bmp
[ 7335] rcle_edgeonly_17x17.bmp
[ 7600] n=1;reg00=reg00+.05;ss=reg00;
[ 7633] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 7846] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 8032] Acko.net: Texer II
[ 8072] v5_square.bmp
[ 8087] rcle_edgeonly_17x17.bmp
[ 8352] n=1;reg00=reg00+.05;ss=reg00;
[ 8385] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 8598] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 8784] Acko.net: Texer II
[ 8824] v5_square.bmp
[ 8839] rcle_edgeonly_17x17.bmp
[ 9104] n=1;reg00=reg00+.05;ss=reg00;
[ 9137] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 9350] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 9536] Acko.net: Texer II
[ 9576] v5_square.bmp
[ 9591] rcle_edgeonly_17x17.bmp
[ 9856] n=1;reg00=reg00+.05;ss=reg00;
[ 9889] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 10102] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 10288] Acko.net: Texer II
[ 10328] v5_square.bmp
[ 10343] rcle_edgeonly_17x17.bmp
[ 10608] n=1;reg00=reg00+.05;ss=reg00;
[ 10641] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 10854] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 11040] Acko.net: Texer II
[ 11080] v5_square.bmp
[ 11095] rcle_edgeonly_17x17.bmp
[ 11360] n=1;reg00=reg00+.05;ss=reg00;
[ 11393] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 11606] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 11792] Acko.net: Texer II
[ 11832] v5_square.bmp
[ 11847] rcle_edgeonly_17x17.bmp
[ 12112] n=1;reg00=reg00+.05;ss=reg00;
[ 12145] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 12358] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 12544] Acko.net: Texer II
[ 12584] v5_square.bmp
[ 12599] rcle_edgeonly_17x17.bmp
[ 12864] n=1;reg00=reg00+.05;ss=reg00;
[ 12897] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 13110] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 13296] Acko.net: Texer II
[ 13336] v5_square.bmp
[ 13351] rcle_edgeonly_17x17.bmp
[ 13616] n=1;reg00=reg00+.05;ss=reg00;
[ 13649] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 13862] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 14048] Acko.net: Texer II
[ 14088] v5_square.bmp
[ 14103] rcle_edgeonly_17x17.bmp
[ 14368] n=1;reg00=reg00+.05;ss=reg00;
[ 14401] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 14614] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 14800] Acko.net: Texer II
[ 14840] v5_square.bmp
[ 14855] rcle_edgeonly_17x17.bmp
[ 15120] n=1;reg00=reg00+.05;ss=reg00;
[ 15153] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 15366] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 15552] Acko.net: Texer II
[ 15592] v5_square.bmp
[ 15607] rcle_edgeonly_17x17.bmp
[ 15872] n=1;reg00=reg00+.05;ss=reg00;
[ 15905] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 16118] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 16304] Acko.net: Texer II
[ 16344] v5_square.bmp
[ 16359] rcle_edgeonly_17x17.bmp
[ 16624] n=1;reg00=reg00+.05;ss=reg00;
[ 16657] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 16870] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 17056] Acko.net: Texer II
[ 17096] v5_square.bmp
[ 17111] rcle_edgeonly_17x17.bmp
[ 17376] n=1;reg00=reg00+.05;ss=reg00;
[ 17409] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 17622] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 17808] Acko.net: Texer II
[ 17848] v5_square.bmp
[ 17863] rcle_edgeonly_17x17.bmp
[ 18128] n=1;reg00=reg00+.05;ss=reg00;
[ 18161] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 18374] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 18560] Acko.net: Texer II
[ 18600] v5_square.bmp
[ 18615] rcle_edgeonly_17x17.bmp
[ 18880] n=1;reg00=reg00+.05;ss=reg00;
[ 18913] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 19126] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 19312] Acko.net: Texer II
[ 19352] v5_square.bmp
[ 19367] rcle_edgeonly_17x17.bmp
[ 19632] n=1;reg00=reg00+.05;ss=reg00;
[ 19665] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 19878] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 20064] Acko.net: Texer II
[ 20104] v5_square.bmp
[ 20119] rcle_edgeonly_17x17.bmp
[ 20384] n=1;reg00=reg00+.05;ss=reg00;
[ 20417] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 20630] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 20816] Acko.net: Texer II
[ 20856] v5_square.bmp
[ 20871] rcle_edgeonly_17x17.bmp
[ 21136] n=1;reg00=reg00+.05;ss=reg00;
[ 21169] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 21382] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 21568] Acko.net: Texer II
[ 21608] v5_square.bmp
[ 21623] rcle_edgeonly_17x17.bmp
[ 21888] n=1;reg00=reg00+.05;ss=reg00;
[ 21921] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 22134] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 22320] Acko.net: Texer II
[ 22360] v5_square.bmp
[ 22375] rcle_edgeonly_17x17.bmp
[ 22640] n=1;reg00=reg00+.05;ss=reg00;
[ 22673] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 22886] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 23072] Acko.net: Texer II
[ 23112] v5_square.bmp
[ 23127] rcle_edgeonly_17x17.bmp
[ 23392] n=1;reg00=reg00+.05;ss=reg00;
[ 23425] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 23638] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 23824] Acko.net: Texer II
[ 23864] v5_square.bmp
[ 23879] rcle_edgeonly_17x17.bmp
[ 24144] n=1;reg00=reg00+.05;ss=reg00;
[ 24177] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 24390] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 24576] Acko.net: Texer II
[ 24616] v5_square.bmp
[ 24631] rcle_edgeonly_17x17.bmp
[ 24896] n=1;reg00=reg00+.05;ss=reg00;
[ 24929] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 25142] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 25328] Acko.net: Texer II
[ 25368] v5_square.bmp
[ 25383] rcle_edgeonly_17x17.bmp
[ 25648] n=1;reg00=reg00+.05;ss=reg00;
[ 25681] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 25894] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 26080] Acko.net: Texer II
[ 26120] v5_square.bmp
[ 26135] rcle_edgeonly_17x17.bmp
[ 26400] n=1;reg00=reg00+.05;ss=reg00;
[ 26433] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 26646] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 26832] Acko.net: Texer II
[ 26872] v5_square.bmp
[ 26887] rcle_edgeonly_17x17.bmp
[ 27152] n=1;reg00=reg00+.05;ss=reg00;
[ 27185] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 27398] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 27584] Acko.net: Texer II
[ 27624] v5_square.bmp
[ 27639] rcle_edgeonly_17x17.bmp
[ 27904] n=1;reg00=reg00+.05;ss=reg00;
[ 27937] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 28150] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 28336] Acko.net: Texer II
[ 28376] v5_square.bmp
[ 28391] rcle_edgeonly_17x17.bmp
[ 28656] n=1;reg00=reg00+.05;ss=reg00;
[ 28689] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 28902] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 29088] Acko.net: Texer II
[ 29128] v5_square.bmp
[ 29143] rcle_edgeonly_17x17.bmp
[ 29408] n=1;reg00=reg00+.05;ss=reg00;
[ 29441] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 29654] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 29840] Acko.net: Texer II
[ 29880] v5_square.bmp
[ 29895] rcle_edgeonly_17x17.bmp
[ 30160] n=1;reg00=reg00+.05;ss=reg00;
[ 30193] cd=above(ss,1); | cd2=equal(ss,0); | ss=if(cd,-1,ss+reg01); | sizex=abs(ss)*reg03; | sizey=sizex; | gs=if(cd2,reg04,gs); | rr=if(cd2,rand(100)*.01,rr); | gg=
[ 30406] px=if(cd2,rand(100)*.01-.5,px); | py=if(cd2,rand(100)*.01-.5,py); | mx=if(cd2,reg05,mx); | my=if(cd2,reg06,my); | x=px*gs+mx; | y=py*gs+my; | red=rr*reg02;
[ 30605] r=r+$pi*.25;
[ 30687] AVS 2.8+ Effect List Config
[ 30826] AVS 2.8+ Effect List Config
[ 31753] AVS 2.8+ Effect List Config
[ 31814] y=i*2-1; | x=0; | red=-i*.2+.23; | green=red*.6; | blue=red*.1;
[ 32000] AVS 2.8+ Effect List Config
[ 32849] AVS 2.8+ Effect List Config
[ 32971] Holden03: Convolution Filter
[ 33231] Holden03: Convolution Filter
======================================================================
FILE: 1P471LuTiJMm... (14803 bytes)
======================================================================
[ 0] Nullsoft AVS Preset 0.2
[ 319] Jheriko: Global
[ 383] offbpm=200100; | offosc=900000;offosc2=901000;diff=0;offspec=902000;offspec2=903000; | offbeat=904000;ow=0;oh=0; | inittime=gettime(0); | initregs();pf3=p
[ 563] reg70 = 32; | | secs=2; //keep soundvalue average over ? seconds (more is smoother, less is more reactive) | //time related | ltime=gettime(time);time=ge
[ 4368] Misc: AVSTrans Automation
[ 4420] #define modg(fff) lcy=0;loop(hh2,yi=lcy*ihh; lcx=0; loop(ww2,xi=lcx*iww; fff; lcx=lcx+1; ); lcy=lcy+1;); | | #define modb(fff) lcy=0;loop(hh2,yi=lcy*
[ 7868] r= i*$pi*2; | d=snd+.5; | x=sin(r)*d; | y=cos(r)*d; | snd = abs((mb(pc+avgoffset))); | red=green=blue=1; | pc=pc+1;
[ 7984] bands = reg70/2; | //background gradient & rolling avg getosc | //reg51 = bands; | iseconds = 1/seconds; | length = smppersec * seconds; | ilength = 1/len
[ 8995] smppersec = 40; | seconds = .2; width=0.05
[ 9072] r= i*$pi*2; | d=snd+.5; | x=sin(r)*d; | y=cos(r)*d; | snd = abs((mb(pc+avgoffset))); | red=green=blue=1; | pc=pc+1;
[ 9188] bands = reg70/2; | //background gradient & rolling avg getosc | //reg51 = bands; | iseconds = 1/seconds; | length = smppersec * seconds; | ilength = 1/len
[ 10199] smppersec = 40; | seconds = .1; width=0.05
[ 10304] loop(10, | x0=x;y0=y; | m=10; | m2=40; | | | dx = sin(y0*m)*.05; | dy = cos(x0*m)*.025; | y=y-dy;; | x=x-dx; | x = ((x*m2) |0) /m2; | y = ((y*m2) |0) /m2; | x
[ 10594] AVS 2.8+ Effect List Config
[ 10687] x0=x;y0=y; | m=10; | m2=40; | | x=x*.98; | y=y*.98; | dx = sin(y0*m)*.05; | dy = cos(x0*m)*.025; | y=y-dy;; | x=x-dx; | x = ((x*m2) |0) /m2; | y = ((y*m2) |0)
[ 10984] AVS 2.8+ Effect List Config
[ 11048] Acko.net: Texer II
[ 11088] _synth_dotfog16.bmp
[ 11108] nt-mask.bmp
[ 11368] // This example needs Maximum render mode | goff = 900000; goff2=800000;
[ 11443] loadsscregs(); loadsndregs() ; loadszregs(); | ww=reg70; iww=1/ww; | hh=ww; ihh=1/hh;; | n=ww*hh;nn=ww*hh; | | red=.1; | sz=.0003*sqrt(max(w*w,h*h)); | | |
[ 12714] dyt=getosc(.1,0,0)*.2;
[ 12740] indx =abs((cx-ww2));; | indy=abs(cy-hh2); | snd =sqrt( mb(indx+indy*ww)); | | x1=((cx*iww)-.5)*2+rx*.5; | z1=((cy*ihh)-.5)*2; | y1=-snd;y0=-y1+rz*.5; | d=.5
[ 13544] AVS 2.8+ Effect List Config
[ 14393] AVS 2.8+ Effect List Config
[ 14458] r=r+.1; | d=d*.9
[ 14543] AVS 2.8+ Effect List Config
======================================================================
FILE: 1fGxeQjPOzfU... (19106 bytes)
======================================================================
[ 0] Nullsoft AVS Preset 0.2
[ 37] keep tryin' | zamuz | | visbot.net
[ 94] reg00=getspec(.1,.1,0); | reg02=min(w,h)*.0035; | reg03=.035;
[ 162] n=0;reg01=0;
[ 240] AVS 2.8+ Effect List Config
[ 321] x=x+.002*sin(y*20); | y=y+.002*sin(x*20);
[ 399] r=r+.006*sin(d*20);
[ 455] Acko.net: Texer II
[ 495] v4_texer7.bmp
[ 775] n=1;cl=reg01;reg01=reg01+.05;
[ 808] gs=reg00; | cl=if(above(cl,1),0,cl+reg03); | cd=above(cl,1); | rs=if(cd,gs*3+.3,rs); | sizex=reg02*cl*rs; | sizey=sizex; | clr=if(cd,rand(2),clr);
[ 956] px=if(cd,(rand(100)*.001-.05)*15,px); | py=if(cd,(rand(100)*.001-.05)*15,py); | x=px; | y=py; | red=if(cd,0,1); | green=red; | blue=red;P
[ 1090] Acko.net: Texer II
[ 1130] v4_texer7.bmp
[ 1410] n=1;cl=reg01;reg01=reg01+.05;
[ 1443] gs=reg00; | cl=if(above(cl,1),0,cl+reg03); | cd=above(cl,1); | rs=if(cd,gs*3+.3,rs); | sizex=reg02*cl*rs; | sizey=sizex; | clr=if(cd,rand(2),clr);
[ 1591] px=if(cd,(rand(100)*.001-.05)*15,px); | py=if(cd,(rand(100)*.001-.05)*15,py); | x=px; | y=py; | red=if(cd,0,1); | green=red; | blue=red;P
[ 1725] Acko.net: Texer II
[ 1765] v4_texer7.bmp
[ 2045] n=1;cl=reg01;reg01=reg01+.05;
[ 2078] gs=reg00; | cl=if(above(cl,1),0,cl+reg03); | cd=above(cl,1); | rs=if(cd,gs*3+.3,rs); | sizex=reg02*cl*rs; | sizey=sizex; | clr=if(cd,rand(2),clr);
[ 2226] px=if(cd,(rand(100)*.001-.05)*15,px); | py=if(cd,(rand(100)*.001-.05)*15,py); | x=px; | y=py; | red=if(cd,0,1); | green=red; | blue=red;P
[ 2360] Acko.net: Texer II
[ 2400] v4_texer7.bmp
[ 2680] n=1;cl=reg01;reg01=reg01+.05;
[ 2713] gs=reg00; | cl=if(above(cl,1),0,cl+reg03); | cd=above(cl,1); | rs=if(cd,gs*3+.3,rs); | sizex=reg02*cl*rs; | sizey=sizex; | clr=if(cd,rand(2),clr);
[ 2861] px=if(cd,(rand(100)*.001-.05)*15,px); | py=if(cd,(rand(100)*.001-.05)*15,py); | x=px; | y=py; | red=if(cd,0,1); | green=red; | blue=red;P
[ 2995] Acko.net: Texer II
[ 3035] v4_texer7.bmp
[ 3315] n=1;cl=reg01;reg01=reg01+.05;
[ 3348] gs=reg00; | cl=if(above(cl,1),0,cl+reg03); | cd=above(cl,1); | rs=if(cd,gs*3+.3,rs); | sizex=reg02*cl*rs; | sizey=sizex; | clr=if(cd,rand(2),clr);
[ 3496] px=if(cd,(rand(100)*.001-.05)*15,px); | py=if(cd,(rand(100)*.001-.05)*15,py); | x=px; | y=py; | red=if(cd,0,1); | green=red; | blue=red;P
[ 3630] Acko.net: Texer II
[ 3670] v4_texer7.bmp
[ 3950] n=1;cl=reg01;reg01=reg01+.05;
[ 3983] gs=reg00; | cl=if(above(cl,1),0,cl+reg03); | cd=above(cl,1); | rs=if(cd,gs*3+.3,rs); | sizex=reg02*cl*rs; | sizey=sizex; | clr=if(cd,rand(2),clr);
[ 4131] px=if(cd,(rand(100)*.001-.05)*15,px); | py=if(cd,(rand(100)*.001-.05)*15,py); | x=px; | y=py; | red=if(cd,0,1); | green=red; | blue=red;P
[ 4265] Acko.net: Texer II
[ 4305] v4_texer7.bmp
[ 4585] n=1;cl=reg01;reg01=reg01+.05;
[ 4618] gs=reg00; | cl=if(above(cl,1),0,cl+reg03); | cd=above(cl,1); | rs=if(cd,gs*3+.3,rs); | sizex=reg02*cl*rs; | sizey=sizex; | clr=if(cd,rand(2),clr);
[ 4766] px=if(cd,(rand(100)*.001-.05)*15,px); | py=if(cd,(rand(100)*.001-.05)*15,py); | x=px; | y=py; | red=if(cd,0,1); | green=red; | blue=red;P
[ 4900] Acko.net: Texer II
[ 4940] v4_texer7.bmp
[ 5220] n=1;cl=reg01;reg01=reg01+.05;
[ 5253] gs=reg00; | cl=if(above(cl,1),0,cl+reg03); | cd=above(cl,1); | rs=if(cd,gs*3+.3,rs); | sizex=reg02*cl*rs; | sizey=sizex; | clr=if(cd,rand(2),clr);
[ 5401] px=if(cd,(rand(100)*.001-.05)*15,px); | py=if(cd,(rand(100)*.001-.05)*15,py); | x=px; | y=py; | red=if(cd,0,1); | green=red; | blue=red;P
[ 5535] Acko.net: Texer II
[ 5575] v4_texer7.bmp
[ 5855] n=1;cl=reg01;reg01=reg01+.05;
[ 5888] gs=reg00; | cl=if(above(cl,1),0,cl+reg03); | cd=above(cl,1); | rs=if(cd,gs*3+.3,rs); | sizex=reg02*cl*rs; | sizey=sizex; | clr=if(cd,rand(2),clr);
[ 6036] px=if(cd,(rand(100)*.001-.05)*15,px); | py=if(cd,(rand(100)*.001-.05)*15,py); | x=px; | y=py; | red=if(cd,0,1); | green=red; | blue=red;P
[ 6170] Acko.net: Texer II
[ 6210] v4_texer7.bmp
[ 6490] n=1;cl=reg01;reg01=reg01+.05;
[ 6523] gs=reg00; | cl=if(above(cl,1),0,cl+reg03); | cd=above(cl,1); | rs=if(cd,gs*3+.3,rs); | sizex=reg02*cl*rs; | sizey=sizex; | clr=if(cd,rand(2),clr);
[ 6671] px=if(cd,(rand(100)*.001-.05)*15,px); | py=if(cd,(rand(100)*.001-.05)*15,py); | x=px; | y=py; | red=if(cd,0,1); | green=red; | blue=red;P
[ 6805] Acko.net: Texer II
[ 6845] v4_texer7.bmp
[ 7125] n=1;cl=reg01;reg01=reg01+.05;
[ 7158] gs=reg00; | cl=if(above(cl,1),0,cl+reg03); | cd=above(cl,1); | rs=if(cd,gs*3+.3,rs); | sizex=reg02*cl*rs; | sizey=sizex; | clr=if(cd,rand(2),clr);
[ 7306] px=if(cd,(rand(100)*.001-.05)*15,px); | py=if(cd,(rand(100)*.001-.05)*15,py); | x=px; | y=py; | red=if(cd,0,1); | green=red; | blue=red;P
[ 7440] Acko.net: Texer II
[ 7480] v4_texer7.bmp
[ 7760] n=1;cl=reg01;reg01=reg01+.05;
[ 7793] gs=reg00; | cl=if(above(cl,1),0,cl+reg03); | cd=above(cl,1); | rs=if(cd,gs*3+.3,rs); | sizex=reg02*cl*rs; | sizey=sizex; | clr=if(cd,rand(2),clr);
[ 7941] px=if(cd,(rand(100)*.001-.05)*15,px); | py=if(cd,(rand(100)*.001-.05)*15,py); | x=px; | y=py; | red=if(cd,0,1); | green=red; | blue=red;P
[ 8075] Acko.net: Texer II
[ 8115] v4_texer7.bmp
[ 8395] n=1;cl=reg01;reg01=reg01+.05;
[ 8428] gs=reg00; | cl=if(above(cl,1),0,cl+reg03); | cd=above(cl,1); | rs=if(cd,gs*3+.3,rs); | sizex=reg02*cl*rs; | sizey=sizex; | clr=if(cd,rand(2),clr);
[ 8576] px=if(cd,(rand(100)*.001-.05)*15,px); | py=if(cd,(rand(100)*.001-.05)*15,py); | x=px; | y=py; | red=if(cd,0,1); | green=red; | blue=red;P
[ 8710] Acko.net: Texer II
[ 8750] v4_texer7.bmp
[ 9030] n=1;cl=reg01;reg01=reg01+.05;
[ 9063] gs=reg00; | cl=if(above(cl,1),0,cl+reg03); | cd=above(cl,1); | rs=if(cd,gs*3+.3,rs); | sizex=reg02*cl*rs; | sizey=sizex; | clr=if(cd,rand(2),clr);
[ 9211] px=if(cd,(rand(100)*.001-.05)*15,px); | py=if(cd,(rand(100)*.001-.05)*15,py); | x=px; | y=py; | red=if(cd,0,1); | green=red; | blue=red;P
[ 9345] Acko.net: Texer II
[ 9385] v4_texer7.bmp
[ 9665] n=1;cl=reg01;reg01=reg01+.05;
[ 9698] gs=reg00; | cl=if(above(cl,1),0,cl+reg03); | cd=above(cl,1); | rs=if(cd,gs*3+.3,rs); | sizex=reg02*cl*rs; | sizey=sizex; | clr=if(cd,rand(2),clr);
[ 9846] px=if(cd,(rand(100)*.001-.05)*15,px); | py=if(cd,(rand(100)*.001-.05)*15,py); | x=px; | y=py; | red=if(cd,0,1); | green=red; | blue=red;P
[ 9980] Acko.net: Texer II
[ 10020] v4_texer7.bmp
[ 10300] n=1;cl=reg01;reg01=reg01+.05;
[ 10333] gs=reg00; | cl=if(above(cl,1),0,cl+reg03); | cd=above(cl,1); | rs=if(cd,gs*3+.3,rs); | sizex=reg02*cl*rs; | sizey=sizex; | clr=if(cd,rand(2),clr);
[ 10481] px=if(cd,(rand(100)*.001-.05)*15,px); | py=if(cd,(rand(100)*.001-.05)*15,py); | x=px; | y=py; | red=if(cd,0,1); | green=red; | blue=red;P
[ 10615] Acko.net: Texer II
[ 10655] v4_texer7.bmp
[ 10935] n=1;cl=reg01;reg01=reg01+.05;
[ 10968] gs=reg00; | cl=if(above(cl,1),0,cl+reg03); | cd=above(cl,1); | rs=if(cd,gs*3+.3,rs); | sizex=reg02*cl*rs; | sizey=sizex; | clr=if(cd,rand(2),clr);
[ 11116] px=if(cd,(rand(100)*.001-.05)*15,px); | py=if(cd,(rand(100)*.001-.05)*15,py); | x=px; | y=py; | red=if(cd,0,1); | green=red; | blue=red;P
[ 11250] Acko.net: Texer II
[ 11290] v4_texer7.bmp
[ 11570] n=1;cl=reg01;reg01=reg01+.05;
[ 11603] gs=reg00; | cl=if(above(cl,1),0,cl+reg03); | cd=above(cl,1); | rs=if(cd,gs*3+.3,rs); | sizex=reg02*cl*rs; | sizey=sizex; | clr=if(cd,rand(2),clr);
[ 11751] px=if(cd,(rand(100)*.001-.05)*15,px); | py=if(cd,(rand(100)*.001-.05)*15,py); | x=px; | y=py; | red=if(cd,0,1); | green=red; | blue=red;P
[ 11885] Acko.net: Texer II
[ 11925] v4_texer7.bmp
[ 12205] n=1;cl=reg01;reg01=reg01+.05;
[ 12238] gs=reg00; | cl=if(above(cl,1),0,cl+reg03); | cd=above(cl,1); | rs=if(cd,gs*3+.3,rs); | sizex=reg02*cl*rs; | sizey=sizex; | clr=if(cd,rand(2),clr);
[ 12386] px=if(cd,(rand(100)*.001-.05)*15,px); | py=if(cd,(rand(100)*.001-.05)*15,py); | x=px; | y=py; | red=if(cd,0,1); | green=red; | blue=red;P
[ 12520] Acko.net: Texer II
[ 12560] v4_texer7.bmp
[ 12840] n=1;cl=reg01;reg01=reg01+.05;
[ 12873] gs=reg00; | cl=if(above(cl,1),0,cl+reg03); | cd=above(cl,1); | rs=if(cd,gs*3+.3,rs); | sizex=reg02*cl*rs; | sizey=sizex; | clr=if(cd,rand(2),clr);
[ 13021] px=if(cd,(rand(100)*.001-.05)*15,px); | py=if(cd,(rand(100)*.001-.05)*15,py); | x=px; | y=py; | red=if(cd,0,1); | green=red; | blue=red;l
[ 13155] Holden03: Convolution Filter
[ 14248] AVS 2.8+ Effect List Config
[ 14337] r=r+1; | d=d*.8;
[ 15150] AVS 2.8+ Effect List Config
[ 15239] r=r+1; | d=d*.8;
[ 16052] AVS 2.8+ Effect List Config
[ 16141] r=r+2; | d=d*.5;
[ 16978] AVS 2.8+ Effect List Config
[ 17067] r=r+2; | d=d*.5;
[ 17880] AVS 2.8+ Effect List Config
[ 18730] Channel Shift
[ 18787] alpha=y*.5+.5;
[ 18850] Holden03: Convolution Filter
======================================================================
FILE: 1mghJK8yDkXO... (17184 bytes)
======================================================================
[ 0] Nullsoft AVS Preset 0.2
[ 37] vorticity | brain activity remix | | original by synth-c | remix by zamuz | | visbot.net
[ 439] Misc: AVSTrans Automation
[ 491] #define $dt reg00 | #define $resize reg02 | #define $fps reg04 | #define $beat reg05 | #define $t reg06 | #define $debug reg20 | #define $playing reg30 | #de
[ 5275] Jheriko: Global
[ 5339] debug = 1; reg20 = debug; | ptime = gettime(0);reg70=0;
[ 5394] currenttime = gettime(0); | dt = currenttime-ptime; | ptime = currenttime; | reg00 = dt; | reg06 = gettime(0); | | | playtime = reg60 = gettime(-1); | | d
[ 5790] //background gradient & rolling avg getosc | reg51 = bands; | iseconds = 1/seconds; | length = smppersec * seconds; | ilength = 1/length; | | n=bands; | li
[ 6518] smppersec = 60; bands = 200; | seconds = .2; width=0.02;
[ 6610] //indexes | i=ic*itrail; index=((ic+ac+trail+1)%trail+parc*trail)*4; | // load Shape vector; | vec(Sh,gmb(index),gmb(index+1),gmb(index+2)); | | sub_vec(M
[ 7260] // trails | #define rotsines_vec(name,r) rx_=vec_##r##_x;ry_=vec_##r##_y;rz_=vec_##r##_z;rs_##name##_xs=-sin(rx_);rs_##name##_xc=cos(rx_);rs_##name##_y
[ 9718] if(above(timer,.2), | | timer = 0; | bc=bc+1; | if( above(bc,3) , | vec(L,rand2(),rand2(),rand2()); | bzr = rand2(); | bc=0 | ,0); | , | 0 | )
[ 9878] trail = 30; sndspd = 10; //sound mutliplier | refreshtime = 1/60; bc=5; | vec(L,rand2(),rand2(),rand2()); | normalize_vec(L,L); | fc=-1;
[ 11546] alpha=d*2-.2;
[ 11608] Holden03: Convolution Filter
[ 11868] Holden03: Convolution Filter
[ 12128] Holden03: Convolution Filter
[ 12388] Holden03: Convolution Filter
[ 12660] Acko.net: Texer II
[ 12700] _synth_dotfog16.bmp
[ 12980] // lights on trails
[ 13005] trail =reg50; itrail = 1/(trail-1); | nn=particles = reg51; ipart = 1/(nn-1); | n=trail*particles;; | off=600000; | pc=0;ic=0;parc=0; | | sqsz= sqrt(w*w+h*
[ 13182] i=ic*itrail; | pci=parc*ipart; | index=((ic+ac)%trail+parc*trail)*4; | gmbtovec(pc,off,Pr); | project_vec(Pr); | | x = x * $aspx; y = y * $aspy; | | snd = a
[ 13741] AVS 2.8+ Effect List Config
[ 13805] Acko.net: Texer II
[ 13845] v4_texer7.bmp
[ 14133] gs=.1*getspec(.1,.1,0); | sx=if(bx,sx+gs,sx-gs); | sy=if(by,sy+gs,sy-gs); | size=min(w,h)*.03; | sizex=size; | sizey=size;
[ 14254] bx=rand(2); | by=rand(2);E
[ 14282] x=.25*sin(sx); | y=.25*sin(sy); | red=.25; | green=red*.1; | blue=red*.5;P
[ 14355] Acko.net: Texer II
[ 14395] v4_texer7.bmp
[ 14683] gs=.1*getspec(.1,.1,0); | sx=if(bx,sx+gs,sx-gs); | sy=if(by,sy+gs,sy-gs); | size=min(w,h)*.03; | sizex=size; | sizey=size;
[ 14804] bx=rand(2); | by=rand(2);E
[ 14832] x=.25*sin(sx); | y=.25*sin(sy); | red=.25; | green=red*.1; | blue=red*.5;P
[ 14905] Acko.net: Texer II
[ 14945] v4_texer7.bmp
[ 15233] gs=.1*getspec(.1,.1,0); | sx=if(bx,sx+gs,sx-gs); | sy=if(by,sy+gs,sy-gs); | size=min(w,h)*.03; | sizex=size; | sizey=size;
[ 15354] bx=rand(2); | by=rand(2);G
[ 15382] x=.25*sin(sx); | y=.25*sin(sy); | blue=.25; | red=blue*.1; | green=blue*.5;P
[ 15457] Acko.net: Texer II
[ 15497] v4_texer7.bmp
[ 15785] gs=.1*getspec(.1,.1,0); | sx=if(bx,sx+gs,sx-gs); | sy=if(by,sy+gs,sy-gs); | size=min(w,h)*.03; | sizex=size; | sizey=size;
[ 15906] bx=rand(2); | by=rand(2);G
[ 15934] x=.25*sin(sx); | y=.25*sin(sy); | blue=.25; | red=blue*.1; | green=blue*.5;
[ 16099] AVS 2.8+ Effect List Config
[ 16260] AVS 2.8+ Effect List Config
[ 17077] sx=ceil(cos(x*80)); | sy=ceil(cos(y*80)); | x=x+.02*sy; | y=y-.02*sx;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 752 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 532 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 670 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 271 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 227 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 220 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 250 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

Some files were not shown because too many files have changed in this diff Show more