To add a new track to the visualizer, you must update the configuration in everything-is-visualized-worker.js and upload assets to R2.
In everything-is-visualized-worker.js, add an entry to the TRACKS object:
TRACKS['newtrack'] = {
name: 'NewTrack',
bpm: 128,
key: 'A Major',
symbol: 'Nt',
color: '#00ff00',
length: '4:30',
master: '8.NewTrack_Master.m4a',
images: ['NewTrack-Symbol-1000x1000.png', 'NewTrack-1000x1000.png'],
geometry: { name: 'Sphere', icon: '<svg>...</svg>' },
particleEffects: [0, 5, 10, 15] // 4 indices from the 28 available modes
};- R2 Binding: Create a new R2 bucket binding in Cloudflare named
NEWTRACK(all caps). - Upload Assets: Upload the
.m4aand.pngfiles directly to the new bucket. - Flat Bucket: Assets are served via filename lookup only; do not include folder paths in the bucket.
The visualizer uses a Modular ES6 Registry for shader injection and double-buffered scene handling.
File: modules/visualizer-config-effects.js
Add your new effect name to the EFFECT_KEYS array and a default value to EFFECT_DEFAULTS.
Choose the appropriate registry file:
- Vertex (Displacement):
modules/visualizer-shader-vertex.js - Fragment (Color/Post):
modules/visualizer-shader-fragment-core.js - Phase (Specific):
modules/visualizer-shader-phases.js
Example:
shaderRegistry.registerVertex('yourEffect', 'displacement', `
if (uEffects[getIdx('yourEffect')] > 0.01) {
float strength = uEffects[getIdx('yourEffect')];
pos += normal * sin(pos.y * 10.0 + uTime) * strength;
}
`);Always use getIdx('effectName') for index safety. The registry automatically injects this code into the main shader during scene initialization.
File: modules/visualizer-config-phases.js
{
name: 'YOUR_PHASE',
renderMode: 'standard', // Options: low_poly, translucent, particles_only, etc.
yourEffect: 1.0, // Intensity
motionMode: 0, // 0-26
cameraMode: 'standard', // Options: macro, observer, etc.
colorMode: 5, // 0-5
speed: 0.005, // Base animation speed
camZ: 3.5 // Camera distance
}Add the name to SHARED_PHASES or a specific track in TRACK_PHASES.
- GC FREE: Reuse all
THREE.Vector3andTHREE.Eulerobjects at module scope. UseMath.exporMath.powfor frame-rate independent smoothing. - No build step: All imports must use the
.jsextension. No npm packages. - Scene Isolation: Do not share state between
VisualizerSceneinstances. TheTransitionManagerhandles visual blending. - Audio Reactivity: Use
uAudioHistoryfor frequency history. Bass and Treble are pre-smoothed in theAudioController(seevisualizer-audio.js).