This document details the implementation of recursive texture processing systems in TouchDesigner using Feedback TOP operators in conjunction with custom GLSL shaders. Such configurations enable the generation of complex temporal visual phenomena including trajectory trails, recursive diffusion patterns, and evolving procedural textures - all executed with full GPU acceleration for real-time performance capabilities.
The specific implementation described herein focuses on a compound transformation feedback system incorporating spatial scaling, rotational transformation, and temporal decay parameters, establishing a foundational framework for advanced real-time visual synthesis applications.
Part 1: The Feedback Loop
A feedback loop in TouchDesigner is built with a Feedback TOP:
[Source TOP]
↓
GLSL TOP ←──────────────┐
↓ │
Feedback TOP ─────────────┘
↓
Null TOP (OUT_FEEDBACK)
Step by step:
- Create a
Noise TOPas your seed texture (or any visual source). - Create a
GLSL TOP— this is where the effect lives. - Create a
Feedback TOP.- Set its Target TOP parameter to the path of the GLSL TOP (e.g.
glsl1). - This makes the Feedback TOP read from the GLSL TOP’s previous frame.
- Set its Target TOP parameter to the path of the GLSL TOP (e.g.
- Connect:
Noise TOP → input[0] of GLSL TOP,Feedback TOP → input[1] of GLSL TOP. - Connect the
GLSL TOPoutput to aNull TOP.
Now the shader receives both fresh input (slot 0) and last frame’s output (slot 1).
Part 2: The GLSL Shader
Open the GLSL TOP, go to its DAT and replace the pixel shader with:
uniform sampler2D sTD2DInputs[2]; // [0] = fresh source, [1] = feedback
uniform vec4 uTDOutputInfo;
// Uniforms (add these as Custom Parameters on the GLSL TOP)
uniform float uZoom; // e.g. 1.002
uniform float uRotation; // e.g. 0.001 (radians per frame)
uniform float uDecay; // e.g. 0.97 (how fast trails fade)
uniform vec2 uOffset; // e.g. 0.0, 0.0 (translate each frame)
out vec4 fragColor;
void main()
{
vec2 uv = vTD2DInputCoord.st;
// Centre the UV so transforms are around the middle
vec2 centred = uv - 0.5;
// Apply rotation
float c = cos(uRotation);
float s = sin(uRotation);
centred = vec2(c * centred.x - s * centred.y,
s * centred.x + c * centred.y);
// Apply zoom (scale back toward centre)
centred /= uZoom;
// Apply translate offset
centred += uOffset;
// Return to 0-1 UV space
vec2 feedbackUV = centred + 0.5;
// Sample last frame's output, apply decay to fade trails
vec4 feedback = texture(sTD2DInputs[1], feedbackUV) * uDecay;
// Sample fresh source
vec4 fresh = texture(sTD2DInputs[0], uv);
// Combine: add new content on top of decayed history
fragColor = TDOutputSwizzle(max(fresh, feedback));
}Part 3: Adding Custom Parameters
For the uniforms to be tweakable, create Custom Parameters on the GLSL TOP:
- Right-click the GLSL TOP → Customize Component…
- Add float parameters matching the uniform names:
uZoom— default1.002, range0.99–1.05uRotation— default0.001, range-0.05–0.05uDecay— default0.97, range0.5–1.0uOffset— default0, 0(XY float pair)
Now sliders appear on the parameter panel for live tweaking during performance.
Part 4: Driving with Audio
Audio Device In CHOP → Audio Spectrum CHOP → Analyze CHOP (RMS)
→ Math CHOP (remap: e.g. 0→1 becomes 1.000→1.008)
→ [CHOP reference onto GLSL TOP's uZoom custom parameter]
Kick drums push the zoom, creating the classic “zoom-in-on-beat” VJ effect.
Visual Variations
| Change | Effect |
|---|---|
uZoom > 1 | Content zooms in and expands outward — “into the abyss” |
uZoom < 1 | Content shrinks inward — imploding tunnel |
uRotation != 0 | Trails spiral |
uDecay close to 1 | Long, persistent trails |
uDecay close to 0.5 | Short, quickly fading traces |
Add sin(absTime.seconds) to uOffset | Drifting, oscillating trails |
Common Gotchas
- Feedback explodes to white →
uDecayis too high (≥ 1.0). Drop it to0.97. - Nothing feeds back → confirm the Feedback TOP’s Target TOP path is exactly the GLSL TOP’s name.
- Green/uniform shader errors → check the GLSL TOP’s
InfoOP for compile errors; common issue is uniform name mismatch. - 1-frame latency in the loop is unavoidable and is what makes feedback work — the Feedback TOP always serves the previous frame.
- For reaction-diffusion (Turing patterns), replace the simple zoom/rotate with a two-channel diffusion equation in the shader — a natural next step from this recipe.
Related Topics
- Feedback Loops — pure TOP-based feedback without GLSL
- Introduction to GLSL — GLSL fundamentals in TouchDesigner
Parameter Tuning & Behavior
| Parameter | Behavior |
|---|---|
| uZoom | >1.0 = trails expand outward (tunnel effect); <1.0 = trails shrink toward center. |
| uRotation | Higher = trails spiral rapidly; Zero = trails move in straight lines from the center. |
| uDecay | Higher (0.99) = trails stay on screen for a long time; Lower (0.8) = trails vanish quickly. |
| uOffset | Adds a directional “drift” to the feedback (e.g., trails always float upward). |
Network Architecture
To visualize how the data flows, here is a map of the final network:
[ SOURCE ]
Noise TOP (Seed) ──┐
│ (Input 0)
▼
[ FEEDBACK LOOP ] ──▶ [ GLSL TOP ] ──▶ [ Null TOP (OUT) ]
▲ (Input 1) │
│ │
└──── [ Feedback TOP ] ◄┘
▲
│ (Target: glsl1)
[ CONTROL ] │
Audio In ──▶ Analyze ──▶ Math ──▶ [ uZoom Parameter ]Data Flow Explanation
- Dual Input: The
GLSL TOPis the brain. It takes the current frame from theNoise TOP(Input 0) and the previous frame from theFeedback TOP(Input 1). - Shader Logic: Inside the GLSL code, we transform the feedback texture (rotate/zoom/offset) and then “mix” or “max” it with the fresh source.
- Recursive Loop: The
Feedback TOPis set to “target” the GLSL TOP. This means every frame, it grabs the output of the shader and feeds it back into Input 1 for the next frame. - Decay: The
uDecayparameter in the shader multiplies the feedback by a value like 0.97. This ensures that old trails eventually fade to black rather than staying on screen forever. - Audio Link: By mapping audio energy to
uZoom, the entire feedback “pulses” outward on every beat.
(y) Return to Recipes & Projects | (y) Return to Recipes & Projects | (y) Return to TouchDesigner | (y) Return to Home