Skip to content

pkmiecinski/FieldGen

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FieldGen

Real-time GPU particle field generator inspired by Refik Anadol's fluid data sculptures. Drives 500K+ particles through a full 3D Navier-Stokes velocity field on the GPU, sharing the output with TouchDesigner via Syphon (macOS) or Spout (Windows) for live visuals.

What it does

FieldGen runs an 11-stage fluid simulation entirely on the GPU using Vulkan compute shaders:

  1. Inject — emits density and temperature into the field from a configurable source
  2. Forces — buoyancy, vortex confinement, cohesion, point/sphere/line/plane attractors, gravity
  3. Advect — semi-Lagrangian advection moves the field through itself
  4. Diffuse — Jacobi iteration for viscous diffusion
  5. Pressure solve — divergence → pressure (Jacobi) → gradient subtraction for incompressibility
  6. Boundary — clamps velocities and densities at domain edges
  7. Derived fields — computes vorticity/curl magnitude for coloring
  8. Particle advection — RK4 integration of 500K particles through the velocity field with gravity, emitter shapes, and attractor physics

The particle positions are packed into an RGBA texture and published over Syphon/Spout so TouchDesigner (or any Syphon/Spout client) can render them as geometry in real time.

Every parameter is controllable live via OSC on port 9000 — connect any OSC source (TouchDesigner CHOPs, iPad apps, Max/MSP, etc.) and all values are 0-1 with automatic internal remapping.

Features

  • Vulkan compute — all simulation runs on GPU compute shaders, zero CPU bottleneck
  • 500K particles with RK4 integration, gravity, and initial velocity on spawn
  • 48x48x48 Navier-Stokes solver — full incompressible fluid with pressure projection
  • 4 emitter shapes — volume, point, sphere surface, disc (for water/splash effects)
  • 4 attractor shapes — point, sphere, vertical line, horizontal plane
  • Syphon/Spout texture sharing to TouchDesigner, VDMX, Resolume, etc.
  • OSC control — 40+ parameters, all accepting 0-1 from TouchDesigner
  • Dear ImGui overlay — live diagnostics, system health, CFL monitoring, parameter readout
  • OpenGL preview — built-in particle rendering with additive blending

Requirements

  • Vulkan SDK 1.3+ — download here
    • macOS: uses MoltenVK (included in Vulkan SDK)
    • Windows: native Vulkan drivers
  • CMake 3.20+
  • C++20 compiler (Clang 14+, GCC 12+, MSVC 2022+)
  • Git (for cloning dependencies)
  • Xcode Command Line Tools (macOS only, for building Syphon)

Quick start

git clone https://github.com/pkmiecinski/FieldGen.git
cd FieldGen
./setup.sh

The setup script will:

  1. Check for Vulkan SDK, CMake, and glslc
  2. Clone dependencies (GLFW, GLM, oscpack, Dear ImGui, Syphon/Spout)
  3. Build Syphon framework (macOS) or set up Spout (Windows)
  4. Run CMake and build the project

Then run:

cd build
./fieldgen

Manual build

If you prefer to build manually:

# Clone dependencies
git clone --depth 1 --branch 3.4 https://github.com/glfw/glfw.git external/glfw
git clone --depth 1 --branch 1.0.1 https://github.com/g-truc/glm.git external/glm
git clone --depth 1 https://github.com/RossBencina/oscpack.git external/oscpack

# Build
mkdir -p build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j$(nproc)
./fieldgen

TouchDesigner integration

FieldGen publishes particle positions as an RGBA32F texture over Syphon (macOS) or Spout (Windows).

Receiving particles in TD

  1. Add a Syphon Spout In TOP — select "FieldGen_Particles"
  2. Add a TOP to SOP — this converts pixel colors to point positions
  3. Important: positions are encoded as 0-1 in the texture. Remap back to world space:
    • Add a Math TOP between Syphon In and TOP to SOP: set Range1 = 0, 1 and Range2 = -1, 1
    • Or in a GLSL TOP: vec3 pos = texture(...).rgb * 2.0 - 1.0
  4. Render the SOP with a Geometry COMP and point sprites

Sending OSC from TD

All parameters accept 0 to 1. Add an OSC Out CHOP pointing to localhost:9000:

OSC address What it controls
/fieldgen/inject/density Fluid density emission
/fieldgen/inject/temperature Temperature emission (drives buoyancy)
/fieldgen/inject/radius Emitter radius
/fieldgen/inject/x, y, z Emitter position
/fieldgen/forces/buoyancy Hot fluid rises
/fieldgen/forces/vortex Vortex confinement (swirl)
/fieldgen/forces/cohesion Particles attract to density
/fieldgen/forces/entropy Random perturbation in old regions
/fieldgen/attractor/x, y, z Attractor position
/fieldgen/attractor/strength Attractor pull force
/fieldgen/attractor/shape 0=point, 1=sphere, 2=line, 3=plane
/fieldgen/attractor/radius Sphere attractor size
/fieldgen/gravity/x, y, z Constant gravity (0.5 = zero)
/fieldgen/emit/shape 0=volume, 1=point, 2=sphere, 3=disc
/fieldgen/emit/dir_x, dir_y, dir_z Emit direction
/fieldgen/emit/speed Initial particle velocity
/fieldgen/emit/spread 0=tight stream, 1=random
/fieldgen/particles/strength Field influence on particles
/fieldgen/particles/damping Velocity damping
/fieldgen/particles/life Life decay rate
/fieldgen/particles/speed Max speed clamp
/fieldgen/viscosity Fluid viscosity
/fieldgen/diffuse_iters Diffuse solver iterations
/fieldgen/pressure_iters Pressure solver iterations

See MANUAL.md for the full parameter reference with visual descriptions.

UI controls

The GLFW window shows an ImGui overlay:

  • Diagnostics checkbox — shows system health, CFL number, field statistics, particle stats, recent OSC changes
  • Preview checkbox — enables built-in OpenGL particle rendering
  • Quit button — clean shutdown
  • ESC key — also quits

Project structure

FieldGen/
├── main.cpp                    # Application entry, OSC bindings, render loop
├── CMakeLists.txt              # Build configuration
├── setup.sh                    # One-step setup & build script
├── shaders/
│   ├── inject_sources.comp     # Density/temperature injection
│   ├── apply_forces.comp       # Buoyancy, vortex, attractor forces
│   ├── advect_field.comp       # Semi-Lagrangian advection
│   ├── diffuse.comp            # Jacobi viscous diffusion
│   ├── divergence.comp         # Divergence computation
│   ├── pressure_solve.comp     # Jacobi pressure solver
│   ├── gradient_subtract.comp  # Pressure gradient subtraction
│   ├── boundary.comp           # Domain boundary conditions
│   ├── derived_fields.comp     # Vorticity / curl magnitude
│   ├── particle_advect_v2.comp # Particle physics (RK4, gravity, emitters)
│   └── init_sdf.comp           # Signed distance field init
├── src/
│   ├── core/                   # Vulkan engine (device, buffers, pipelines)
│   ├── field/                  # Field generator, params, particle structs
│   ├── io/                     # OSC controller, Syphon/Spout sharing
│   ├── diagnostics/            # System health, ImGui overlay
│   └── render/                 # OpenGL preview renderer
├── TD/                         # TouchDesigner example project
├── MANUAL.md                   # Full parameter manual (plain English)
└── external/                   # Dependencies (gitignored, cloned by setup.sh)

License

MIT

About

Real-time GPU particle field generator — Vulkan compute, Navier-Stokes solver, 500K particles, Syphon/Spout to TouchDesigner, OSC control

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages