3D pipeline. Three.js scene with a PBR-shaded character (albedo / normal / metalness / roughness) in WebP for fast loads. FBX model loaded once, pose changes are animation channels rather than re-loads. Custom material setup in materialManager.js so the user's painted texture composites cleanly on top of the PBR base.
Painting system. This was the hardest part. A pointer event in screen space has to land on the right UV pixel, which means a raycast from the camera into the model, intersection point's UV, mapped to a 2D canvas the size of the texture, brush blob stamped on that canvas, canvas re-uploaded to the GPU as a THREE.CanvasTexture. All of that happens inside one pointermove at ~60fps, with mouse events throttled and cursor tracking hardware-accelerated. Brush has size + opacity + colour controls, plus a 20-step undo/redo stack of canvas snapshots. Eraser is the same brush in destination-out composite mode.
Mask regions. A separate mask texture (head / jacket regions) gates where paint can land. The brush samples the mask before stamping — so a brushstroke that crosses from the jacket onto the face only paints the jacket part. Stickers obey the same mask.
Sticker system. Pre-designed PNG stickers (stickers/) the user picks from a gallery. Same UV-space placement pipeline as the brush — sticker becomes a textured plane composited into the painting canvas at the raycast UV.
Environments. Nine lighting presets (studio, outdoor, sunset, night, forest, beach, dawn, cloudy, indoor) — each is a coordinated swap of HDRI / ambient / key light / background colour, defined declaratively so a 10th preset is two more lines.
Multi-screen workflow. A screenManager.js module holds the user's progress through Colour → Paint → Environment, so the toolbar / sidebar surface only the controls relevant to the current step. Reduces cognitive load for first-timers.
Export. Render-to-target at higher resolution than the viewport, with the background and floor disabled, output as a transparent PNG. The user gets a marketing-ready image they can drop into anything.
Performance. Hardware-accelerated CSS (transform3d, will-change) on UI panels; pointer events throttled; brush canvas operations batched per frame; bounded undo history (20 steps) to cap memory. The whole thing stays at 60fps on a mid-tier MacBook with the character + paint canvas at 2048².
UI. Glassmorphism panels with backdrop blur, dark theme, blue accent. Modern floating toolbar that doesn't eat the canvas. The September redesign tightened the visual language and made it easier to embed the tool inside Webflow — the live page is a Webflow shell with the Three.js app mounted into a single container.