Eyes were the warmup. Mouth is where SAUCE learns to speak. If the eyes are the window to the soul, the mouth is the door β€” and we need that door to open, close, purse, pout, and sync to audio without exploding the vertex count.

Why Mouth Is Harder Than Eyes

Eyes blink. That’s one state transition: open ↔ closed. The UV slides horizontally, shader does the rest, done.

Mouths speak. That’s not one transition β€” that’s a continuous deformation problem. Every phoneme in every language reshapes the lips, jaw, and cheeks differently. And because SAUCE isn’t a static portrait β€” it’s a 3D character that tilts, turns, and animates β€” those deformations need to work from every angle.

The good news: we already solved the hard part. The eye pipeline (Gemini β†’ Hunyuan3D β†’ 3D Studio β†’ Blender β†’ Paint.NET) proved the AI-assisted workflow works. Now we’re adapting it for mouths with one critical addition: shapekeys.

The Pipeline: Same Players, New Rules

Stage Eye Pipeline Mouth Pipeline
1. Concept Gemini redraws eye concept Gemini redraws mouth expression
2. 3D Gen Hunyuan3D β†’ base mesh Hunyuan3D β†’ base mesh
3. Retopo 3D Studio β†’ clean quads 3D Studio β†’ clean quads + lip loops
4. Assembly Blender β†’ UV fix, integrate Blender β†’ shapekeys, UV fix, integrate
5. Texture Paint.NET β†’ atlas export Paint.NET β†’ expression atlas

The only new stage is shapekey creation β€” everything else is the same pipeline with mouth-specific conventions.

The Trait Inventory: 15 Mouths, One Base

From the collection tree (devlog1), we have 15 mouth traits to support:

Trait Rarity Type Notes
Bored #20 Flat UV Neutral, slightly open
Buck Teeth #20 Flat UV Protruding upper incisors
Cat Mouth #20 Flat UV Small, pursed
Clown Smile #20 Flat UV Wide, painted aesthetic
Frown #20 Flat UV Downturned corners
Grin #20 Flat UV Teeth showing, friendly
Lisp #20 Flat UV Tongue-forward
Meh #20 Flat UV Flat line, dead inside
Open #20 Flat UV Mid-open, surprised
Smile #20 Flat UV Classic upturned
Smirk #20 Flat UV Asymmetric, one side up
Tongue Out #20 Flat UV Playful, non-speech
Toothless #20 Flat UV Gums visible
Vampire #20 Flat UV Fang reveal
Wide Open #20 Flat UV Scream/sing pose

All 15 are currently flat UV textures. The goal: each becomes a 3D mouth with the same shapekey set, so any SAUCE head can speak regardless of which mouth trait is equipped.

The Base Mesh: Mouth-Specific Topology

The SAUCE mouth base mesh follows rules learned from the eye radial topology:

  • Concentric lip loops: 3 edge loops minimum (outer lip, mid-lip, inner lip)
  • Radial corner fans: Edge flow radiates from mouth corners for natural creasing
  • Jaw adjacency: Lower lip loops connect to chin geometry, not floating
  • Quad purity: No triangles in the deform zone β€” quads deform predictably
  • Symmetry plane: Mirror across X, break only for asymmetric traits (Smirk)

Target stats:

  • Mouth mesh: ~120–180 tris
  • Lip deformation zone: ~40 vertices
  • Full head with mouth: consistent with existing SAUCE base

UV Shapekey Standards: The Core Spec

This is the heart of the document. Every mouth trait β€” flat or 3D β€” needs these shapekeys to support speech animation.

Shapekey Naming Convention

Mouth_<Category>_<Name>

Examples:

  • Mouth_Phoneme_AA β€” wide open β€œah” sound
  • Mouth_State_Closed β€” rest/neutral
  • Mouth_State_Wide β€” grin width (non-speech)
  • Mouth_Emotion_Frown β€” sad downturn

Required Shapekey Set (16 Total)

1. Rest State (1 shapekey)

Name Description Vertices Affected
Mouth_State_Closed Lips together, neutral expression All mouth verts

2. Viseme Shapekeys (11 shapekeys)

Based on the standard OVRLipSync viseme set (industry standard for VR/chat avatars):

