Shaders

Noisemaker’s GPU rendering engine. Dual WebGL2 and WebGPU backends, a composable DSL for building effect chains, and a growing library of shader effects.


      
      
Loading...
Parameters

Project Structure

Shader development lives under shaders/:

shaders/
├── src/                      # Runtime, compiler, and backend code
├── effects/                  # Effect definitions
│   ├── synth/                # 2D generators
│   ├── filter/               # Image processors
│   ├── mixer/                # Blend/composite effects
│   ├── render/               # Rendering utilities (pointsEmit, pointsRender)
│   ├── points/               # Particle/agent simulations
│   ├── synth3d/              # 3D volumetric generators
│   ├── filter3d/             # 3D volumetric processors
│   ├── classicNoisedeck/     # Ported complex shaders
│   └── manifest.json         # Auto-generated effect registry
└── tests/                    # Test suites
demo/
└── shaders/                  # Interactive development UI

Each effect is a directory:

effects/filter/blur/
├── definition.js           # Effect definition
├── glsl/                    # WebGL 2 shaders
├── wgsl/                    # WebGPU shaders
└── help.md                  # Optional documentation

Double Buffering

Global surfaces (o0-o7, geo0-geo7) are double-buffered. Each has a read buffer and write buffer that swap at frame end.

Display surfaces (o0-o7) swap normally—previous frame’s write becomes current frame’s read.

State surfaces (textures with names containing xyz, vel, rgba, trail, or state) persist their bindings for simulation continuity.

See shaders/src/runtime/pipeline.js, specifically swapBuffers() and the surface creation code around line 376.

Multi-Pass Effects

Use internal textures (prefixed with _) to chain passes.

Example: filter/blur uses _blurTemp as intermediate storage between horizontal and vertical blur passes.

Pattern:

  1. Define internal texture in textures: { _temp: { ... } }

  2. Pass 1 writes to _temp

  3. Pass 2 reads from _temp, writes to outputTex

Feedback Effects

Read from previous output by copying to an internal texture each frame.

Example: filter/feedback uses _selfTex:

  1. Main pass reads inputTex + _selfTex, writes to outputTex

  2. Copy pass copies outputTex to _selfTex for next frame

Iteration

Use repeat: "uniformName" to run a pass multiple times per frame.

Example: synth/rd uses repeat: "iterations" on its simulate pass. The pipeline handles buffer swapping when a pass reads and writes the same texture.

Agent-Based Effects

Shared global textures pass state between effects in a chain.

Naming: Textures prefixed with global_ are shared across effects.

Example chain: pointsEmit().physarum().pointsRender()

  • pointsEmit creates global_xyz, global_vel, global_rgba

  • physarum reads and updates these textures

  • pointsRender uses global_xyz to scatter points to global_points_trail

MRT (Multiple Render Targets): Use drawBuffers: N for passes writing multiple textures.

Points rendering: Use drawMode: "points" and blend: true for scatter operations.

See: render/pointsEmit, render/pointsRender, points/physarum

Running Tests

npm run test:shaders              # All shader tests
npm run test:shaders:render       # Both backends

# Test harness for specific effects
node shaders/tests/test-harness.js --effects synth/noise --backend webgl2
node shaders/tests/test-harness.js --effects "synth/*" --backend webgpu

Development Workflow

npx http-server -p 8000
open http://localhost:8000/demo/shaders/

Regenerate manifest after adding/removing effects or changing texture definitions:

python shaders/scripts/generate_shader_manifest.py

When to regenerate: The manifest must be regenerated whenever you add or remove effect files, or modify texture definitions in definition.js. The manifest tracks all effects and their texture requirements for the runtime.

Bundle for distribution:

npm run bundle:shaders

Downstream Integration

Consumer projects vendor the built bundles from dist/.

Effect bugs and new effects belong in this repository. UI customization belongs downstream.