Skip to content

Commit f584dff

Browse files
REMvisualclaudehappy-otter
committed
docs: rewrite README with detailed parameter descriptions
Clean block-style parameter docs, removed tables. Covers all four pages: Motion, Range, Axes, Advanced. Includes per-axis range and the math section. Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
1 parent 41d7135 commit f584dff

1 file changed

Lines changed: 36 additions & 44 deletions

File tree

README.md

Lines changed: 36 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
Ornstein-Uhlenbeck brownian motion for TouchDesigner. A Script CHOP that generates smooth, mean-reverting procedural noise — perfect for organic camera drift, floating objects, generative motion, and anything that needs to feel alive.
77

8-
<!-- Add a screenshot or GIF here -->
98
<!-- ![Preview](assets/preview.gif) -->
109

1110
## What It Does
@@ -19,64 +18,59 @@ Unlike random noise, Ornstein-Uhlenbeck motion always pulls back toward center
1918
- **Deterministic** — set a seed for repeatable motion
2019
- **Headless-tested** — 20 automated tests validate the math at extreme parameters
2120

21+
## Install
22+
23+
1. **[Download the .tox](https://github.com/REMvisual/touchdesigner-brownian-motion/releases/latest)** from Releases
24+
2. Drag into your TouchDesigner project
25+
3. Wire the CHOP output to whatever needs motion
26+
27+
Outputs three channels: `tx`, `ty`, `tz`.
28+
2229
## Parameters
2330

2431
### Motion
2532

26-
| Parameter | Default | Description |
27-
|-----------|---------|-------------|
28-
| **Range Min / Max** | `-1` / `1` | Output bounds. The normalized [-1, 1] motion gets mapped to this range. Default [-1, 1] means output matches the raw sim. Set to [0, 100] and your channels wander between 0 and 100. |
29-
| **Speed** | `1.0` | How fast time passes for the simulation. Speed=1 is real-time. Speed=5 means the OU process evolves 5x faster — more ground covered per frame. Transitions are smoothed so dragging the slider doesn't cause jumps. |
30-
| **Amplitude** | `1.0` | Output multiplier (0 = no motion). |
31-
| **Reversion** | `2.0` | How strongly the motion pulls back toward the center point (theta in the OU process). High values = tight orbit around center, snaps back quickly. Low values = lazy wandering, barely cares about center. Zero = pure Brownian motion, no pull at all. |
32-
| **Roughness** | `0.5` | Controls the smoothing filter on the output. 0 = very smooth, flowing motion (spring with ~2s settling). 0.5 = moderate. 1 = raw unfiltered OU, no spring at all. Doesn't affect speed, just the texture of the motion. |
33+
**Range Min / Range Max** `[-1, 1]`
34+
Output bounds. The normalized [-1, 1] motion gets mapped to this range. Default [-1, 1] means output matches the raw sim. Set to [0, 100] and your channels wander between 0 and 100.
3335

34-
### Range
36+
**Speed** `1.0`
37+
How fast time passes for the simulation. Speed=1 is real-time. Speed=5 means the OU process evolves 5x faster — more ground covered per frame. Transitions are smoothed so dragging the slider doesn't cause jumps.
3538

36-
| Parameter | Default | Description |
37-
|-----------|---------|-------------|
38-
| **Per-Axis Range** | Off | Toggle to set different min/max per axis. |
39-
| **Range Min / Max** | `-1` / `1` | Uniform output bounds (shown when Per-Axis Range is off). |
40-
| **Range Min/Max X** | `-1` / `1` | X axis bounds (shown when Per-Axis Range is on). |
41-
| **Range Min/Max Y** | `-1` / `1` | Y axis bounds (shown when Per-Axis Range is on). |
42-
| **Range Min/Max Z** | `-1` / `1` | Z axis bounds (shown when Per-Axis Range is on). |
39+
**Amplitude** `1.0`
40+
Output multiplier. 0 = silence, 1 = full range. Useful for fading motion in and out.
4341

44-
### Axes
42+
**Reversion** `2.0`
43+
How strongly the motion pulls back toward the center point (theta in the OU equation). High values = tight orbit around center, snaps back quickly. Low values = lazy wandering, barely cares about center. Zero = pure Brownian motion, no pull at all.
4544

46-
| Parameter | Default | Description |
47-
|-----------|---------|-------------|
48-
| **Affect X / Y / Z** | All on | Per-axis enable toggles. |
45+
**Roughness** `0.5`
46+
Controls the smoothing filter on the output. 0 = very smooth, flowing motion (spring with ~2s settling). 0.5 = moderate. 1 = raw unfiltered OU, no spring at all. Doesn't affect speed, just the texture of the motion.
4947

50-
### Advanced
48+
### Range
5149

52-
| Parameter | Default | Description |
53-
|-----------|---------|-------------|
54-
| **Center X / Y / Z** | `0` | The point each axis drifts toward (in normalized [-1, 1] space). Default 0 = center of range. Set Center X to 0.5 and tx will hang out in the upper half of your range. |
55-
| **Seed** | `0` | Random seed for reproducibility. 0 = unseeded (different every time). Any other value = deterministic — same seed always produces the same motion after Reset. |
56-
| **Independent** | On | When ON (default), each axis gets its own random noise — tx, ty, tz move independently in 3D. When OFF, all three axes share the same noise value each step, so they move together in lockstep (motion along the diagonal). Useful if you want correlated movement across channels. |
57-
| **Reset** | - | Pulse to snap all channels back to their center positions and re-seed the RNG. Fresh start. |
50+
**Per-Axis Range** `Off`
51+
Toggle to set different min/max per axis. When off, all axes share the same Range Min/Max. When on, each axis gets its own bounds — useful when X needs [-180, 180] degrees but Y only needs [-10, 10].
5852

59-
## Install
53+
**Range Min/Max X, Y, Z** `[-1, 1]`
54+
Per-axis output bounds. Only visible when Per-Axis Range is on.
6055

61-
1. **[Download the .tox](https://github.com/REMvisual/touchdesigner-brownian-motion/releases/latest)** from Releases
62-
2. Drag into your TouchDesigner project
63-
3. Wire the CHOP output to whatever needs motion
56+
### Axes
6457

65-
## Architecture
58+
**Affect X / Y / Z** `All on`
59+
Per-axis enable toggles. Disabled axes output zero.
6660

67-
Everything lives in one file: `src/brownian_motion.py` — the `BrownianMotion` class (pure Python, no TD deps) and the Script CHOP callbacks together. To assemble in TouchDesigner:
61+
### Advanced
6862

69-
1. Create a Script CHOP
70-
2. Paste `src/brownian_motion.py` into its callbacks DAT
71-
3. Click "Setup Parameters" on the Script CHOP
63+
**Center X / Y / Z** `0`
64+
The point each axis drifts toward, in normalized [-1, 1] space. Default 0 = center of range. Set Center X to 0.5 and `tx` will hang out in the upper half of your range.
7265

73-
## Testing
66+
**Seed** `0`
67+
Random seed for reproducibility. 0 = unseeded (different every time). Any other value = deterministic — same seed always produces the same motion after Reset.
7468

75-
The math is validated by 20 headless pytest tests covering extreme speeds, ranges, edge cases, and numerical stability:
69+
**Independent** `On`
70+
When ON (default), each axis gets its own random noise — `tx`, `ty`, `tz` move independently in 3D. When OFF, all three axes share the same noise value each step, so they move together in lockstep (motion along the diagonal). Useful if you want correlated movement across channels.
7671

77-
```bash
78-
python -m pytest tests/test_brownian.py -v
79-
```
72+
**Reset** `Pulse`
73+
Snap all channels back to their center positions and re-seed the RNG. Fresh start.
8074

8175
## The Math
8276

@@ -88,9 +82,7 @@ dx = theta * (mu - x) * dt + sigma * sqrt(dt) * N(0,1)
8882

8983
Where `theta` is reversion strength, `mu` is center bias, and `sigma = 0.55 * sqrt(2*theta)` is tuned so the stationary distribution fills ~80% of the [-1,1] range.
9084

91-
A critically-damped second-order spring filter smooths the raw OU signal. The spring's natural frequency scales with speed so smoothing keeps pace with faster motion.
92-
93-
Sub-stepping (max 1/120s per step) ensures numerical stability at any speed.
85+
A **critically-damped second-order spring** filter smooths the raw OU signal. The spring's natural frequency scales with speed so smoothing keeps pace with faster motion. Sub-stepping (max 1/120s per step) ensures numerical stability at any speed.
9486

9587
## License
9688

0 commit comments

Comments
 (0)