Cellular Automata (Blender Geometry-Nodes)
This file provides a Geometry-Nodes setup for Cellular-Automata (CA) simulation.
This setup has been tested with Blender >=3.6.
For any inquiries or feedback, feel free to reach out on Twitter.
Check here for an introduction to cellular-automata.
Summary of the setup
There are three main node-trees, based on the number of dimensions of the simulation.
- cellular_automaton_1d
will run 1D CA based on the update rule set in the node-tree.
- cellular_automaton_2d
will run 2D CA.
- cellular_automaton_3D
will run 3D CA. High "Grid Size" values (e.g. >>50) can be very slow, so make sure to try first low values (and lower the value of other setups before moving to this one, to avoid Blender getting stuck).
For all setups, you can control the size with the first parameter. Note the setup defaults to equal size for each dimension, you will need to manually edit the node-tree if you want otherwise (for example a non-square grid for 2D).
"Keep Old States" is provided only for 1D and 2D, with the "Z Shift Delta" param controlling how much to shift the new layer (in addition to the basic grid size shift).
The MinCount and MaxCount for Born (inclusive) and Survive (exclusive) are the params that control the CA for 2D and 3D. The default for 2D correspond for Conway's Game of Life rules. For 3D is harder to find satisfying configs, the default values give something nice, but feel free to explore and share the results.
If an "Init Image" is provided, this will be used to set the initial state, otherwise each cell will be randomly initialized, the "Seed" controls such random initialization.
All setup returns a point cloud made up of only the active cells (with an age attribute too). You can apply other modifiers on top of it, for example "Instance on Points" or "Points to Volume".
The additional cellular_automaton_extra
setup contains the "growth along curve" and "empty effect" bits. You can play around and manually tweak them.
Technical Considerations
The sim is done by running a wrapped convolution that fetches all relevant neighbors states and sums them up. At the beginning we set the index of relevant neighbors for each cell as named attributes; via "Sample Nearest" run for every valid shift from the current position.
At each simulation run we then fetch all neighbors values via "Evaluate at Index". The named attributes are cleaned up when not needed anymore. Overall this is faster than running the convolution to find the neighbors indexes at every frame.