Skip to content

Repository files navigation

pixel-goo

version homebrew tap

Goo-like particle system simulation running on the GPU.

Something similar to Sebastian Lague's Ant and Slime Simulations - particles following one another's trails, but without looking at the code.

Runs as a window (goo) or as an animated desktop wallpaper: goo-macwp on macOS, goo-wlwp on wayland (layer-shell), goo-x11wp on X11. Still being tinkered with, so expect the tunables to move around.

Install

Via Homebrew (macOS and Linuxbrew):

brew install lczyk/pixel-goo/goo

This installs the goo binary (plus goo-macwp, the desktop-wallpaper variant, on macOS).

If Homebrew refuses to load the tap with a trust error, it's the third-party tap gate (HOMEBREW_REQUIRE_TAP_TRUST). Trust it once and retry:

brew trust --tap lczyk/pixel-goo

Build from source

./nob.c              # show usage (default target)
./nob.c build        # compile bin/goo
./nob.c run          # build and run
./nob.c clean        # remove bin/ and the generated headers

./nob.c build-macwp  # macos wallpaper   -> bin/goo-macwp
./nob.c build-wlwp   # wayland wallpaper -> bin/goo-wlwp
./nob.c build-x11wp  # x11 wallpaper     -> bin/goo-x11wp

./nob.c shaders      # expand shader includes into shaders_pp/ and embed them, nothing else

Only goo is compiled in by default. The other sims are opt-in at build time:

GOO_SIM_POLLOCK=1 ./nob.c build                    # + the three-family sim
GOO_SIM_POLLOCK=1 GOO_SIM_BLANK=1 ./nob.c build    # + the blank reference sim as well

Configuration

There is more than one simulation, though a default build only carries goo -- see the build flags above. --core.sim picks between whichever ones were compiled in, and --help lists them.

pollock (GOO_SIM_POLLOCK=1) is three particle families that each sense only their own density field -- goo's force law three times over, differing in nothing but hue.

blank (GOO_SIM_BLANK=1) is one density channel, goo's repulsion on it, white particles, nothing else. It is there to be copied when starting a new sim (sim_blank.c implements the least a SimDef can and still draw), and as a control: if a change to core moves blank too, the change was core's.

With more than one compiled in, tab switches between them at runtime -- the physics cross-fades over --core.switch-frames rather than cutting. --core.switch-every auto-cycles, and on the wallpaper builds, which never take keyboard focus, SIGUSR1 does the same job. With only goo built, all three are no-ops.

Flags are namespaced by what owns them:

  • --core.* -- the shared simulation: particle count, render scale, the density field, the repel/exclusion field, drag, dither, colormap exposure, switching.
  • --goo.* -- the goo simulation itself: its trail field and the force it exerts.
  • --pollock.* -- the pollock simulation. Empty for now: its physics is entirely --core.* and its colours are fixed in the shader.
  • --window.* -- windowing and output: geometry, monitor, vsync, dump/headless.

Each simulation contributes its own flags, and every compiled-in sim's set is present whichever one is running -- picking a sim is a runtime decision, so they all have to resolve at startup. A sim left out at build time takes its flags with it. The density field is a core service each sim instantiates -- goo with one channel, pollock with one per family -- so every --core.dens-* parameter means the same thing in all of them. --core.dens-sub is defined per channel, which is what keeps a three-channel field at the same particle count, and so the same magnitude, as a single-channel one.

Short flags (-p, -d, -r, -m, -N) are unprefixed, as are --help, --version and --dump-params.

default-params.ini is the source of truth for the defaults and is baked into the binary at build time. Its [section] headers are the flag prefixes, so [goo] trail-tau = 6.15 is --goo.trail-tau=6.15 on the command line. Edit a value there, rebuild, and the default changes.

The resolved config can be printed and fed back in:

goo --dump-params              # print every resolved value as ini
goo --dump-params | goo -      # ... and run with it (a bare - reads config from stdin)

Layering is defaults, then stdin config, then command line -- later wins.

Autoformat

./nob.c format   # clang-format the top-level *.c/*.h (skips lib/)

ToDo's

  • automagically include shader files at compile time
  • fullscreen mode is still a bit janky
  • no acceleration and velocity shaders
  • no velocity double buffer
  • fix segfault buggs
  • ? add frame rendering
  • trail buffer colormap sampling
  • screen rendering shader could blend between density and trail colormap
  • ? better lerp in screen rendering shader

About

Goo-like particle system simulation running on the GPU

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages