The shader here is not my work or idea; it is v buckenham's excellent r_g_b, remixed here for educational purposes.

Source: github.com/ludios/r_g_b

How it works (this is partly slop)

How the image changes

The image filters itself over and over. Each step uses the previous image to make the next, stored at the selected Bit depth.

For each pixel, the filter reads 25 samples in a 5×5 grid, spread out by Spacing and centered on that pixel, multiplies each by a weight, and adds the results. Each sample position is called a tap. The 25 taps and their weights make up the kernel.

Persistence mixes the result with the pixel’s old value. A negative setting makes the change larger instead. Each color channel is then clipped to the range 0–1. If stamping is on, the seeds are painted back over the result.

Starting a pattern

The kernel’s weights add up to 1, so a flat color stays flat. To get a pattern started, use Noise, paint, or seeds. You can also click the Frequency Response map to restart with a stripe pattern.

The default seeds are three dots: red, green and blue. They sit on a line through the center of the window, at 1/6, 1/2 and 5/6 of its longer dimension.

With Stamped every step on, the seeds are redrawn after each step. They stay put and keep feeding the pattern around them. With it off, they are drawn only at the start, then change like any other pixels.

Red, green and blue are processed separately. Against a dark-gray background, a red dot raises the red channel but lowers green and blue. That starts the channels in opposition: red against cyan.

Editing the kernel

The Hinton Diagram shows each weight as a square, its area proportional to the weight’s size. Hollow squares are negative. Past 1 or −1, a square stops growing and turns bronze.

Drag a square or type a value to change a weight. The middle one adjusts itself to keep the total at 1.

The taps’ offsets from the pixel run from −2 to 2 on each axis, multiplied by Spacing, with the resulting positions rounded to whole pixels. Because the filter reads only at these positions, fine stripes can look like wider ones to it. This is why the Frequency Response map roughly repeats.

Jitter gives each pixel a different spacing, fixed over time. This blurs the repeats and tends to favor the widest stripes.

Contrast scales each weight’s difference from 1/25. That is the weight every tap would have in an equal average.

Drift scales the kernel’s lopsided part. This can shift stripes and make them grow.

Mouse control of Contrast and Drift applies only to random kernels. Once you choose a preset or edit the kernel, Contrast and Drift return to 1× and the mouse leaves them alone.

Reading the Frequency Response map

The map estimates how much one step multiplies stripe contrast by, before clipping. Each position represents a stripe width and direction. The center is flat color; farther out, the stripes get finer.

Shaded areas have a multiplier above 1, so those stripes grow. Circles mark the fastest growth.

A step can also shift stripes. A shift of half a cycle swaps bright and dark. Hatched areas are close to that shift, so those patterns strobe.

Click anywhere on the map to restart the image with the corresponding stripes.

Keyboard controls

When no field, button, menu, link or section title has focus, Space pauses or plays, and Enter advances one step while paused. Z undoes a change to the kernel; Shift+Z redoes it.

In the Hinton Diagram, use the arrow keys to select a tap. Type a weight and press Enter to set it.

Why “tap”?

The name comes from FIR filters built as tapped delay lines. A signal passes through a chain of delays, and each tap takes a copy and multiplies it by a weight. Here, the taps read different positions in an image rather than different delays in a signal.

Presets
Time

Step 0.

Start
Seeds
Pixel size
Bit depth
Taps
0.0%
Kernel
Kernel
Number
to 1
3600 steps

Next kernel in 0 steps.

Hinton diagram
Drag or click to edit.Arrows choose a tap.
Dashed: 1 − the rest.
Frequency response
Middle: flat; edge: fine stripes.
Shaded: grows; hatched: inverts.

Pointer
Position changes

x: r_g_b.html sets Contrast while the kernel is random, rising evenly from 0.8× at the left edge to 3.8× at the right.

y: r_g_b.html sets Persistence from 0% at the top to almost 100% at the bottom, which all but freezes the image, and Spacing from 0.2 px to a third of the image’s height, at most 256 px. Both double every tenth of the way down, within those limits.

Click
View
UI