Name Phoneme Mapping Mouth Shape
Mouth_Viseme_sil Silence / closed Lips fully closed, rest pose
Mouth_Viseme_AA A, a, ah Jaw dropped, mouth wide open
Mouth_Viseme_E E, e, eh Teeth showing, corners pulled back
Mouth_Viseme_I I, i, ee Wide horizontal, teeth closed
Mouth_Viseme_O O, o, oh Lips rounded, protruded
Mouth_Viseme_U U, u, oo Lips pursed, small circle
Mouth_Viseme_PP B, P, M Lips pressed together (plosive)
Mouth_Viseme_FF F, V Lower lip tucked under upper teeth
Mouth_Viseme_TH Th, th Tongue between teeth (if visible)
Mouth_Viseme_DD D, T, N, L Tongue up, slight teeth part
Mouth_Viseme_CH Ch, J, Sh Teeth nearly closed, slight smile

3. Emotional/Expression Shapekeys (4 shapekeys)

Name Description Use Case
Mouth_Emotion_Smile Corners up, teeth showing Happy states
Mouth_Emotion_Frown Corners down, brow involvement Sad/angry states
Mouth_Emotion_Surprise Jaw drop + rounded lips Shock states
Mouth_Emotion_Pursed Lips pressed tight Disapproval, thinking

Shapekey Value Rules

  • Range: 0.0 to 1.0 (Blender standard)
  • Default rest: All shapekeys at 0.0, base mesh = Mouth_State_Closed
  • Combinability: Visemes are mutually exclusive β€” only one viseme active at a time
  • Emotion overlay: Emotional shapekeys CAN combine with visemes (e.g., smiling while saying β€œoh”)
  • Combination method: Additive blending β€” final = base + (viseme * weight) + (emotion * weight)
  • Max total weight: Clamp at 1.5 to prevent over-deformation

A flat cartoon mouth lifting off a glowing page and rising into a sculpted 3D face mesh above it

UV Atlas Layout: Expression States

For flat-texture mouth traits (the 15 existing variants), the UV atlas follows the eye pattern but with more columns:

+--------+--------+--------+--------+
| Closed | Open   | Wide   | Pursed |
+--------+--------+--------+--------+
| Smile  | Frown  | Ooh    | Aah    |
+--------+--------+--------+--------+

Atlas spec:

  • Dimensions: 1024Γ—512 minimum (4Γ—2 grid of 256Γ—256 expression tiles)
  • Grid: 4 columns Γ— 2 rows = 8 expression states per trait
  • States per tile: Closed, Open (surprise), Wide (grin), Pursed, Smile, Frown, Ooh (rounded), Aah (wide)
  • Shader logic: UV offset driven by animation state, same as eye blink
  • Alpha channel: Teeth and inner mouth masked for layering over face texture

For 3D mouth traits (future mechanical/expression variants), the atlas becomes a single diffuse + normal + roughness β€” the shapekeys handle all deformation.

Lip-Sync Compatibility: The Translation Layer

SAUCE needs to talk. Whether it’s a user voice chat, pre-recorded audio, or AI TTS, the mouth must sync. Here’s the compatibility matrix:

OVRLipSync (Meta / VRChat standard)

OVRLipSync Viseme SAUCE Shapekey
sil Mouth_Viseme_sil
AA Mouth_Viseme_AA
E Mouth_Viseme_E
ih Mouth_Viseme_I
oh Mouth_Viseme_O
ou Mouth_Viseme_U

OVRLipSync outputs 6 visemes + laughter/blink. Our 11-shapekey set is a superset β€” we map 6-to-11 and fill gaps with nearest-neighbor.

Rhubarb Lip-Sync (offline, free)

Rhubarb outputs 9 mouth shapes (A, B, C, D, E, F, G, H, X). Map:

  • A β†’ Mouth_Viseme_AA
  • B β†’ Mouth_Viseme_PP
  • C β†’ Mouth_Viseme_E
  • D β†’ Mouth_Viseme_TH
  • E β†’ Mouth_Viseme_O
  • F β†’ Mouth_Viseme_U
  • G β†’ Mouth_Viseme_FF
  • H β†’ Mouth_Viseme_I
  • X β†’ Mouth_State_Closed

Custom JSON Animation Format

For web-based SAUCE implementations (three.js and friends):

{
  "track": "mouth_viseme",
  "keyframes": [
    {"time": 0.0, "value": "sil"},
    {"time": 0.12, "value": "AA"},
    {"time": 0.28, "value": "PP"},
    {"time": 0.45, "value": "sil"}
  ]
}

The runtime maps string viseme IDs to shapekey indices. 16 shapekeys = index 0–15.

Blender Implementation: Shapekey Creation Workflow

