The feedback section represents a feedback frame buffer – an image, which can sample the previous iteration of itself or other feedback buffers. This is useful for simulating some phenomena such as cellular automata or fluid dynamics.

Its syntax can be one of:

feedback <name> = <initializer>;
feedback <name> = <initializer> : <modifier1, modifier2, ...>;

The available modifiers and initializers are listed below.

The previous frame of every feedback object is accessible as a 2D texture sampler with the feedback buffer's name in all GLSL functions that follow it. Use the full_range modifier whenever a range of 256 values between 0 and 1 is insufficient.


You can specify any subset of the following modifiers:

  • initialize(<function>) – specifies the function that computes the initial state of the buffer. It receives the position of the pixel between (0, 0) and (1, 1), and must return the value at that pixel as vec4.
    vec4 initializeFunction(vec2 position);
  • update_rate(<updates per second>) – sets how often the buffer is updated. If unset, it will be updated every frame, which are synchronized with the monitor's refresh rate.
  • synchronize(<parent feedback>) – synchronizes the feedback buffer with another buffer, so that this one is updated immediately after the other. Cannot be used together with update_rate.
  • filter(<filter mode>) – specifies the texture filtering mode for GLSL. The possible values are:
    • none / nearest – nearest neighbor resampling / no filtering
    • linear – linear filtering, no mipmaps (default)
    • bilinear – linear filtering with discrete mipmap steps
    • trilinear – linear filtering with linear mipmap transitions
    • anisotropic / anisotropicN – anisotropic filtering (N×)
  • map(<X mapping>, <Y mapping>) – specifies the texture mapping / wrapping. You can also supply only one argument to be used for both dimensions. The possible values are:
    • clamp – clamps the texture coordinate to <0, 1>
    • repeat / wrap – repeats the texture outside its bounds (default)
    • mirror – repeats the texture but every other repetition is mirrored
  • hidden(<true / false>) – do not create a window for the feedback and only use it as an intermediate output
  • resizable(<true / false>) – make the window resizable and the feedback buffer dynamically adapt to its size
  • full_range(<true / false>) – if enabled, the pixels will be stored in floating point format without clamping, allowing other shaders to sample the exact computed value at each pixel, but sacrificing some performance

glsl initializer

Initializes the feedback buffer with a GLSL update shader.

Its first argument is a GLSL function that will be evaluated at each pixel during the update. This function must have three parameters, the first one being the sampler2D reference to itself, the second one the vec2 position of the pixel between (0, 0) and (1, 1), and the third one the float time elapsed since the last update, in seconds. Its return value (vec4) will be stored in the buffer.

vec4 updateFunction(sampler2D self, vec2 position, float deltaTime);

The second argument specifies the dimensions of the buffer. You may as well pass the width and height separately as two arguments. Use sizeof(SomeImageOrAnimation) to make the buffer the same size as another object.


feedback MyFeedback = glsl(updateFunction, 256, 256) : initialize(initializeFunction), full_range(true);