WorldBuilder - A 3D Character Customisation Tool That Runs in a Browser

Web · 3D · Three.js · WebGL · Character Customisation · Texture Painting · Commissioned · Tool-Building
INTRODUCTION
WorldBuilder is a web-based 3D character customisation tool I built in 2025 for Avinash Kumar / Quicksand as a community-engagement piece for the WorldBuilder IP. It's an end-user creative tool: someone lands on the page, picks a base colour for the WorldBuilder mascot, paints directly onto its surface with brushes, slaps stickers wherever, picks one of nine lighting environments, and exports a high-quality PNG with a transparent background. No installs, no plugin chain — Three.js + HTML5 Canvas + WebGL doing the heavy lifting in-browser.

The interesting bit isn't "Three.js character viewer" (everyone has one). It's that you can paint on the model itself, with masked regions, brush controls, and undo history, and the painting flows back into the texture of a PBR-shaded character that you then pose under different lights. It's a small Photoshop-on-a-3D-character, designed so a non-3D user can produce a finished, share-ready mascot in a couple of minutes.
MY ROLE
Solo developer (commissioned). Three.js scene + render pipeline, the painting system, UV → 2D canvas mapping, mask logic, multi-screen workflow, glassmorphism UI, performance work, deployment, post-launch UI redesign.
timeline
2025 (initial build mid-year, redesign + Webflow integration in September).
situation
Commissioned by Avinash Kumar — founder of Quicksand and one of the people behind the WorldBuilder IP, a travelling festival / cultural-futures initiative (linked to Eye Myth Festival, Antariksha Studio, and Unbox Cultural Futures) that sits at the intersection of heritage, design, and immersive tech.

WorldBuilder has a mascot. The brief: build a public, browser-based tool that lets the festival's audience and community make the mascot their own — paint it, sticker it, pick a lighting environment, and screenshot the result to share. A marketing tool in the strict sense, but really a community-engagement tool: every piece of UGC is a custom mascot, and every custom mascot is a small social signal for the IP.

The technical brief: install-free, browser-only, low time-to-first-character (under five minutes for a complete novice), and high-quality transparent-PNG export so the result drops cleanly into Instagram, posters, decks, anywhere.
👇 Interactive section to showcase all verticals
👇 Figma sneak peak of entre design process
task
  • Real-time 3D character preview in the browser, no downloads
  • A painting system that lets users brush directly on the character's UV-mapped surface, with mask regions (so paint stays inside e.g. the jacket and not the face)
  • Stickers — placeable, positionable, snap-to-surface
  • Multi-screen workflow (Colour → Paint → Environment) so the tool guides a first-time user through the steps
  • Nine environment presets that swap lighting + sky + tone in one click
  • High-resolution PNG export with a transparent background
  • Session persistence — closing the tab doesn't lose the work
  • Smooth on a mid-range laptop or tablet
👇 Figma sneak peak of entre design process
action

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.

result
  • Live and in production at worldbuilder.in/character-builder
  • Built in vanilla JS + Three.js — no React/Vue overhead, fast first-paint
  • Open-sourced the engine on GitHub (MIT) so the work survives the brand