Programa web para pinchar visuales con licencia GPL. https://ruidovisualab.com
|
|
13 hours ago | |
|---|---|---|
| css | 1 week ago | |
| data | 14 hours ago | |
| docs | 13 hours ago | |
| js | 14 hours ago | |
| models | 2 weeks ago | |
| scripts | 14 hours ago | |
| tests | 1 week ago | |
| tour | 1 week ago | |
| typo | 1 month ago | |
| .gitattributes | 4 weeks ago | |
| .gitignore | 2 weeks ago | |
| AGENTS.md | 14 hours ago | |
| CHANGELOG.md | 1 week ago | |
| LICENSE | 4 months ago | |
| LICENSE.es | 1 month ago | |
| README.en.md | 14 hours ago | |
| README.md | 14 hours ago | |
| audio.html | 1 week ago | |
| documentacion.md | 14 hours ago | |
| documentation.md | 14 hours ago | |
| favicon.ico | 1 week ago | |
| index.html | 1 week ago | |
| manual_de_usuario.md | 14 hours ago | |
| mapping.html | 4 weeks ago | |
| package.json | 14 hours ago | |
| projector.html | 4 weeks ago | |
| start-server.bat | 1 month ago | |
| start-server.sh | 1 month ago | |
| user_manual.md | 14 hours ago |
WebGL2-based VJ application, inspired by Resolume 2.4, that lets you mix and manipulate video in real time with visual effects and projection mapping. Built as a self-contained static website: no frameworks, no build tools, no Node.js dependencies. Just vanilla JavaScript with ES Modules.
License: GPL-3.0 · Version: 0.3.11
📘 To start using it, see the User Manual.
RVWVP is a VJ software that runs entirely in the browser. It mixes dynamic video layers in real time (with per-layer blend modes and RGB tint), applies the catalog's visual effects (40; the count comes from js/effect-registry.js) per layer or globally, and projects the output to an external window/monitor. It also includes a Mapping Mode that lets you project video onto polygonal regions of a facade image.
js/effect-registry.js):
typo/ folder (FontFace API; monospace fallback)docs/window.postMessage| Technology | Use |
|---|---|
| WebGL2 | Graphics and shader rendering on GPU |
| Web MIDI API | Support for physical MIDI controllers |
| Web Audio API | Audio playback, spectral analysis, effects, and BPM detection |
| Canvas Recording API | Video export/recording |
| getUserMedia | Webcam input as a video layer |
| FontFace API | Loading TYPO/ASCII fonts from typo/ |
| Vanilla JS (ES Modules) | Application logic — no frameworks |
Supported browsers: Chrome 90+, Firefox 88+, Safari 15+, Edge 90+ (require WebGL2). Recommended: Firefox (the testing browser). If something fails in your browser, report it to contacto(at)ruidovisualab.com.
Important: Do not open
index.htmldirectly from the file system. ES Modules require an HTTP server due to browser CORS restrictions.
Option A — Start script (recommended):
Linux/Mac:
./start-server.sh
Windows:
start-server.bat
The script detects Python, starts a server on port 8000, and tries to open the browser automatically.
Option B — Manual server:
python3 -m http.server 8000
Then visit: http://localhost:8000
You can use the production version published at https://ruidovisualab.com without installing anything.
Since this is a static website, deployment simply consists of copying all files (index.html, mapping.html, projector.html, audio.html, favicon.ico, js/, typo/, LICENSE) to the public directory of any web server. There is no build step.
With Nginx:
Copy the files to the server:
scp -r ./* user@your-vps:/var/www/rvwvp/
Configure a server block in Nginx:
server {
listen 80;
server_name rvwvp.yourdomain.com; # or the VPS IP
root /var/www/rvwvp;
index index.html;
# Correct MIME types for ES modules
location / {
try_files $uri $uri/ =404;
}
# Aggressive caching for JS modules (immutable between releases)
location /js/ {
add_header Cache-Control "public, max-age=31536000";
}
# Do not cache HTML (so changes show up instantly)
location ~ \.html$ {
add_header Cache-Control "no-cache";
}
}
Reload Nginx:
sudo nginx -t && sudo nginx -s reload
With Apache: copy the files to the DocumentRoot (e.g. /var/www/html/rvwvp/). Apache serves .js files with the correct MIME type by default.
With any static server (Caddy, serve, http-server, Netlify, Vercel...): just serve the project root directory.
Note on pop-up windows: the projector and the mapping editor use
window.open(). Some browsers block pop-ups unless they originate from a user gesture. The "Abrir Proyector" and "Mapping" buttons are direct user clicks, so they work; if your browser blocks them, add the domain to the pop-up exceptions.
The core of the design is the Effect Registry Pattern: a single file (js/effect-registry.js) is the single source of truth for the metadata of all effects —parameters, ranges, value transforms, shader uniform mappings—. Derived from this registry automatically: MIDI-mappable parameters, fader
automation configs and the initial per-layer effect state. The slider UI is NOT
generated automatically: each card lives by hand in index.html (a data-effect
button and data-effect-param controls that match the registry's sliderId).
Adding a new effect requires touching: its registry entry, its fragment in
shader-library.js, the compile line in compileBasicShaders() (webgl-renderer.js),
its id in EFFECT_ORDER with an apply<Id> method (or isGenerative) in
composition-service.js, and its card in index.html. The step-by-step recipe
lives in the "Añadir un efecto nuevo" route of the code tour.
Video frames (N layers)
│ getLayerTextures(gl) — raw texture per layer (UNPACK_FLIP_Y)
▼
renderer.processLayers()
│ applies per-layer effects via dedicated ping/pong FBOs
▼
renderer.composeLayers()
│ back-to-front shader-based composition (blend modes, opacity, RGB tint)
▼
Global layer (optional)
│ post-composition effects; its output composes by its mode, opacity and tint
▼
Global intensity (optional)
│ RGB multiplier 0.0–2.0
▼
renderToScreen() → #output-canvas (1280×720)
│
└─→ transferable createImageBitmap() ~60fps → projector.html
└─→ captureStream() → MediaRecorder → WebM/MP4 recording
When mappingMode is active, render() switches routes: instead of normal composition, it calls mappingRenderer.renderToCanvas(), which draws the facade image and projects each layer's video inside its assigned polygon (clipping by triangulation, affine mapping). Per-layer effects are still processed (processLayers with ensureFBOTextures), so the mapping respects the effects applied to each layer.
For a detailed explanation of each module and the data flow, see documentation.md.
Mapping Mode projects video onto polygonal regions of a facade image: you load the photo, draw up to three polygons, assign each one to a layer, and the output shows the facade with the video clipped and mapped inside its polygon. The editor opens with the "Mapping" button in the top bar and the mode keeps projecting when you close its window.
The step-by-step walkthrough is in the user manual §4; the protocol between the editor window and the main one is in documentation.md.
rvwvp/
├── index.html # Main control interface
├── audio.html # Advanced audio popup window (spectrum, mappings)
├── mapping.html # Mapping editor window (full screen)
├── projector.html # External projection window
├── favicon.ico # Site icon (at the root: that is where the browser asks)
├── start-server.sh # Start script (Linux/Mac)
├── start-server.bat # Start script (Windows)
├── LICENSE # GPL-3.0 (official English text)
├── LICENSE.es # License summary in Spanish
├── README.md # This README (Spanish)
├── README.en.md # This README (English)
├── manual_de_usuario.md # User manual (Spanish)
├── user_manual.md # User manual (English)
├── documentacion.md # Detailed technical documentation (Spanish)
├── documentation.md # Detailed technical documentation (English)
├── docs/
│ ├── preparacion_de_videos.md # Video preparation guide (Spanish)
│ ├── video_preparation.md # Video preparation guide (English)
│ ├── historial_de_refactorizacion.md # Refactoring history (Spanish)
│ ├── refactor_history.md # Refactoring history (English)
│ ├── RuidoVisual-midi-mapping-standard.json # Standard MIDI mapping (loadable)
│ ├── smoke-0.3.8-progreso.md # Browser validation log, step by step
│ ├── plans/ # Work plans: `refactors/` and `desarrollo/` (index in its README)
│ ├── auditoria/ # Published code audit reports (primary source)
│ ├── filosofia/ # Development philosophy (living document)
│ └── capturas/ # Manual screenshots (added manually)
├── typo/
│ ├── fonts.json # TYPO/ASCII font manifest (optional)
│ └── (fonts .ttf/.otf/.woff/.woff2, also in subfolders with licenses; not versioned — loaded at runtime)
└── js/ # ES modules (vanilla JS, no dependencies)
├── vj-app.js # Entry point / orchestrator
├── utils.js # Shared utilities (sanitization, mirror mapping)
├── blend-modes.js # Blend mode definitions (shader-based, active since 0.3.1)
├── effect-registry.js # Single source of truth: the effect catalog
├── font-loader.js # TYPO/ASCII font loading (FontFace API)
├── text-renderer.js # TYPO text and ASCII atlas rendering on 2D canvas
├── video-layer.js # Video layer (file/camera + texture)
├── layer-manager.js # Management of N dynamic layers
├── layer-effects.js # Per-layer effect state
├── midi-controller.js # Hardware MIDI support (fixed-layer mapping)
├── fader-automation.js # Fader automation (loop/bounce)
├── motion/ # Motion Control engine (per-layer keyframes)
│ ├── motion-easing.js # Easing curves (Linear/Ease-in/Ease-out/Smooth/Bounce)
│ ├── motion-clip.js # Pure clip model: keyframes, segments, JSON serialization
│ └── motion-service.js # REC sessions and per-layer playback (rAF)
├── project-manager.js # Project save/load (effects + MIDI + mapping + audio + modulation)
├── recorder-manager.js # Video/audio recording (MediaRecorder)
├── performance-monitor.js # FPS metrics
├── projector-window.js # Projection window logic
├── core/ # Cross-cutting core: state, events, DI, windows
│ ├── state-manager.js · events.js · service-container.js
│ └── window-manager.js · window-protocol.js
├── services/ # Domain services
│ ├── composition-service.js · layer-service.js · effect-service.js
│ └── output-service.js · renderer-interface.js
├── renderer/ # Render backend (WebGL2 today)
│ ├── webgl-renderer.js # WebGL2 rendering + per-layer FBOs
│ └── shader-library.js # GLSL shaders (vertex + fragment)
├── ui/ # UI facade and subcontrollers
│ └── ui-controller.js + ui-*.js
├── audio/ # Audio engine, window and modulation
│ └── audio-controller.js · audio-window.js · audio-registry.js · modulation-*.js
├── transitions/ # Layer transitions (swap model)
│ ├── transitions.js # Pure catalog: types, patterns, easing, validation
│ └── transition-service.js # Orchestration: state, roulette, fade and swap
├── 3d/ # 3D models (3D path, WebGPU/3D plan)
│ └── glb-parser.js # GLB/glTF 2.0 parser with no dependencies (phase A1)
├── guion/ # Scripting: scene document and coverage pass
│ ├── guion-model.js # Pure model: scenes, sanitizing and versioned JSON
│ ├── guion-service.js # Transport: loads, applies, chains and measures
│ ├── guion-applier.js # One scene applied to the engine (via the facade)
│ ├── guion-executor.js # Full pass: caption, report and state hygiene
│ ├── cobertura.js # Coverage generators derived from the catalogues
│ └── synthetic-source.js # Test pattern generated in memory (layer source)
└── mapping/ # Projection mapping subsystem
├── mapping-constants.js # Shared constants (default regions)
├── mapping-editor.js # Mapping broker: state + window + postMessage
├── mapping-editor-window.js # Visual editor in the separate window (viewer + SVG)
└── mapping-renderer.js # Mapping WebGL render (facade + polygons)
For a detailed description of each module's role, the data flow, and the mapping coordinate conventions, see documentation.md.
For the bounce effect (forward and backward playback) it is worth pre-processing the videos with FFmpeg instead of resolving it live: the guide with the command, the recommended formats and the rest of the tasks is in docs/video_preparation.md. For the same thing without a command line, two free tools: OBS Studio (its virtual camera simulates a webcam, so you can load any window or broadcast signal as a layer) and HandBrake (encode videos without typing commands).
Every tag in the repository is a complete snapshot of the project at a milestone: you can download it and run it exactly as it was at that time. The table of release versions, with its date and what each one includes, and the command to run a specific one, live in the CHANGELOG.
This project is licensed under GPL-3.0. See LICENSE (official text) and LICENSE.es (Spanish summary).
All shader code (GLSL), JavaScript modules, HTML, and CSS are distributed under the same license. The original author is Ruido Visual Lab.
RVWVP has been developed with an AI-assisted workflow using different systems over time:
.zcode/ cleanup, 2026-08-03): started using ZCode, with GLM 5.2 and DeepSeek Flash v4.How the work flows: I hand-review all the code and additionally do a peer review by cross-checking it against other models to spot nuances. DeepSeek (web version) has continuously supervised the work: in every iteration it explains parts of the code to me, while ZCode (or whichever code generator is in turn) executes the designs I had previously produced with DeepSeek's occasional help.
The code tour (data/tour.json + @code-tour: comments) is precisely what makes that audit possible: it enables self-review and third-party review of the skeleton and architectural design of each part of the program, and it can serve as the basis for practical, scripted training courses.
The development philosophy —the story of how the project got here, how the work is split between human and machine, what can and cannot be demonstrated about that supervision, and how human validation is dosed— is written up in docs/filosofia/filosofia_de_desarrollo.md (in Spanish).
Intermediate dates are approximate; the verifiable anchors in the git history are the first commit (2025-12-14) and the .zcode/ cleanup (2026-08-03).
RVWVP · Ruido Visual Lab Web-VJ Project · GPL-3.0