# FlyLo Filament · FFGL Effect Plugin

A constellation of glowing colored "nodes" connected by rainbow filaments.
Each node lives in a drifting position; its brightness is driven by the
local luminance + edge gradient of the input texture, so the nodes light
up wherever the performer is in frame — fingers, face, body — and dim
elsewhere. Strands between near-pairs of bright nodes carry chromatic
aberration so they read as fine multi-coloured threads.

Inspired by AR hand-tracking overlays, but the latching here is image-
based (input luma + edges), so it works on any source — webcam, prerendered
clip, generator — not just live skeletal tracking. The trade-off vs real
MediaPipe Hands: nodes gravitate to bright/edgey regions rather than
snapping to specific knuckles.

## Three distribution modes

| Mode | Layout | Good for |
|---|---|---|
| **Drift Grid** | uniform NxM grid with Lissajous wander | general use, framed-up shots |
| **Tight (hand-close)** | concentric golden-angle cluster near frame centre | hand close-ups, face shots |
| **Spread (body)** | Halton low-discrepancy distribution across 80% of frame | whole-body shots, group shots |

## 16 controls

| Param | Range | Purpose |
|---|---|---|
| **Mode** | 3-option | distribution / drift behaviour |
| **Node Count** | 0–1 → 6..32 | how many constellation points |
| **Node Drift Speed** | 0–1 | wander velocity per node |
| **Node Drift Range** | 0–1 | wander amplitude (~0..0.085 UV) |
| **Dot Size** | 0–1 | bright-core radius of each node |
| **Dot Glow** | 0–1 | halo size + brightness around the core |
| **Strand Thickness** | 0–1 | width of the connecting filaments |
| **Strand Max Length** | 0–1 | only connect node pairs closer than this (UV) |
| **Chromatic Split** | 0–1 | RGB aberration on the strands |
| **Hue Cycle Speed** | 0–1 | how fast the rainbow rotates over time |
| **Saturation** | 0–1 | HSV saturation |
| **Brightness** | 0–1 | HSV value |
| **Input Luma Gate** | 0–1 | how strongly input luma boosts node visibility |
| **Input Edge Gate** | 0–1 | how strongly Sobel edges boost node visibility |
| **Background Fade** | 0–1 | 0 = keep input fully, 1 = full black behind nodes |
| **Alpha** | 0–1 | output alpha |

## Install (drop-in to existing flylo-layer3-ffgl workspace)

1. Extract `FlyLoFilament/` from this zip into `flylo-layer3-ffgl/source/plugins/`
2. Add one line to `CMakeLists.txt` (alongside the other `add_ffgl_plugin(...)` calls):
   ```cmake
   add_ffgl_plugin(FlyLoFilament)
   ```
3. Build on Mac:
   ```bash
   cd flylo-layer3-ffgl
   cmake -B build -G Xcode
   cmake --build build --config Release
   # The .bundle lands in build/binaries/Release/
   cp -R build/binaries/Release/FlyLoFilament.bundle \
     "$HOME/Library/Application Support/Resolume Arena 7/Extra Effects/"
   ```
4. Restart Resolume. The plugin appears as **FlyLo Filament** in the FFGL effects list.

## Suggested first-use settings

**For a hand close-up (similar register to the Instagram reel reference):**
- **Mode**: Tight (hand-close)
- **Node Count**: ~0.6 (≈22 nodes)
- **Dot Size**: ~0.25 · **Dot Glow**: ~0.55
- **Strand Thickness**: ~0.20 · **Strand Max Length**: ~0.35
- **Chromatic Split**: ~0.55
- **Hue Cycle Speed**: ~0.15
- **Input Luma Gate**: ~0.55 · **Input Edge Gate**: ~0.50
- **Background Fade**: ~0.65 (the input shows through dimly behind the nodes)

**For a whole-body shot:**
- **Mode**: Spread (body)
- **Node Count**: ~0.85 (≈28 nodes)
- everything else mostly the same — push **Strand Max Length** to ~0.55 so far-apart nodes can connect

## Performance notes

- Pure single-pass fragment shader. CPU pre-computes node positions; shader does dot + strand rendering per pixel.
- Worst-case workload at MAX_NODES=32: ~32 dot tests + ~512 pair tests per pixel, both with early-outs. On a 5090 this is sub-millisecond at 1080p; on Apple Silicon M1+ it's ~3-5ms; on integrated graphics it'll struggle past ~720p. If you see FPS drops, reduce **Node Count** first.
- No feedback buffer — composes cleanly with other FFGL effects above or below in the layer stack.

## Why "node mesh on input" instead of real hand tracking?

Real MediaPipe Hands tracking inside an FFGL plugin would require embedding MediaPipe's C++ runtime, threading model, and ~30MB of dependencies — a multi-day engineering project. The image-driven approach here gives a similar visual signature (glowing colored dots clustering on the performer, connected by chromatic threads) without the complexity, and it has the side benefit of working on any input source, not just a live camera feed pointed at hands.

If you DO want true skeletal-tracking glowing nodes (snapped exactly to knuckles + fingertips), use the outboard **FlyLo Gesture FX** app and NDI into Resolume.