For the artist (me, in Blender at 2 AM):

  1. Duplicate base mesh β†’ create shapekey from mix
  2. Enter edit mode on the new shapekey
  3. Deform only lip vertices β€” jaw vertices follow if jaw is separate mesh
  4. Use proportional editing (O key) with smooth falloff for natural deformation
  5. Test in object mode β€” slider from 0 to 1, check silhouette from front and side
  6. Name strictly β€” Mouth_Viseme_AA, not ah_mouth or wide_open
  7. Set slider range β€” 0 to 1, never negative
  8. Pin for preview β€” pin the shapekey at 1.0 to sculpt the next variant

Proportional Editing Settings

Shapekey Type Prop. Edit Falloff Radius
Viseme (open) Smooth Medium
Viseme (closed) Sharp Small
Emotion (smile) Root Large
Emotion (frown) Linear Medium

Paint.NET: The Expression Atlas

For flat-texture mouth traits, Paint.NET stays the texture source. The workflow:

  1. Base mouth shape β€” neutral closed, lips together
  2. Duplicate layer β€” one per expression state
  3. Transform each layer β€” warp lips to match shapekey target
  4. Export grid β€” 4Γ—2 tiles, 1024Γ—512 total
  5. Name convention: mouth_<traitname>_<YYYY-MM-DD>_<HHMM>.webp

Critical: Each tile must align pixel-perfect with the UV shell. One pixel offset = lip seam in engine. Zoom to 800%, use grid snap, check alignment against UV reference overlay.

A neat holographic grid of dozens of small glowing mouth expressions floating like tiles

Integration: From Blender to SAUCE

The export pipeline:

  1. Blender β†’ Shapekeys baked, base mesh frozen
  2. Export format: GLB (glTF 2.0) with morph targets
  3. Morph target naming: Preserved from shapekey names
  4. Engine import: Three.js family β†’ mesh.morphTargetInfluences
  5. Runtime animation: AnimationMixer or custom driver updates influence array

Three.js Morph Target Example

// Access morph targets by name
const mouthMesh = scene.getObjectByName('mouth')
const morphDict = mouthMesh.morphTargetDictionary

// Set viseme influence (0.0 to 1.0)
mouthMesh.morphTargetInfluences[morphDict['Mouth_Viseme_AA']] = 0.85

// Blend with emotion
mouthMesh.morphTargetInfluences[morphDict['Mouth_Emotion_Smile']] = 0.3

Vertex Count Budget

  • Each shapekey = full vertex position array for deformable verts
  • 120 mouth verts Γ— 16 shapekeys = 1,920 extra vertex positions
  • In GLB: stored as morph target accessors (~23KB uncompressed)
  • Acceptable overhead for the expressiveness gain

Quality Gates: Definition of Done

Before a mouth trait graduates from β€œin progress” to β€œcollection ready”:

  • All 16 shapekeys created and named correctly
  • No vertex pinching at 1.0 influence (check from 45Β° angle)
  • Viseme set produces readable lip-sync on test audio
  • Texture atlas exported (flat traits) or material assigned (3D traits)
  • Weight painted to head rig (if using bones + shapekeys)
  • Exported to GLB and reimported cleanly
  • Tested in a live web build with morphTargetInfluences driver
  • Screenshots: front view, 3/4 view, profile, all shapekeys at 1.0

The Mechanical Mouth Future

Just like Ekubo and Kano’s bionic eyes, some mouth traits deserve 3D geometry:

  • Vampire β€” fangs protrude in Mouth_Viseme_PP
  • Buck Teeth β€” incisors extend in Mouth_Viseme_AA
  • Clown Smile β€” painted grin widens asymmetrically
  • Tongue Out β€” tongue mesh with independent bone

These follow the same shapekey spec but add geometry-specific deformation. The jaw opens, the fangs track with it, the tongue extends on its own bone layer.

Summary: The Spec At a Glance

Element Standard
Base mesh tris 120–180
Lip loops 3 minimum
Shapekey count 16 (1 rest + 11 visemes + 4 emotions)
Shapekey range 0.0 – 1.0
Viseme standard OVRLipSync compatible
Atlas format 1024Γ—512, 4Γ—2 grid, 8 states
Export format GLB with morph targets
Runtime Three.js morphTargetInfluences

Next

This document is the spec. The next task is the execution: take one trait (probably Smile β€” simplest geometry, most recognizable) and run it through the full pipeline with shapekeys. If Smile works, the other 14 are variations on the same rig.

The mouth is where SAUCE stops being a picture and starts being a person. Let’s make it count. πŸ«™


Days until June 30 deadline: 32 | Pipeline: locked | Shapekeys: specified | Status: ready to sculpt