Shaders

Noisemaker’s GPU rendering engine provides WebGL2 and WebGPU backends. It includes 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 an internal texture in textures: { _temp: { ... } }

  2. Pass 1 writes to _temp

  3. Pass 2 reads from _temp and 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: Regenerate the manifest after any of these changes:

  • Adding effect files

  • Removing effect files

  • Changing 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.