kb
Kratin BhardwajProduct Designer
KAI · LIVE RENDER · FOLLOWS YOUR CURSORHOVER FOR THE TOPOLOGY PASS
The Studio · 3D and Animation

Built to move

I design, rig, and animate small personalities, then ship them straight to the browser. Everything moving on this page is procedural Three.js: no video, no downloaded models, just code running at 60 fps.

Hover any character. The lights go out and the raw topology lights up, mid action. Click one and see what happens.
01CHARACTER DESIGN02RIGGING AND ARMATURES03KEYFRAME + PROCEDURAL ANIMATION04THREE.JS · WEBGL05MOTION SYSTEMS AND EASING TOKENS
05.1 · Cast

The cast

1 lead robot and 8 studies in material and timing: chrome, glass, matte clay, lacquered toy gloss, short flock, long wind blown fur. All procedural, all alive. Hover any card to see the bones.

PIP

SEATED IDLE · LEG SWING

Waits on his bench like it is his job. Alternating leg swings with a sneaky double kick, real knees that lag the swing, and boots that never quite reach the floor.

… tris◇ WIREFRAME

NOVA

CHROME · GLASS DOME

Chrome cadet. Mirror finish body under a glass dome, red eyes on a porcelain face. She scans the room in servo steps and lets the reflections do the acting.

… tris◇ WIREFRAME

DOZE

SLEEP CYCLE · SHELL FUR

Asleep on the clock. Slow breathing with a deep sigh every 12th breath, 1 ear twitching at dreams. The 54 shell coat breathes with him; hover and it dissolves into topology.

… tris◇ WIREFRAME

BILL

MATTE CLAY · OFF DUTY

Off the clock entirely. A clay duck in a clay armchair, cap on, phone out. The thumb keeps scrolling, the webbed feet keep wiggling, and every 9 seconds a silent wheeze opens the bill. Poke him and he fumbles the phone.

… tris◇ WIREFRAME

MOCHI

SQUASH AND STRETCH HOP

Painfully shy. Sways, double blinks, then every 7.5 seconds gathers the courage for 1 perfect hop: anticipation squash, airtime stretch, landing settle.

… tris◇ WIREFRAME

GIGI

LONG FUR · WAVE CYCLE

A walking hairdo. Layered shell fur that sways as she moves, 1 arm permanently mid wave, smooth vinyl hands and feet for contrast. Hover to comb her down to topology.

… tris◇ WIREFRAME

SCOOP

READING LOOP · PAGE TURN

Catching up on the Daily News. The eye line scans each line with a quick return sweep, and the page turns every 6 seconds. The visor stays glossy, even in wireframe.

… tris◇ WIREFRAME

FUZZ

SPIKY FUR · PEEK IDLE

A haystack with stage fright. Spiky blue fur in constant motion, a red face peeking out, ball cluster hands on long coral arms. The stick legs are load bearing, somehow.

… tris◇ WIREFRAME
05.2 · Kai
Character design → rig → motion → ship

Kai: a character study in code

Could a portfolio mascot do more than sit in a hero image? Kai is my answer: a character that is modeled, rigged, and animated entirely in JavaScript, light enough for a phone, and hopefully charming enough that you already hovered him.

ROLEConcept, modeling, rig, animation, build. Solo.
TOOLSThree.js and WebGL. Blender for previz. After Effects for motion tests.
TIMELINE3 weeks of evenings. v2 shipped July 2026.
OUTPUTReal time web character. 60 fps. 0 external assets.
DRAG TO ORBIT

The actual production asset, not screenshots. Every stage rebuilds live from the same source.

The brief

Most portfolio mascots are decoration: a PNG that never moves, or a Lottie loop that ignores you. I wanted a character with an actual production pipeline behind him: designed, modeled, rigged, and animated, then shipped as running code instead of a rendered video.

The constraint that shaped everything: he had to live on a real website without hurting it. That meant a tight polygon budget, no downloaded assets, and animation cheap enough to share a thread with the rest of the page.

3 decisions that shaped him

01 · MODELINGPrimitives over sculpt

Kai is roughly 30 primitives: rounded boxes, spheres, capsules. No sculpting, no retopo, no import pipeline. The topology view above is the actual geometry, and the silhouette survives at 48 pixels.

02 · RIGGINGTransforms over bones

There is no skeleton. Each part hangs off nested pivot groups, and animation drives rotation and scale directly, like a stop motion armature. Cheaper than skinning, and it reads just as alive at this scale.

03 · MOTIONPrinciples over presets

Every move is built from animation fundamentals: anticipation before the wave, follow through on the ear, squash and stretch in the hop, layered sines so the idle never visibly loops.

Process

Character sheets

Silhouette first: a rounded square head on a small body, readable at 48 pixels. The ear dot went through 9 placements before landing top left.

Blockout

Grey primitives to lock proportion: head to body ratio near 1.5:1, feet tucked tight to the body so the float reads as one connected mass. The blockout stage in the viewer is this exact pass.

Topology

Rebuilt each primitive with clean subdivision so the wireframe reads as modeling loops, not triangle soup. The white on black grid you see on hover is the real mesh.

Rig

Nested pivots for head, arms, ear, eyes, and float. Control rings in the rig view mark every animatable transform: 14 in total.

Motion pass

Idle, blink, saccade, wave, and cursor follow, layered as independent sine and noise channels with offset periods so the combination never repeats exactly.

Ship and budget

Merged materials, capped device pixel ratio, 1 shared renderer for every scene on this page. The live stats below are the receipt.

Motion breakdown · the timing sheet

Hover float1.9 rad/s

1 sine on the root, shadow scaled in counter phase so the float reads as weight, not drift.

Blink~3.4 s cycle

Layered sines with a pseudo random beat so blinks land off rhythm. Fully closed for 2 frames.

Eye saccadeevery 1.7 s

Eyes jump to a new offset and ease in over 120 ms, the same move your own eyes are making right now.

Wave3.1 + 6.2 rad/s

Base swing plus a 2nd harmonic at double frequency, fired in bouts with an anticipation dip before each one.

Ear spring-0.95 phase lag

The ear trails every head turn by about a quarter second: follow through, straight from the 12 principles.

Fur windamp · f²

Every fur shell shears sideways, weighted by the square of its layer height: tips travel, roots hold, the coat looks alive.

What broke, and what fixed it

Z fighting on the wireframe

The topology overlay sat exactly on the surface and flickered. Fixed with polygon offset plus a 0.35 percent inflation: the overlay hovers a hair above the shell.

The loop seam

Blink, float, and wave on unrelated periods produced a visible hitch every 40 seconds. Retimed every channel to share a common period so the loop point is invisible.

10 canvases

1 WebGL context per scene tanked the frame rate. Rebuilt as a single renderer that scissor clips every scene from 1 fullscreen canvas: the reason this page holds 60 fps.

By the numbers

Measured live from this page. These stats are computed by the running scene, not typed in.

Triangles · the entire cast of 9
Draw calls per frame · measured live
Measured FPS on this device
Animated pivots across the cast
0External models, textures or videos
1Shared WebGL context, scissor clipped

Where Kai goes next

v3 is a character sheet page of his own: expression states wired to site events, a walk cycle for page transitions, and a small emote set his chat widget can trigger mid conversation. Same rig, same budget.

Kai is also in the corner of this page right now. Click him and ask for a tour.