Wireface 2D

Any picture can talk.

A photo, an oil painting, anime, pixel art, a lump of clay. Gemini Pro finds the face, a 468-point rig is fitted over it, and it talks, blinks and pulls faces, lip-synced, right here in your browser.

Plain JavaScript on WebGL2, with Wireface's own expressions and lip sync. Free for personal and non-commercial use.

Any art style

Thirteen styles, one rig

Every one of these is a single flat picture. Pick one to hear it: the same expressions, blinks and lip sync drive each, scaled to its own features, so huge anime eyes still blink shut and a pixel mouth opens on pixel teeth.

How it works

How the face is found

A face detector trained on photos misses most drawings. So Gemini Pro looks first, and MediaPipe adds the fine detail where it can. Here is each character's own detection, replayed.

  1. Gemini Pro finds the face

    One request returns the face's box, 19 named points (eye corners, brows, nose, mouth, chin, jaw), the art style, and a character to talk as.

  2. MediaPipe adds 468 landmarks

    Locally, in the browser. On drawings it often misses, so it looks again inside Gemini's box.

  3. The two are combined

    Where they agree, the dense landmarks are kept; where they half agree, they're bent onto Gemini's points; otherwise a thin-plate spline fits the mesh to Gemini's.

  4. The rig takes over

    Wireface's animator moves a 3D face; each vertex's movement is carried onto the picture through its own local scale, and the mouth opens onto real teeth.

Expressions and teeth

Make a face

Pick a feeling, then look inside the mouth: teeth can be rendered, a picture drawn to match the art style, a photographic set (vampire included), or left out.

Character

Feeling

Teeth

For developers

Put a talking picture in your own app

import { createFace2d } from './wireface-2d/src/index.js';

const face = createFace2d(canvas, {
  detect: { gemini: { endpoint: '/api/detect' } },   // your server holds the key
});
await face.useCharacter('sora');      // ready-made...
await face.useCharacter(file);        // ...or any picture
face.express('happy');
await face.say(await face.clip('sora'), { audioContext });

What's in it

  • No build step: plain ES modules on WebGL2, no runtime dependencies.
  • Wireface core's animation: the same expressions, moods, blinks and lip sync, and the same method names.
  • Face detection with Gemini Pro and MediaPipe, step by step, with an overlay to show it.
  • Teeth three ways, thirteen characters, recorded lines, Gemini Live conversations.
  • Keys stay on your server: Node and Python reference servers mint one-use conversation tokens.

Try it

Bring your own picture

Talk with any of the characters, or give it a picture of your own: watch the face being found, then say hello.