Dev.to · 9 min read

Your AI Character Looks Right—Except Every Asymmetric Detail Flipped

Your AI Character Looks Right—Except Every Asymmetric Detail Flipped

This article comes from the author's work maintaining Tsuduri, a recurring AI-illustrated character with asymmetric design features. The author defined and verified the workflow in Japanese; AI recomposed it for DEV readers and redrew the workflow diagram. #ABotWroteThis Tsuduri's hair ornament belongs on her left side. When she faces the viewer, that ornament appears on the right side of the image. When she faces away, it appears on the left. In a side view, it may move to the near side or disappear behind her head. That sounds simple until an image model returns a polished illustration with the ornament on the wrong side. The face, colors, and mood can all look correct. The image may be attractive. It is still the wrong character state. I stopped trying to solve this by loading a longer character profile into every generation. The workflow I settled on was smaller and more explicit: keep a short invariant in the character's own coordinate system; start with the single reference view closest to the requested composition; classify the actual output view, then validate at least two asymmetric traits. Keep the full turnaround sheet as source material. Do not make it the default payload for every image. TL;DR Write "the ornament is on the character's left," not only "put it on screen right." Store the complete design canon, but begin each generation with one view-specific reference. Judge the image that was actually produced, not only the view you requested. Check at least one primary identity trait and one independent secondary trait. Use N/A when a trait is genuinely occluded or outside the frame; do not turn missing evidence into PASS. After a failed retry, change the reference or method instead of repeating the same ambiguous prompt. Treat the bug as a coordinate-system bug "Left" can refer to two different frames: subject-relative left: the character's own left side; screen-relative left: the viewer's left side of the finished image. Those frames agree only in some poses. Actual output view Character's left side appears Hair ornament expectation Front Screen right Visible on screen right Back Screen left Visible on screen left Character faces screen left Near side Usually visible Character faces screen right Far side Usually hidden Three-quarter view Depends on angle and occlusion Evaluate from the actual pose If the prompt stores only "screen right," it becomes wrong as soon as the camera or character turns. The stable rule is the subject-relative relation. The screen position is a view-dependent projection. A usable instruction therefore has two layers: Invariant: the hair ornament is attached to the character's left side. Requested view: frontal; the ornament should appear on screen right. The first line survives a camera change. The second line helps this specific generation. A beautiful image can still fail spatially Image quality and spatial correctness are separate checks. The 2022 paper Benchmarking Spatial Relationships in Text-to-Image Generation evaluated whether generated images preserved requested relations between objects. It found that producing recognizable objects did not guarantee that the requested relation was correct. A 2026 preprint, Can Text-to-Image Models Draw from the Right Frame of Reference?, separates viewer-relative instructions from object-relative ones. Across 1,200 prompt pairs and 22 models, the paper reports that object-relative accuracy averaged 41.8% lower than the corresponding viewer-relative accuracy; even the best model reached 44.3% on the object-relative task. The same preprint also reports that rewriting prompts from visual feedback raised mean accuracy from 25.0% to 29.2% under an equal generation budget. That is an improvement, not a solution. The practical implication is that a closed loop—inspect the output, then select or correct it—is more realistic than expecting a stronger opening instruction to settle the question by itself. Those numbers are not Tsuduri's success rate. The models, prompts, scoring, and target designs differ. They support a narrower point: switching between "the character's left" and "the image's right" is a real evaluation problem, not merely a wording typo. That is why my review asks two questions independently: Does the image look good? Are the character-relative relationships correct for the pose that was actually rendered? Passing the first question cannot answer the second. Keep a thick canon and a light generation payload The full design canon is still valuable. It can contain front, back, side, and three-quarter views; color rules; clothing connections; asymmetric hardware; and known exceptions. The mistake is treating "valuable to retain" as "mandatory to attach every time." Making "attach everything" the default is a workflow cost, not a measured accuracy effect. The cost follows from the shape of the request itself: every generation starts by locating the same image set and attaching it in a fixed order; angles that this pose does not need are in the input, and the request says nothing about which image should win; the things you actually asked for this time, such as pose, scene, expression and style, sit next to a large block of reference description; when a generation fails, the request gives you no way to say which reference or instruction was ignored; every correction means rebuilding the whole bundle, and the routine stops being something you keep doing. OpenAI Academy's image-generation guide recommends clear, specific prompts. The rest is my operating policy, not the guide's claim: keep the full canon as the thing you preserve, and attach only the minimum evidence this run needs. That policy does not prove one image is always more accurate. It keeps the two roles separate so a failure is easier to trace. Use three layers: Layer Contains Used when Character canon Turnaround views, colors, clothing connections, exceptions Updating the design or resolving ambiguity Generation reference The closest view for the requested composition Normal generation Validation contract Expected visible traits and PASS/FAIL/N/A rules Reviewing the actual output Build an asymmetry inventory before writing a longer prompt Do not inventory the whole character. Inventory the features whose spatial relation carries identity. asymmetric_traits: - name: hair_ornament subject_side: left attached_to: left_hair_mass identity_weight: primary - name: diagonal_strap starts_at: right_shoulder ends_at: left_waist identity_weight: secondary Each trait needs enough information to answer: What is the feature? Which side or attachment point is invariant? In which views should it be visible? When is it legitimately N/A because of occlusion, crop, or scale? Is it a primary identity signal or a secondary cross-check? Checking only the hair ornament is weak. A flipped image can accidentally place one item correctly while reversing the strap, hair flow, or garment closure. Use at least two independent asymmetric signals when both are observable. The three-stage loop 1. Freeze a short invariant Keep the stable relation short enough to inspect: The ornament remains on the character's left side. The diagonal strap runs from the character's right shoulder to left waist. Do not bury these lines inside biography, personality, lighting, and scene history. 2. Start with the closest single view Choose the reference whose pose and camera angle most closely match the request. State its role: identity, orientation, clothing connection, or style. The rule is "one view first," not "one view forever." If the output requires a back connection that the frontal reference cannot show, add a second reference specifically for that missing role. 3. Validate the actual output The generated image may not match the requested view exactly. Classify what it actually shows before checking trait placement. def review(output_view, observations): expected = expected_traits_for(output_view) verdicts = [] for trait in expected: if observations[trait].is_occluded: verdicts.append((trait, "N/A")) elif observations[trait].matches_subject_relation: verdicts.append((trait, "PASS")) else: verdicts.append((trait, "FAIL")) visible = [v for _, v in verdicts if v != "N/A"] return "PASS" if len(visible) >= 2 and all(v == "PASS" for v in visible) else "FAIL" This is review logic, not a claim that computer vision can infer every trait reliably. A person or a bounded visual reviewer still has to supply the observations. The code makes the decision boundary explicit: two visible independent traits, no observed mismatch, and no invented PASS for an occluded feature. Escalate references by missing role, not by anxiety When a result fails, use this order: Reclassify the actual output view. The image may have turned more than expected. Confirm the invariant uses the character's frame, not the screen's frame. Replace the first reference if another stored view is closer. Add one second reference with a named role, such as "back strap connection." If the same defect survives a bounded retry, change the generation method, composition, or review strategy. Repeatedly attaching more images without naming their roles makes the input larger without making the failure easier to explain. What this workflow does not guarantee This loop targets left/right and other asymmetric spatial consistency. It does not by itself guarantee: anatomy or hand correctness; exact facial identity; color fidelity under different lighting; style continuity; that the model followed the requested pose; that one reference is sufficient for every composition. It also asks a different question from an identity-ablation experiment. An ablation test asks how much a design may change before recognition breaks. This workflow assumes the design should not change and asks whether the generated pose preserved its spatial invariants. A checklist for the next image Before generation: [ ] Write one or two subject-relative invariants. [ ] Select the closest single reference view. [ ] Name the role of every attached reference. [ ] Choose one primary and one independent secondary asymmetric trait. After generation: [ ] Classify the actual output view. [ ] Translate subject-relative traits into expected screen positions for that view. [ ] Mark each trait PASS, FAIL, or N/A. [ ] Reject when an observable trait is flipped. [ ] After a repeated failure, revise the setup instead of replaying the same prompt. The durable design record can stay rich. The per-image payload can stay small. The review must be specific enough to catch the polished wrong answer.

This is a summary aggregated from Dev.to. Read the complete article on the original site:

Read full article at Dev.to

More AI & Machine Learning News