Volver a Trabajo Herramienta propia

TD Shader Translator

Una app de escritorio que traduce shaders multi-pase de Shadertoy al formato GLSL TOP de TouchDesigner, e inyecta un sistema de 8 knobs y 8 pads listo para controlar en vivo. Es la herramienta que alimenta la librería de Sistema VJ GR.

ElectronReactTypeScriptGLSL

Shadertoy y TouchDesigner hablan variantes distintas de GLSL. Shadertoy separa un shader complejo en pases (Common, Buffer A-D, Image) con su propia convención de uniforms; el GLSL TOP de TouchDesigner espera otra estructura, y no entiende esa arquitectura multi-pase de forma nativa. Adaptar cada shader a mano, pase por pase, es lento y repetitivo.

Dos dialectos de GLSL que no se hablan

Artistas de TouchDesigner y VJs quieren aprovechar Shadertoy, la comunidad más grande de shaders open-source, sin reescribir cada uno a mano. No es solo un tema de sintaxis, es de arquitectura: un shader multi-pase de Shadertoy encadena buffers con su propia convención de texturas e inputs, y el GLSL TOP de TouchDesigner no entiende esa estructura de forma nativa.

Sin una herramienta que lo automatice, sumar un shader nuevo a un show en vivo significa horas de adaptación manual por cada uno.

Traducción automática, no manual

La app reconoce la arquitectura del shader original (uno o varios pases), reconstruye la cadena de Buffer A a D y el Image final manteniendo la coherencia de texturas entre pases (sTD2DInputs[]), e inyecta automáticamente las variables de sistema que TouchDesigner necesita para funcionar dentro de un GLSL TOP.

Antes de traducir, defino qué controla cada uno de los 8 knobs y 8 pads que voy a usar en vivo, con un nombre descriptivo real (uSpeed, uGlow, uZoom) en vez de uKnob1/uPad1 genéricos. La app inyecta esos uniforms al inicio de cada buffer activo, listos para mapear a un controlador MIDI sin tocar el código a mano.

// inyectado automáticamente por el traductor
uniform float uTime;
uniform vec2  uTDResolution;

// knobs con nombre descriptivo, no uKnob1/uKnob2
uniform float uSpeed;
uniform float uGlow;

out vec4 fragColor;

void main(){
  vec2 uv = vFragCoord.xy / uTDResolution.xy;
  vec3 color = palette(uv, uGlow);
  fragColor = TDOutputSwizzle(vec4(color, 1.0));
}

Stack técnico: Electron para empaquetar la app como ejecutable de escritorio (Windows y macOS, vía electron-builder), React + TypeScript para la interfaz, Monaco Editor (el mismo editor de VS Code) para escribir y revisar el GLSL traducido, y Zustand para el estado de la aplicación.

Prueba real: un shader de cinco pases, de Shadertoy a TouchDesigner

Para documentar la app la probé con «Game of life on a monitor», de Théo Goureau (licencia MIT): una escena 3D con cámara, luces y un Juego de la Vida en la pantalla de un monitor. Son cinco pases y unos 55.000 caracteres de GLSL. Este es el recorrido completo.

Escena 3D de un escritorio con un monitor mostrando el Juego de la Vida, renderizada en TouchDesigner
El resultado corriendo en TouchDesigner. «Game of life on a monitor» © 2023 Théo Goureau, licencia MIT.
Paso 01

Pegar cada pase y ver la traducción al instante

Cada pase del shader tiene su pestaña (Common, Buffer A–D, Image). A la izquierda va el código de Shadertoy y a la derecha aparece el GLSL listo para TouchDesigner, con los nombres ya adaptados: iTime pasa a ser uTime. El código compartido de Common se inyecta solo en cada buffer que lo usa.

Pestañas por pase: código de Shadertoy y GLSL traducido
Paso 02

Indicar qué lee cada pase

La app detecta qué canales usa cada pase y muestra una tarjeta por canal: imagen, audio, ruido, otro buffer, cubemap o volumen 3D. Si un buffer se lee a sí mismo, arma el feedback. En la captura, el Buffer D lee el B, el A, su propio frame anterior y una textura.

Tarjetas de canales con buffers, feedback y textura
Paso 03

Controles con nombre para tocar en vivo

Hasta 32 knobs y 32 pads con nombre propio (uCamaraVelocidad en vez de uKnob1), listos para mapear a un controlador MIDI, más audio reactivo y efectos de sistema en todos los shaders. La IA puede proponer los controles: lee el shader y sugiere qué parámetros vale la pena controlar, explicando qué hace cada uno.

Panel de controles: audio reactivo, knobs y pads
Knobs, pads y audio reactivo.
Controles propuestos por la IA con su descripción
Controles propuestos por la IA para este shader.
Paso 04

La red se arma sola en TouchDesigner

La app genera un script de Python que construye un GLSL TOP por buffer, con sus feedbacks, texturas y conexiones, y carga cada uniform con su expresión. Se copia, se corre en TouchDesigner y la red queda armada. Si el shader cambia, se vuelve a correr y actualiza los mismos nodos.

Ventana Script Vectors con los uniforms de cada buffer
Paso 05

Si algo falla, la IA lo corrige

Un pase no compiló: en Shadertoy la resolución tiene tres valores y en TouchDesigner dos, y el shader la pasaba a una función que esperaba tres. Pegué el error de TouchDesigner en «Debuggear con IA»: la app encontró la causa en el código original, la explicó y la corrigió con un clic. Con eso, la escena se ve igual que en Shadertoy.

Explicación del error y código corregido propuesto por la IA
Además

Herramientas para dejar cada shader listo para un show

Herramientas de IA: audio reactivo, cambios con palabras, optimizar y debug
Herramientas de IA de cada pase.
Galería de shaders guardados con buscador y miniaturas
Galería con más de 150 shaders.
  • Cambios con palabras"Que el zoom reaccione más al bombo" y la IA modifica el shader.
  • OptimizarUna versión más liviana, guardando también la original para comparar.
  • GaleríaBuscador, miniaturas y autoguardado para no perder ningún shader.
  • Otras fuentesEscenas de Synesthesia, links de Shadertoy y scripts de TouchDesigner ya armados.

Alimenta una librería de 120+ shaders en vivo

Esta herramienta es la que alimenta la librería de más de 120 shaders de Sistema VJ GR: cada shader nuevo que sumo al show en vivo pasa primero por este traductor, en uso real, no como prueba de concepto aislada.

Operar en vivo con lo traducido mostró que los nombres genéricos de control fallaban bajo presión de show, así que el naming descriptivo (uGlow en vez de uKnob3) terminó movido al centro del flujo de traducción, en vez de quedar como un paso manual posterior.

Podés ver el resultado en acción en Sistema VJ GR, o escribirme si necesitás herramientas a medida para tu propio flujo de trabajo creativo.