Mesh Avatar Studio Guide
Guides › Drawn Variants Without Codex: A Real Test

Drawn Variants Without Codex: A Real Test

The official flow assumes Codex image generation. We did it with a different model — here is everything that went wrong and what worked.

The editor's Drawn variants step prepares a request for Codex and its built-in image generation. But the request is really just three files: the source image, an edit mask, and a prompt. Any image model that can edit a reference image without changing the character will do. We tested this end-to-end — here is the honest record.

What the editor gives you

uv run tools/variant-requests.py projects/<name> writes eleven request folders — closed/half/smiling eyes, sad/surprised expression eyes, four vowel mouths, angry/sad closed mouths — each containing mask.png, prompt.md and a shared README. The rules that matter:

The model test: what failed, what worked

We tried three routes before one worked. Names differ per provider, so treat this as a checklist, not gospel:

  1. Native "image edit" models on the wrong endpoint — 404s. If your provider's docs name an edit model, check which endpoint it actually lives on.
  2. An aggregator's model alias on the provider's native API — "Model not exist." Aliases are often proxy-layer names that do not exist upstream.
  3. The general image model with a reference image input — worked. A model that accepts an image plus a text instruction (often called image-to-image or instruction editing) handled "close both eyes, keep everything else identical" perfectly, including line style and the transparent background.

The one step that makes it reliable: mask compositing

Even a good edit model shifts a pixel here or there outside the mask. Rather than hoping, we composite deterministically: take the generated image only inside the mask's editable (transparent) region, keep the original pixels everywhere else. Ten lines of image-library code; the outside-mask rule becomes mathematically guaranteed instead of model-dependent.

from PIL import Image
src = Image.open("source.png").convert("RGBA")
gen = Image.open("generated.png").convert("RGBA")
gen = gen.resize(src.size)  # safety
mask = Image.open("mask.png").getchannel("A")   # 0 = editable, 255 = protected
editable = mask.point(lambda v: 255 - v)
Image.composite(gen, src, editable).save("variants/eyes_closed.png")

Two traps we hit, so you do not have to:

Then let Studio import and verify

Save each result to projects/<name>/variants/<variant>.png and run:

uv run tools/build-sprites.py projects/<name>
npm run render-poses -- projects/<name>

build-sprites validates properly: it corrects shifts up to 3 px, removes uniform color tints measured inside the mask edge, and rejects with a reason anything redrawn outside the mask. Re-render the review poses afterwards and the expression frames (angry, sad, surprise) now show the drawn eyes and mouths — see the showcase before/after.

Cost and time

Eleven variants, roughly one to two minutes each on a general image model, for a few cents total. The whole drawn-variant stage is cheaper than the coffee you will drink while it runs.