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:
npx [email protected] 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 thescaffold-packageskill. - No → it stays local:
products/leumas-web/src/cinematic/scenes/for one-off web scenes (seeBlackHole.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 approachSceneCanvas.jsxdeliberately uses instead of a postprocessing pass ("reads like bloom without a postprocessing pass"). - Do not introduce
three/webgpu,three/tsl, or aWebGPURendererwithout an explicit decision — it is a renderer migration, not an import. postprocessing,gsap, andlenisare not installed anywhere in this repo, despitecinematic-frontend-directorprescribing 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-motionand ship the poster fallback.SceneCanvasdoes both already — going around it means reimplementing both. - Target 60fps with a mobile fallback; the router's
$threejs-visual-validationskill 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, itsplacement.mdlane — the full placement conventions this file summarizes for 3D.scaffold-package— when a viewer or scene primitive earns its own@leumas/*package.