Bind a face GLB to a VRM

Strata on-device

Start from a photo. The page reads the face on your device, makes a face-blendshape GLB from it, and drives a base VRM's expression blendshapes from that GLB's morphs, and (optionally) moves the VRM's face shape, hair shape and colors toward the photo. The skeleton, skin weights and existing blendshapes are not changed, and the hairstyle can be re-laid as waves, curls or coils or switched to a cut preset (no new hair is added).

Stays on this device

Your photo, the face GLB made from it, and everything derived from them are processed in this page and are never sent to any server. The face model runs locally from files served with this page (nothing from a CDN). The page makes GET requests only, and the whole thing works with the network off once the page has loaded.

Approximate, not a likeness guarantee

The binding makes the VRM's expressions drivable from the face source. The shape and color matching below is a rough, measured nudge (eye size and spacing, mouth, jaw, profile depth; skin, hair, eye and brow color); an anime base will still look like an anime character.

Input

1. Face photo

or

A clear, front-facing face. The photo stays on this device.

On-device face model: loading…

Already have a face-blendshape GLB? Use it instead of a photo

2. Base VRM

Use your own VRM instead (a local file or a URL)
Match the photo
(optional and approximate; everything is applied to the VRM's own geometry and materials)

The hairstyle is the VRM's own hair cards, scaled, shifted and optionally re-laid (waves, curls, coils, or a cut preset); braids, buns and ponytails are not possible, and the texture guessed from the photo is a rough estimate you can override. The body and the skeleton are not changed, and the photo's texture is not painted onto the avatar. With a face GLB instead of a photo only the skin tone applies (there are no measurements or hair/eye/brow colors in it).

Network audit
(no requests)

Agent use: ?vrm=male|female|URL&run=1 auto-runs once a photo (or face GLB) is supplied from local disk; the result is on window.__webcli_result. window.__facebind.run({ vrm, image, shape: { strength }, hairShape: { strength, hug }, hairStyle: { cut, texture }, facialHair, bald, look: { skin, hair, iris, brow, strength } }) takes 'male' (default), 'female', a URL or a File for vrm and a File (or face: a face GLB's bytes) for the starting point, never a URL, for either.