You generate your brand mascot holding a coffee mug. It looks great. You generate it again, looking at a laptop, same prompt style, and it's a slightly different robot. Different face, different proportions, close enough that you almost don't notice until you put the two images side by side.
That's character drift, and it's the reason most AI-generated mascots never make it into an actual brand system. A character your audience can't recognize across posts isn't a character, it's a random image generator with extra steps.
Why "Just Describe the Character Consistently" Doesn't Work
The instinct is to write a longer, more detailed prompt each time. That doesn't solve drift, because the model isn't remembering your character between generations, it's reinterpreting the same words fresh every time, and small wording differences produce visibly different outputs.
"Friendly robot holding a coffee mug" ββ> Robot Face A
"Friendly robot looking at a laptop" ββ> Robot Face B, different enough to notice
vs.
Fixed turnaround sheet + exact hex codes + lens spec ββ> Same robot, 500 assets later
The Six Layers That Actually Hold
Start with a real anchor image. Generate a high-resolution turnaround sheet with a neutral expression, four fixed angles: front, three-quarter, profile, back. This single image becomes the thing every future generation references, not a paragraph of description.
Nail down anatomy with numbers, not adjectives. Cheekbone angle, eye spacing, nose bridge curvature if it's humanoid. Give the character one distinctive, specific trait a model can anchor onto, an off-center antenna, a particular hair cowlick, a specific style of glasses.
Color has to be hex, not a word. "Blue jacket" gives the model room to interpret. #00ADFB doesn't. Lock your primary surface color, an accent, and a neutral baseline as exact values, and use them every time.
Lighting and lens choice are part of the identity too. If one asset renders under harsh top light and another under soft studio light, they won't read as the same character even if the face is technically right. Pick a render style, a focal length, a lighting setup, and don't vary it.
| Vague prompting | A real Character Bible | |
|---|---|---|
| Face | "Young developer with curly hair" | "Maya: sharp jawline, copper curls in a high bun, freckles across the nose bridge" |
| Clothing | "Wearing a tech hoodie" | "Matte-black oversized hoodie, embroidered teal logo, left chest" |
| Render style | "Realistic, trending on artstation" | "3D stylized, Pixar-style subsurface scattering, Octane render, amber rim light" |
From Spec to a Working Pipeline
Draft the spec (traits, hex codes, lens choice, in markdown)
β
βΌ
Generate the four-angle turnaround as your anchor seed
β
βΌ
Lock a reference vector (--cref, or train a LoRA)
β
βΌ
Generate unlimited scenes, the anchor keeps the identity fixed
Where This Still Breaks
Clothing changes are the most common way identity slips even with a good reference. If you're on Midjourney, isolate the face reference at high weight (--cw 100) so clothing tokens can vary by scene without dragging the face along with them. Skip this and every outfit change becomes a small face change too.
Frequently Asked Questions
Which model actually handles this best right now?
Midjourney v6 and later with <code>--cref</code> works well for stylized 3D mascots. For photorealistic human characters, a Flux.1 setup with a custom LoRA trained on twenty or so reference images gives you more control.
How do you stop clothing changes from also changing the face?
Weight separation. Isolating the face reference at high weight while letting clothing tokens vary freely keeps the identity locked even as the scene and outfit change.
Is a four-angle turnaround really necessary, or can I skip straight to generating scenes?
It's worth the extra step. Without a real anchor image, every "consistent" generation is still just the model reinterpreting a text description, which is exactly what causes drift in the first place.
Comments
Comments are reviewed before appearing publicly.
No comments yet β be the first.