Skip to content

Transformed feedback — fb_zoom, fb_rotate, fb_dx, fb_dy, fb_center_x, fb_center_y

The trails stage does not only dim the past — it moves it. Each frame the accumulation is resampled through a transform before this frame’s light is deposited on top, so the tail travels while it fades:

paramdefaultunitwhat it does
fb_zoom1factor per second> 1 pushes the past outward — a tunnel; < 1 pulls it in
fb_rotate0radians per secondspins the past — a spiral
fb_dx0frame-heights per secondslides the past sideways
fb_dy0frame-heights per secondslides the past vertically
fb_center_x0.5uv (0..1, left to right)the fixed point the three above turn about
fb_center_y0.5uv (0..1, top to bottom)the same, vertically

Every default is the identity, so a preset that binds none of these renders exactly what it did before they existed — and trails must be on for any of them to do anything, since they transform the accumulation the trails stage owns.

They are ordinary bindables, which is the point: fb_zoom = "1 + beat * 0.8" is a light tunnel that kicks on the beat.

The rates are per second, and they compose with dt. fb_zoom = 2 doubles the past’s scale every second however long a frame is; fb_rotate = 6.28 is one revolution a second. Do not reach for “per frame” values here — a 1.02 you tuned as a per-frame zoom is a barely-visible 2 %/s.

Translation is measured in frame heights, on both axes. fb_dx = 1 crosses a 16:9 frame horizontally in 1.78 s while fb_dy = 1 crosses it vertically in 1.0 s. That is deliberate: one isotropic vocabulary is what makes a diagonal drift a straight line and a rotation a rotation — not a shear — whatever the display’s shape.

What lies beyond the frame is nothing. A zoom-out, a drift, or a rotation about an off-centre point all pull in from outside the accumulation, and what arrives is transparent — the backdrop, showing through. It is not a smear of the edge pixel: that would compound into a permanent bar of colour along the border. So an fb_zoom < 1 reads as the picture receding into empty space, which is the depth cue you want; if you want something in that space, put it in bg_*.

Built from a8ce055 at version 0.115.0. This site tracks main and is not versioned per release.