Lenia - 1st foray

Lenia - 1st foray
Lenia

Lenia was created some years ago by created by Bert Wang-Chak Chan as a system of continuous cellular automata – a form of artificial life. It was derived from Conway's Game of Life by making everything smooth, continuous and generalized.

My challenge was to take this shader from Shadertoy and port it into Touchdesigner, then expose its parameters to OSC so that I could send audio information from Max. Touchdesigner has its own awesome set-up for audio-reactivity, but I wanted to set something up from the Max side so I could later do some DSP right there. I am using separate laptops for Max and Touchdesigner in case the shader code and any effects I decide on get heavy on the GPU.

In this first demo, I am only using the audio descriptor of pitch confidence (FluCoMa via the Dataknot package). This was the lowest-hanging fruit because it sends out numbers from 0 - 1 from the start. Also, my sound source, the flute, was pitched based.

I scaled the incoming pitch confidence at different rates depending on where I sent it in the Lenia code. In the end, I plan to have 8 parameter changes ( a - h ) going to different target places in the matricies of the Lenia species set-up. In this instance, there are 4 x 4 matrices for:

  • betaLen: the number/index of kernel rings used for each interaction.
  • beta 0 - 2: kernel ring amplitudes. These values scale the (Gaussian) bell amplitude for that ring. Rings beyond betaLen are unused (height irrelevant).
  • mu: the target value of the local neighborhood average. Also can be thought of as the target density for the growth function. Growth is maximized when the kernel's neighborhood average equals mu, and becomes negative when far from mu.
  • sigma: controls the width of the Gaussian growth window. In other words, the width of the growth bell around mu. Smaller sigma → sharper peak → more sensitive to exact density. The last element (sentinel kernel) uses sigma=1 (growth near 0).
  • eta: growth weight for each kernel (growth * Gaussian). Its matrix determines how growth in one channel affects another channel. Specifically, the kernel's growth value is multiplied by eta before being accumulated into the destination channel's update. Higher eta → stronger / faster influence from this kernel. Sentinel (last element) is always 0 — no contribution.
  • relR: modifies the effective radius of a particular kernel/channel interaction. Allows different kernels to sense at different spatial scales within the same species. Actual pixel radius = relR * R

In this version, I called each parameter relRa, relRb, etc. because I thought I would only be modifying that matrix. I tried that but modifying too many made the simulation unstable they all died (a sad part of simulation experimentation). I decided to modify the other matrices as well, especially those that modify amplitude and growth. I will need to change these namings later to avoid confusion!

The scaling from 0 - 1 needed to be adjusted: all numbers going into beta0, beta1, relR I scaled either 0-1 -> 0.5-1. or 1-0 -> 0.45-0.8. I like using variations of reverse scaling (using both 0-1 and 1-0) to achieve variation. All numbers going into eta I scaled from 0-1 -> 0.1-0.3.

Here is the set-up I used in Max MSP. Again, I am going to need to change some parameter names (I at first thought of using sliders.) I will keep this for now, even though only using one descriptor. Others may come in handy 😺

Maxpatch sending OSC to Touchdesigner

Sources used:

Wikipedia article on Lenia

https://chakazul.github.io/lenia-CE/lenia.html? (cool interactive model!)

Comments in project: https://www.shadertoy.com/view/NflXDn (amazing implementation combined with particle system!)