Skip to content

Commit f61ee37

Browse files
committed
feat: experimental mathcode rain via p5.js (renderer=p5)
- js/p5-rain/main.js: instance-mode sketch, 2D text columns, MATHCODE_GLYPHS from three-rain/glyphs.js - version mathcode_p5; parseRenderer accepts p5 / p5js / p5.js - scripts/vendor-p5.mjs + lib/p5.min.js; postinstall; SW cache; Holoplay rejects p5 like three - Docs: RENDERING, RENDERING_PIPELINE, SECURITY (LGPL), DEPENDENCY_POLICY, README, DEV_README, Copilot - tests/matrix-p5-rain.spec.js Made-with: Cursor
1 parent b3642c3 commit f61ee37

16 files changed

Lines changed: 272 additions & 22 deletions

.copilot/instructions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ When adding features that span multiple windows/displays:
341341
342342
These complement `.github/copilot-instructions.md` (treat that file as the detailed source of truth).
343343
344-
- **Renderers**: `js/webgl/` (GLSL + regl **temporarily**, vendored `lib/regl.min.js`) and `js/webgpu/` (WGSL). URL `renderer=regl` is a legacy alias for WebGL. Holoplay / Looking Glass is **WebGL-only** — see [RENDERING.md](../RENDERING.md), [HOLOPLAY.md](../HOLOPLAY.md), and [DEPENDENCY_POLICY.md](../DEPENDENCY_POLICY.md).
344+
- **Renderers**: `js/webgl/` (GLSL + regl **temporarily**, vendored `lib/regl.min.js`) and `js/webgpu/` (WGSL). Experimental: `renderer=three` (`js/three-rain/`), `renderer=p5` (`js/p5-rain/`). URL `renderer=regl` is a legacy alias for WebGL. Holoplay / Looking Glass is **WebGL-only** — see [RENDERING.md](../RENDERING.md), [RENDERING_PIPELINE.md](../RENDERING_PIPELINE.md), [HOLOPLAY.md](../HOLOPLAY.md), and [DEPENDENCY_POLICY.md](../DEPENDENCY_POLICY.md).
345345
- **Tests**: `npm test` runs Node tests + Playwright smoke tests; `npm run test:regression` is the full mode×effect matrix (slow). Failures on `[Matrix][WebGL]` console lines are intentional.
346346
- **PWA cache names**: Not just `matrix-v{version}` — the service worker uses `matrix-sw-{scope}-v{VERSION}-{VER}`; `js/main.js` prints the matching string for debugging.
347347
- **GLSL**: Shared uniforms must match precision across vertex/fragment stages on some GPUs (`uniform mediump float` where shared). Shader sources are loaded as static strings after fetch (avoid undefined `shaderSource`).

DEPENDENCY_POLICY.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ This repository ships as **static files** (no app bundler). Anything we add must
3232

3333
- **npm `three`** + vendored **`lib/three.module.js`** power **`js/three-rain/`** only when **`renderer=three`** or the **`mathcode_alphabet_three`** version preset. This path is **not** a replacement for the MSDF rain pipeline; see **[RENDERING_PIPELINE.md](RENDERING_PIPELINE.md)**.
3434

35+
## Experimental: `p5` (p5.js)
36+
37+
- **npm `p5`** + vendored **`lib/p5.min.js`** (browser UMD) power **`js/p5-rain/`** when **`renderer=p5`** or **`version=mathcode_p5`**. **LGPL-2.1** — review `node_modules/p5/license.txt` before redistributing modified bundles. Not MSDF / bloom parity; see **[RENDERING_PIPELINE.md](RENDERING_PIPELINE.md)**.
38+
3539
## Removed (policy-compliant cleanup)
3640

3741
- `**twgl`**: Was listed as a dependency and copied to `lib/twgl-full.module.js` but **was not imported** by any application module. It has been **removed** entirely to avoid shipping unused third-party code.

