# threejs-leumas

Three.js, WebGL and GLSL work inside Leumas2 — which scene rig to reuse, where 3D code may live, the pinned three version, the shader-adapter convention.


# Three.js in Leumas2

Two skills, two jobs. **`threejs-skill-router`** (24-skill pack, installed at user scope) owns *technique* — how to author an ocean, a volumetric cloud, bloom, GTAO, a camera rig. **This skill** owns *placement and constraints* — what to reuse, where the code goes, and what this repo's renderer and versions actually support. Load the router for the graphics; obey this file for the wiring.

If the router skill is missing, install the pack:

```sh
npx threejs-awesome-graphics-agent-skills@0.4.4 install --agent claude-code --scope user
```

## Never hand-roll a renderer

Leumas already owns its 3D plumbing. Reuse it — this is golden rule 2, and the pack will not know about it.

| Building | Use | Where |
|---|---|---|
| An r3f scene (declarative, JSX) | `SceneCanvas` — owns `<Canvas>`, the error boundary, and the reduced-motion poster fallback | `shared/packages/cinematic/src/scene/SceneCanvas.jsx` |
| A raw-three viewer (imperative) | `createSceneRig(mount, { onFrame, … })` — renderer, camera, OrbitControls, RAF loop, ResizeObserver, disposal | `shared/packages/forge/src/hud/scene/sceneRig.js`, exported from `@leumas/forge` |
| Model/mesh viewing (STL/OBJ/FBX/GLTF) | `@leumas/react-3d-viewer` | `shared/packages/react-3d-viewer/src/` |

`@leumas/splats` is the reference for the raw-three path — `SplatsViewer.jsx` imports `createSceneRig` from `@leumas/forge` and adds only its point-cloud and fly-control layers. Copy that shape. A new `new THREE.WebGLRenderer(...)` plus a fresh `requestAnimationFrame` loop in a product is a bug, not a scene.

## Where new 3D code lives

Apply the reusability test — *could a different product use this by itself?*

- **Yes** → a shared package. Reusable scene primitives and splash/hero pieces go in `shared/packages/cinematic/src/`; generic viewers get their own package via the `scaffold-package` skill.
- **No** → it stays local: `products/leumas-web/src/cinematic/scenes/` for one-off web scenes (see `BlackHole.jsx`, `Cosmos.jsx`, `FlowerOfLife.jsx`), or the owning Studio surface.

Splash screens are a **`cinematic` mode** in `shared/packages/config-registry/src/modes.js`, CRUD'd through Studio → Imperium Configs — not a bespoke route. Generated textures/video belong in `shared/services/datacenter` under `/library/cinematic/`, consumed via `@leumas/assets-sdk`.

## Renderer reality: WebGL, not WebGPU

The pack targets three `^0.184` and several of its skills assume three's **node/TSL + WebGPU** pipeline — `threejs-spectral-ocean` (WebGPU/TSL FFT), `threejs-shadow-systems` (TSL shadow nodes), `threejs-parallax-occlusion-mapping` (WebGPU + TSL), and `threejs-bloom` (bloom-node). Leumas renders **WebGL** through r3f/drei and raw three. Those four need translating, not copying. So:

- Translate node-pipeline advice to WebGL — `EffectComposer` + `UnrealBloomPass`, or the CSS neon-glow approach `SceneCanvas.jsx` deliberately uses *instead of* a postprocessing pass ("reads like bloom without a postprocessing pass").
- Do not introduce `three/webgpu`, `three/tsl`, or a `WebGPURenderer` without an explicit decision — it is a renderer migration, not an import.
- `postprocessing`, `gsap`, and `lenis` are **not installed anywhere** in this repo, despite `cinematic-frontend-director` prescribing the latter two. Adding one is a dependency decision; say so rather than assuming it's there.

## Versions

Root `package.json` pins `"three": "0.180.0"` as a pnpm override; individual packages declare anywhere from `^0.160` to `^0.180`. The override wins at install time. Before using an API the pack suggests, confirm it exists in 0.180 — the pack's own bloom reference tells you to verify the installed node API, and that advice applies doubly here.

## Shaders follow the existing adapter convention

This repo already has the largest shader surface in it: **219 WebGL2 music-visualizer adapters** in `shared/engines/adapters/media/music/catalog/adapters/*GL.js`, plus 14 camera-effect shaders in `data/library-apps/Camera/adapters/`. Each declares `meta.ctxType: 'webgl2'` and compiles inline `#version 300 es` vertex/fragment sources. New GPU effects in those domains follow that contract — don't stand up a second shader host or a `.glsl` file convention that nothing else reads.

## Loading and accessibility

- three-flavoured modules must be `React.lazy`'d — a hard requirement for `@leumas/splats`, and the right default everywhere else. three + drei is a large chunk; it must not land in a first paint.
- Honour `prefers-reduced-motion` and ship the poster fallback. `SceneCanvas` does both already — going around it means reimplementing both.
- Target 60fps with a mobile fallback; the router's `$threejs-visual-validation` skill gives you a deterministic evidence set when a scene needs defending.

## Licensing note

The pack is published as `MIT AND GPL-3.0-only`. 23 skills derive from MIT/Zlib sources; <!-- counts-ok: a third-party pack's contents, not this tree -->
 **`threejs-precipitation-surfaces`** (rain, puddles, snow accumulation) derives from a GPL-3.0 project, and that copyleft attaches to code derived from its references and examples. Leumas ships as a paid EXE and a white-label product — worth knowing before lifting code from that one skill into a shared package.

## Related skills

- `threejs-skill-router` — all graphics technique; start there for the visual system itself.
- `cinematic-frontend-director` — creative direction, the cinematic arc, Higgsfield asset generation. It sets the taste; the router executes it.
- `leumas-capabilities`, its `placement.md` lane — the full placement conventions this file summarizes for 3D.
- `scaffold-package` — when a viewer or scene primitive earns its own `@leumas/*` package.


---
Source: .claude/skills/threejs-leumas/SKILL.md
Canonical: https://docs.leumas.tech/p/skills/threejs-leumas