DEV_README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ float alpha = smoothstep(0.5 - fwidth(distance), 0.5 + fwidth(distance), distanc
7676

7777
- 🔗 [regl on npm](https://www.npmjs.com/package/regl) / [regl docs](https://regl.party/)**temporary** WebGL runtime (`lib/regl.min.js`); see [DEPENDENCY_POLICY.md](DEPENDENCY_POLICY.md) and [migration_repl.md](migration_repl.md).
7878
- 🔗 [RENDERING.md](RENDERING.md) — WebGPU vs WebGL and Holoplay constraints.
79-
- 🔗 [RENDERING_PIPELINE.md](RENDERING_PIPELINE.md) — pass-based rain vs Three.js demo (`renderer=three`).
79+
- 🔗 [RENDERING_PIPELINE.md](RENDERING_PIPELINE.md) — pass-based rain vs experimental `renderer=three` / `renderer=p5` demos.
8080
- 🔗 [HOLOPLAY.md](HOLOPLAY.md) — Looking Glass HoloPlay Service client, vendored `holoplay-core`, code map, and upgrade notes.
8181
- 💡 **Philosophy**: Treat graphics as pure functions — given the same inputs, always produce the same output. Very Matrix-like in its deterministic perfection.
8282

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ _Variants_
3030
- [Bugs mode](https://ap0ught.github.io/matrix?version=bugs)
3131
- [Mathcode mode — mathematical symbols and arrows (∑∆∇∞≠≈∈∉ ←→↑↓↔↕⇒⇔ ඞ)](https://ap0ught.github.io/matrix?version=mathcode)
3232
- [Mathcode + Latin alphabet (experimental Three.js column split)](https://ap0ught.github.io/matrix?version=mathcode_alphabet_three) — see [RENDERING_PIPELINE.md](RENDERING_PIPELINE.md)
33+
- [Mathcode via p5.js (experimental 2D canvas rain)](https://ap0ught.github.io/matrix?version=mathcode_p5) — see [RENDERING_PIPELINE.md](RENDERING_PIPELINE.md)
3334
- [Rainbow colors](https://ap0ught.github.io/matrix/?effect=rainbow)
3435
- [Light spectrum colors](https://ap0ught.github.io/matrix/?effect=spectrum)
3536
- [Custom stripes (`effect=stripes&stripeColors=R,G,B,R,G,B,R,G,B, etc`)](https://ap0ught.github.io/matrix/?effect=stripes&stripeColors=1,0,0,1,1,0,0,1,0)

RENDERING.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
# Rendering stack
22

3-
This project uses two browser graphics paths:
3+
This project uses several browser graphics paths:
44

55

66
| Path | Directory | Runtime | When it runs |
77
| --------------------------- | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
88
| **WebGPU** | `[js/webgpu/](js/webgpu/)` | WGSL + WebGPU | `renderer=webgpu` and `navigator.gpu` is available |
99
| **WebGL** | `[js/webgl/](js/webgl/)` | GLSL + WebGL1 (currently via [regl](https://www.npmjs.com/package/regl), copied to `lib/regl.min.js`**temporary**, see [DEPENDENCY_POLICY.md](DEPENDENCY_POLICY.md)) | Default, or `renderer=webgl`, or legacy `renderer=regl` |
1010
| **Three.js** (experimental) | `[js/three-rain/](js/three-rain/)` | [three](https://www.npmjs.com/package/three)`lib/three.module.js`; instanced quads + raster atlas | `renderer=three` or preset `**version=mathcode_alphabet_three`** |
11+
| **p5.js** (experimental) | `[js/p5-rain/](js/p5-rain/)` | [p5](https://www.npmjs.com/package/p5)`lib/p5.min.js` (UMD); 2D canvas `text()` columns, mathcode glyph list | `renderer=p5` or preset **`version=mathcode_p5`** |
1112

1213

1314
## Strategy
@@ -20,7 +21,8 @@ This project uses two browser graphics paths:
2021

2122
## Dependencies
2223

23-
- `**regl`** is the only WebGL runtime npm dependency; `npm install` / `npm ci` runs `[scripts/vendor-webgl-deps.mjs](scripts/vendor-webgl-deps.mjs)` to refresh `lib/regl.min.js`. Commit updated `lib/regl.min.js` when the lockfile changes so static hosts without `node_modules` stay consistent.
24+
- `**regl**``postinstall` runs [`scripts/vendor-webgl-deps.mjs`](scripts/vendor-webgl-deps.mjs)`lib/regl.min.js`. Commit when the lockfile changes for static hosting without `node_modules`.
25+
- **`three`** / **`p5`** — optional experimental renderers; [`scripts/vendor-three.mjs`](scripts/vendor-three.mjs) and [`scripts/vendor-p5.mjs`](scripts/vendor-p5.mjs) copy their browser builds into `lib/`. Commit updated `lib/three.module.js` / `lib/p5.min.js` when those dependencies change.
2426

2527
## GLSL (WebGL) notes
2628

RENDERING_PIPELINE.md

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# How rendering works today (and how the Three.js demo relates)
22

3-
This document explains **what the main Matrix rain does on the GPU**, how **`regl` / WebGL** and **WebGPU** paths differ, and how the experimental **`renderer=three`** mode compares to rewriting the same effect in **Three.js**.
3+
This document explains **what the main Matrix rain does on the GPU**, how **`regl` / WebGL** and **WebGPU** paths differ, and how the experimental **`renderer=three`** and **`renderer=p5`** demos compare to the full pipeline.
44

55
For stack overview and links to policy, see **[RENDERING.md](RENDERING.md)**. Looking Glass is **[HOLOPLAY.md](HOLOPLAY.md)**.
66

@@ -14,7 +14,8 @@ For stack overview and links to policy, see **[RENDERING.md](RENDERING.md)**. Lo
1414
- **`webgpu`** — dynamic `import("./webgpu/main.js")` when `navigator.gpu` is available **and** the user asked for WebGPU.
1515
- **`webgl`** (default, or legacy `renderer=regl`) — `import("./webgl/main.js")`.
1616
- **`three`**`import("./three-rain/main.js")` (**experimental** demo; see §5).
17-
4. Holoplay forces **WebGL**; **`renderer=three`** is rejected when **`useHoloplay`** is true (same entry as WebGPU override).
17+
- **`p5`**`import("./p5-rain/main.js")` (**experimental** demo; see §6).
18+
4. Holoplay forces **WebGL**; **`renderer=three`** and **`renderer=p5`** are ignored when **`useHoloplay`** is true (same override path as WebGPU).
1819

1920
Each renderer’s **`default`** export is an **`async (canvas, config) => { ... }`** that owns the animation loop and resize handling.
2021

@@ -71,13 +72,23 @@ So Three is **not a drop-in replacement for regl** here: it replaces **low-level
7172

7273
---
7374

74-
## 6. Summary
75+
## 6. Experimental: `renderer=p5` + `version=mathcode_p5`
7576

76-
| Aspect | WebGL (`js/webgl/`) | WebGPU (`js/webgpu/`) | Three demo (`js/three-rain/`) |
77-
| ------ | --------------------- | ---------------------- | ----------------------------- |
78-
| API | WebGL1 + regl (temporary) | WebGPU + WGSL | WebGL2 (when available) + Three |
79-
| Glyphs | MSDF atlases | MSDF / WGSL sampling | CPU raster atlas |
80-
| Post | Bloom + effects + optional quilt | Bloom + effects | None |
81-
| Holoplay | Supported | Not used | Not supported |
77+
**Purpose:** A **p5.js** sketch in **instance mode** that draws **mathcode** Unicode glyphs (same ordered list as **`three-rain/glyphs.js`**) in falling columns using the **2D** renderer (`text()`, `HSL` fills). It is a **CPU / canvas 2D** path: no MSDF, no GPU simulation textures, no bloom or post stack.
8278

83-
Use the Three mode as a **learning / comparison** slice and for dependency experiments; use **WebGL/WebGPU** for the full Matrix experience.
79+
**Entry:** **`js/p5-rain/main.js`** — loads **`lib/p5.min.js`** (UMD from the **`p5`** npm package via **`scripts/vendor-p5.mjs`**), hides the Matrix WebGL canvas element, injects a fullscreen p5 canvas on `document.body`, and runs `new p5(sketch, document.body)`.
80+
81+
**Try it:** `?version=mathcode_p5` or `?renderer=p5&version=mathcode`.
82+
83+
---
84+
85+
## 7. Summary
86+
87+
| Aspect | WebGL (`js/webgl/`) | WebGPU (`js/webgpu/`) | Three demo (`js/three-rain/`) | p5 demo (`js/p5-rain/`) |
88+
| ------ | --------------------- | ---------------------- | ------------------------------ | ---------------------- |
89+
| API | WebGL1 + regl (temporary) | WebGPU + WGSL | WebGL2 (when available) + Three | Canvas 2D + p5 loop |
90+
| Glyphs | MSDF atlases | MSDF / WGSL sampling | Raster atlas (GPU) | `text()` (CPU) |
91+
| Post | Bloom + effects + optional quilt | Bloom + effects | None | None |
92+
| Holoplay | Supported | Not used | Not supported | Not supported |
93+
94+
Use the **Three** and **p5** modes as **learning / comparison** slices; use **WebGL/WebGPU** for the full Matrix experience.

SECURITY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ See **[DEPENDENCY_POLICY.md](DEPENDENCY_POLICY.md)** for what may be added or ve
5656
| -------------------- | ----------------------------------------- | --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
5757
| **regl** (npm) | WebGL command wrapper used by `js/webgl/` | Pinned in `package.json`; `postinstall` copies `dist/regl.min.js` to `lib/` via `scripts/vendor-webgl-deps.mjs` | [regl-project/regl](https://github.com/regl-project/regl) | **Exception:** upstream is effectively unmaintained. **Removal is required** per [migration_repl.md](migration_repl.md); tracked explicitly so it is not mistaken for a long-term choice. |
5858
| **three** (npm) | Experimental `js/three-rain/` demo (mathcode + alphabet columns) | Pinned in `package.json`; `postinstall` copies `build/three.module.js` to `lib/` via `scripts/vendor-three.mjs` | [mrdoob/three.js](https://github.com/mrdoob/three.js) | Actively maintained. Used only when `renderer=three` or `version=mathcode_alphabet_three`. Not feature-parity with main rain — see [RENDERING_PIPELINE.md](RENDERING_PIPELINE.md). |
59+
| **p5** (npm) | Experimental `js/p5-rain/` mathcode demo (2D `text()` rain) | Pinned in `package.json`; `postinstall` copies `lib/p5.min.js` via `scripts/vendor-p5.mjs` | [processing/p5.js](https://github.com/processing/p5.js) | Actively maintained by the Processing Foundation. **LGPL-2.1** (see package `license.txt`). Used only when `renderer=p5` or `version=mathcode_p5`. See [RENDERING_PIPELINE.md](RENDERING_PIPELINE.md). |
5960
| **holoplay-core** (vendored) | WebSocket client to HoloPlay Service for Looking Glass calibration / quilt flow | Checked in as [`lib/holoplaycore.module.js`](lib/holoplaycore.module.js) (not an npm `dependency` today); loaded from [`js/webgl/lkgHelper.js`](js/webgl/lkgHelper.js) | [holoplay-core (npm)](https://www.npmjs.com/package/holoplay-core) | Vendor SDK: LGF-owned; npm still receives occasional releases. In-tree copy may lag npm (header shows **0.0.8**; verify against latest on npm when upgrading). License: see upstream **LICENSE.txt**; file also contains **MIT** CBOR. Details: [HOLOPLAY.md](HOLOPLAY.md). |
6061
| **gl-matrix** | High-performance matrix and vector math | Bundled locally in `/lib/` | [toji/gl-matrix](https://github.com/toji/gl-matrix) | Actively maintained and widely adopted for WebGL/WebGPU math. Receives regular releases. The bundled version tracks a stable 3.x release of the library. |
6162
| **@playwright/test** | End-to-end browser testing (dev only) | npm `devDependency`**not included in production builds** | [microsoft/playwright](https://github.com/microsoft/playwright) | Very actively maintained by Microsoft with frequent releases and an extensive user base. This project pins a recent stable major version in its devDependencies. |

js/config.js

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ function parseRenderer(s) {
4747
if (x === "three" || x === "three.js") {
4848
return "three";
4949
}
50+
if (x === "p5" || x === "p5js" || x === "p5.js") {
51+
return "p5";
52+
}
5053
if (x === "regl" || x === "webgl") {
5154
return "webgl";
5255
}
@@ -350,7 +353,7 @@ const defaults = {
350353
slant: 0, // The angle at which rain falls; the orientation of the glyph grid
351354
resolution: 0.75, // An overall scale multiplier
352355
useHalfFloat: false,
353-
renderer: "webgl", // webgpu | webgl | three (URL may still use legacy alias regl)
356+
renderer: "webgl", // webgpu | webgl | three | p5 (URL may still use legacy alias regl)
354357
suppressWarnings: false, // Whether to show warnings to visitors on a load
355358
isometric: false,
356359
useHoloplay: false,
@@ -691,6 +694,31 @@ export const versions = {
691694
resolution: 0.8,
692695
},
693696

697+
mathcode_p5: {
698+
/*
699+
* Mathcode via p5.js (experimental): 2D canvas text columns using the same glyph list as
700+
* `fonts.mathcode`. Not MSDF / bloom / effects — see RENDERING_PIPELINE.md.
701+
*/
702+
font: "mathcode",
703+
renderer: "p5",
704+
numColumns: 48,
705+
animationSpeed: 0.75,
706+
cycleSpeed: 0.05,
707+
fallSpeed: 0.5,
708+
baseBrightness: -0.45,
709+
baseContrast: 1.1,
710+
cursorColor: hsl(0.55, 1, 0.88),
711+
cursorIntensity: 2,
712+
palette: [
713+
{ color: hsl(0.55, 0.9, 0.0), at: 0.0 },
714+
{ color: hsl(0.55, 1.0, 0.45), at: 0.55 },
715+
{ color: hsl(0.56, 1.0, 0.85), at: 0.95 },
716+
],
717+
raindropLength: 1.0,
718+
resolution: 0.8,
719+
glyphRandomFlip: true,
720+
},
721+
694722
alphabet: {
695723
/*
696724
* Alphabet — The Human Language

js/main.js

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,10 @@ function enforceHoloplayRenderer(config) {
3030
console.warn("[Matrix] Looking Glass (Holoplay) requires WebGL; ignoring renderer=webgpu for this session.");
3131
config.renderer = "webgl";
3232
}
33-
if (r === "three") {
34-
console.warn("[Matrix] Looking Glass (Holoplay) requires the regl/WebGL rain path; ignoring renderer=three for this session.");
33+
if (r === "three" || r === "p5") {
34+
console.warn(
35+
"[Matrix] Looking Glass (Holoplay) requires the regl/WebGL rain path; ignoring experimental renderer for this session.",
36+
);
3537
config.renderer = "webgl";
3638
}
3739
}
@@ -302,7 +304,9 @@ document.body.onload = async () => {
302304
const solution =
303305
rendererName === "three"
304306
? import("./three-rain/main.js")
305-
: import(`./${(await supportsWebGPU()) && rendererName === "webgpu" ? "webgpu" : "webgl"}/main.js`);
307+
: rendererName === "p5"
308+
? import("./p5-rain/main.js")
309+
: import(`./${(await supportsWebGPU()) && rendererName === "webgpu" ? "webgpu" : "webgl"}/main.js`);
306310

307311
/*
308312
* The Matrix Choice: Blue Pill vs Red Pill
@@ -689,9 +693,11 @@ async function initializeGalleryMode() {
689693
const solution =
690694
rendererName === "three"
691695
? await import("./three-rain/main.js")
692-
: await import(
693-
`./${(await supportsWebGPU()) && rendererName === "webgpu" ? "webgpu" : "webgl"}/main.js`,
694-
);
696+
: rendererName === "p5"
697+
? await import("./p5-rain/main.js")
698+
: await import(
699+
`./${(await supportsWebGPU()) && rendererName === "webgpu" ? "webgpu" : "webgl"}/main.js`,
700+
);
695701
currentMatrixRenderer = solution;
696702
await startMatrix(currentMatrixRenderer, canvas, newConfig);
697703
} else {

0 commit comments

Comments
 (0)