character-reference-sheets
Dress 3D character base renders with AI-generated clothing while preserving the body, pose and framing, so each garment can be cut out and sent to image-to-3D generators. Use when the request involves a Blender base render in A-pose or T-pose, a character visual sheet, a turnarou
Install
npx skills add https://github.com/guinacio/claude-image-gen/tree/master/optional-workflows/character-reference-sheets
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install guinacio-claude-image-gen@llmmart
git clone https://github.com/guinacio/claude-image-gen.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole guinacio/claude-image-gen collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
Character reference sheets
Pipeline: a nude body render comes out of Blender, the model dresses that body, each garment is cut out, it goes to an image-to-3D generator, and the mesh comes back into Blender.
The goal of the generation is not a beautiful image. It is the same body as the render, now clothed, with every piece legible and cuttable. Everything below exists to protect that.
Cost rule, before anything else
Never call create_asset without asking first. Every generation spends the
user's API credit. Write the full prompt, surface the decisions that change the
image, and wait for an explicit go-ahead. This applies to each retry after a bad
result too — do not silently fix and re-run.
Workflow
- Measure the input renders with
scripts/measure.py. If any criterion in section 8 ofreferences/resolutions-and-proportions.mdfails, say so and ask for a re-export from Blender. Cheaper than discovering the problem after the image is paid for. - Flatten alpha onto white if the PNG is RGBA. Alpha often becomes black on upload and contaminates the result.
- Build the prompt using the architecture in
references/prompt-template.md. - Ask for permission to generate.
- Generate, one view per call.
- Measure the output and compare against the input (thresholds below).
- Copy from
IMAGE_OUTPUT_DIRinto the character project's own output folder, with a descriptive versioned name:character_outfit_front_v2.png.
Measurement dependency
scripts/measure.py requires Python and Pillow. Before first use, ask before
installing the dependency, then run:
python -m pip install -r /path/to/character-reference-sheets/requirements.txt
If Pillow is unavailable and cannot be installed, do not generate: report that the mandatory pre-flight measurement could not be completed.
The rule that matters most
Never describe the body in the prompt. Not the build, not shoulder width, not head size, not height. Describing anatomy makes the model draw a new body from the text instead of preserving the one in the image.
Recorded case: a prompt opening with "heavyset bara-build, very broad shoulders, thick muscular arms, wide barrel chest, heavy thighs, small head" collapsed the character's arm span from 88.9% to 74.3% of the frame width — 14.6 points. Same character, same render, same model, rebuilt with the correct architecture and zero body description: 89.2%, a 0.3 point deviation.
The prompt says what to add and what to preserve. Never what the body is.
Parameters
| Model | gpt-image-2 |
| Aspect ratio | 2:3 for a standing character · 1:1 for an isolated garment or prop |
| Quality | Provider default — the current create_asset client does not expose quality |
input_fidelity |
Provider default — the current client does not expose this option. OpenAI documents GPT Image 2 as supporting high-fidelity image inputs, but this workflow does not explicitly request high |
| References | 2 to 4, base image first |
| Turnarounds | never in a single image — one view per call |
Verification after generating
Run scripts/measure.py on the input and the output and compare horizontal
occupancy (ocup_h):
ocup_h deviation |
Reading |
|---|---|
| within ±2 points | normal, accept |
| beyond ±2 points | the prompt let the model redraw the body — regenerate |
Empirical basis: crocodile character +1.6 / −1.4 across three generations; tiger v2 +0.3; tiger v1 (wrong prompt) −14.6.
Vertical occupancy usually rises 2 to 4 points even when everything is right. On its own it is not a failure signal.
Known residual: limbs get thinner
In every recorded generation so far — three of one character, two of another
— arms and thighs came out with less volume than the base render. The PRESERVE
block fixes framing and scale; it does not fix muscle mass.
Do not treat this as a new bug on each character. Practical consequences:
- Leg and foot pieces (pants, boots, sneakers) — safe to cut out, limb volume does not drive the garment's shape.
- Torso pieces (shirt, vest, jacket) — they were modelled over a narrower torso than the original mesh. The generated 3D tends to come out tight. Warn the user before they send it to an image-to-3D generator.
Where output lands
The server writes to IMAGE_OUTPUT_DIR (an MCP environment variable) and
rejects any outputPath outside it. Pass a bare filename and copy the result
into the character's folder afterwards.
References
references/prompt-template.md— the prompt architecture, with a real examplereferences/resolutions-and-proportions.md— aspect ratios, per-edge margins, Blender export settings, the mandatory pre-flight check, and what to feed an image-to-3D generatorscripts/measure.py— bounding box, occupancy and margins
Files (claude-image-gen)
-
references
-
prompt-template.md 6.9 KB
# The prompt architecture Seven blocks, in this order. Prompts are always in English and always self-contained — generations run in a clean session with no conversation context. ``` I'm attaching two images. IMAGE 1 - [what the base render is]. This is the base. Everything in it must be preserved. IMAGE 2 - [what the clothing reference is]. Use it ONLY as a reference for which clothing to add. Completely ignore its [style, pose, anatomy, and everything present in it that is absent from the render]. TASK: dress the character from IMAGE 1 in that outfit. Clothing to add: - [one line per piece] Hardware must be crisp and consistent: [the hardware this outfit has]. Keep every piece of hardware sharp and correctly repeated rather than smeared, melted or randomly shaped. PRESERVE EXACTLY, with no alteration: - [preservation list] Output: a single image, same framing as IMAGE 1. ``` ## Block by block **IMAGE 1** — declare that it is the base and that everything in it is preserved. Describe the *kind* of image (3D render, A-pose, orthographic camera, white background, flat shading), never the character's anatomy. **IMAGE 2** — declare that it serves **only** to say which clothing. Then list explicitly what to ignore in it. Anything present in the concept art and absent from the render must be named, or the model will add it: hair, tail, weapon, beard, horns, wings. Also instruct it to ignore painting style, lineart, lighting, background, pose and anatomy. **TASK** — one sentence. It states that the operation is dressing, not drawing. **Clothing to add** — pieces only. No mention of the body. A detail that separates the piece from a generic one (flap pocket, crooked knot, colour panel) is worth more than a quality adjective. **Hardware** — a dedicated paragraph. Hardware is where the model smears most: buckles without frames, melted chain links, irregular eyelets. Name the hardware this particular outfit actually has. **PRESERVE EXACTLY** — the block that holds everything together. Fixed base: ``` - The same A-pose, in the same position and angle - The same orthographic front camera, same framing and same body scale within the frame - The same arm span: the hands stay exactly where they are, at the same distance from the left and right edges - The plain white background, no shadow, no scenery, no gradient - The same clean 3D render style with flat colors: DO NOT paint it, DO NOT add fabric photorealism, DO NOT add grain, DO NOT add dramatic lighting, DO NOT add outlines - The same character colors and markings, the same proportions, the same [head, muzzle, ears, eyes, hands, feet — whatever this character has] ``` The arm span line matters most in A-pose and T-pose: with the arms out, width is what constrains the frame, and width is where framing breaks. **Output** — restate that it is a single image, same framing. ## Reference order Base **first**, clothing sheet after. The array order is the order the prompt calls IMAGE 1 and IMAGE 2. ## A real example that worked Anthropomorphic tiger, front A-pose render plus approved concept art. Result: `ocup_h` 88.9% → 89.2%, a 0.3 point deviation. ``` I'm attaching two images. IMAGE 1 - a 3D render of my character in A-pose, orthographic front view, plain white background, flat matte shading with solid colors. This is the base. Everything in it must be preserved. IMAGE 2 - a concept illustration. Use it ONLY as a reference for which clothing to add. Completely ignore its painting style, its lineart, its lighting, its pose and its anatomy. Also ignore its head hair, its tail and its sword - none of those exist in IMAGE 1 and none must be added. TASK: dress the character from IMAGE 1 in that outfit. Clothing to add: - Crisp white short-sleeve button-up dress shirt, sleeves ending mid-bicep, top three buttons undone showing the cream chest fur, collar open, hem untucked and hanging loose over the pants, and a buttoned flap chest pocket on the left side - A crimson red necktie, knotted but yanked loose: the knot sits low below the open collar and is visibly crooked and off-center, the wide end trailing down askew, as if just pulled down after work - Very baggy loose black cargo pants, deep flap utility pockets on the thighs, buckle straps, D-rings and hanging webbing, waistband riding on the hips, fabric pooling and stacking over the shoes - Crimson red cloth hand wraps fully covering the palms, the backs of the hands and the knuckles, then winding up both forearms, with loose ends trailing from the wrists. The fingers stay bare from the first knuckle up - Bold chunky designer high-top sneakers, white with crimson red panels, stitching and laces, thick sculpted white sole, oversized padded tongue, small red tiger emblem on the outer side - Thin silver chain necklace with a small silver tiger emblem pendant Hardware must be crisp and consistent: shirt buttons are uniform and evenly spaced, buckles have readable frames and prongs, D-rings are cleanly closed, chain links are individually defined and of even size, sneaker eyelets are regular and the laces cross evenly. Keep every piece of hardware sharp and correctly repeated rather than smeared, melted or randomly shaped. PRESERVE EXACTLY, with no alteration: - The same A-pose, in the same position and angle - The same orthographic front camera, same framing and same body scale within the frame - The same arm span: the hands stay exactly where they are, at the same distance from the left and right edges - The plain white background, no shadow, no scenery, no gradient - The same clean 3D render style with flat colors: DO NOT paint it, DO NOT add fabric photorealism, DO NOT add grain, DO NOT add dramatic lighting, DO NOT add outlines - The same character colors and markings, the same proportions, the same bald head with no hair, the same muzzle, ears, amber eyes, hand and foot shapes, and no tail Output: a single image, same framing as IMAGE 1. ``` ## Counter-example — what not to do This prompt, on the same render and the same model, collapsed the arm span by 14.6 points: ``` Full body front view of a heavyset bara-build anthropomorphic tiger, adult male: tall, very broad shoulders, thick muscular arms, wide barrel chest, thick waist, heavy thighs, small head relative to the body. Standing in a neutral symmetrical A-pose facing the viewer: legs straight and shoulder-width apart, both arms hanging down... ``` Three mistakes at once: it describes the anatomy, it describes the pose in text instead of instructing the model to preserve the pose in the image, and it never declares the reference's role. The model treated the render as inspiration and the text as specification — exactly the inverse of what is wanted. ## Back views Back views tend to trip the moderation filter when the base render is a nude body. When that happens, the recorded workaround is to add the already-dressed front view to the references and ask for parity with it, which gives the model a clothed target instead of a nude body. -
resolutions-and-proportions.md 9.1 KB
# Resolutions and proportions for AI-generated references A general guide — it applies to any character or 3D prop. It complements the prompt recipe, which lives in `prompt-template.md`. --- ## 1. What each provider actually delivers **OpenAI (`gpt-image-2`) — only three sizes exist:** | Aspect ratio | Pixels | Use | |---|---|---| | `1:1` | 1024 × 1024 | props, isolated pieces, hardware | | `3:2` | 1536 × 1024 | lying down / horizontal | | `2:3` | 1024 × 1536 | **standing character — the default** | There is no 4K and no 2K. There is no 16:9. Any other ratio requested is substituted with the closest one on the list. **Gemini** honours the requested ratio natively and (on Pro versions) delivers higher resolution. When fine detail matters more than composition, it is the stronger side. ## 2. How the `create_asset` tool maps The `aspectRatio` parameter accepts 7 values, but on OpenAI only **three are exact**. The others are converted and the frame is recomposed — which breaks alignment between views. | You request | OpenAI delivers | Exact? | |---|---|---| | `1:1` | 1024 × 1024 | yes | | `3:2` | 1536 × 1024 | yes | | `2:3` | 1024 × 1536 | yes | | `4:3` | 1536 × 1024 (3:2) | no, substituted | | `16:9` | 1536 × 1024 (3:2) | no, substituted | | `3:4` | 1024 × 1536 (2:3) | no, substituted | | `9:16` | 1024 × 1536 (2:3) | no, substituted | **Rule:** on OpenAI use only `1:1`, `3:2` or `2:3`. On Gemini, any of them. ## 3. Which ratio to use, by subject | Subject | Ratio | Why | |---|---|---| | Standing biped (human, anthro) | `2:3` | the silhouette is tall and narrow | | Quadruped, or long horizontal tail | `3:2` | the body is wider than it is tall | | Isolated garment (vest, shorts, boot) | `2:3` | keeps the proportion of the view it came from | | Small prop or hardware (buckle, crucifix, stud, link) | `1:1` | it is compact, a square wastes nothing | | Long weapon, vehicle, environment | `3:2` | same as quadruped | **Never request a full turnaround sheet** (front + side + back in a single image). The model splits its pixel budget across the three and each view comes out with a third of the detail. One view per call, always. ## 4. Margin — the subject has to fit **clothed** This is the easiest mistake to make, because the base render looks perfect. Clothing **grows outward past the nude silhouette**: | Piece | Grows toward | How much (1.80 m character) | |---|---|---| | Shoulder spike | sides and up | 8-10 cm each side | | Fur collar | up and around the neck | 5-8 cm | | Hanging chain | down | 10-20 cm below the hem | | Thick lug sole | down | 4-6 cm | | Cargo pocket, thigh strap | sides | 3-5 cm | Framed tight to the nude body, none of that has anywhere to go: the model either crops at the edge or squeezes the piece to fit. **But margin is not a fixed number — it is per edge, and it depends on the outfit.** Reserving 12% at the top is pointless if the character wears no hat: it is wasted pixels, and the body shrinks for nothing. The method: for each edge, ask **what part of that outfit passes the nude silhouette in that direction**, and reserve that plus a safety band of ~3%. | Edge | Question | Typical | |---|---|---| | Sides | is the widest point the shoulder or the hand? | arms out → the hand rules, and a glove barely grows: **5-6%** | | Bottom | thick sole, heel, hanging chain? | combat boot: **10%** · long chain: 15% | | Top | hat, hood, horn, crest, collar rising past the head? | none of those: **4%** · with a hat: 15% | Only reserve 12-15% on an edge when something really grows a lot there. Symmetric margin by default is waste; **asymmetric is correct** when only one edge needs it (e.g. 4% top, 16% bottom, for combat boots). If the base render already has the character filling 95% of the height, it is *wrong for this purpose*, however well framed it looks. ### A-pose or T-pose: width is what rules With the arms out, what limits the framing **is not the height, it is the arm span** — and only in the front and back views, because from the side the arms disappear behind the body. Practical consequence: **the front view sets the scale for all the others.** Adjust Ortho Scale until the hands fit with 12% of slack in the front view, then use exactly that value for the sides and the back, even if a lot of empty space is left on the sides of the side view. Empty space is the price of alignment. With the arms out, the body ends up occupying ~65-70% of the frame height, not the 76% of the general rule. That is expected, not an error. ### On resolution: the gain is modest A 1.80 m character filling the frame with correct margin: | Framing | Body height | px per cm | 1 cm stud | |---|---|---|---| | 1024×1024, body at 96% of height | ~980 px | 5.4 | 5 px | | 1024×1536, body at 76% of height | ~1170 px | 6.5 | 6-7 px | That is ~22% of gain, not a game changer. Input fidelity matters more to fine detail than this modest resolution increase. [OpenAI documents GPT Image 2](https://developers.openai.com/api/docs/models/gpt-image-2) as supporting high-fidelity image inputs, but the current `create_asset` client does not expose `input_fidelity`, so it uses the provider default. Do not claim that `high` is enabled. Use `2:3` for the margin and for the subject's proportion, not expecting a sharpness miracle. ## 5. Exporting from Blender 1. **Output Properties → Resolution X/Y**: set the final size directly — `1024 × 1536` for a standing character. Do not export square and crop later. 2. **Orthographic camera**, not perspective. Perspective distorts the silhouette and the views stop matching each other. 3. **Ortho Scale** adjusted so the body fills ~76% of the height, leaving 12-15% of slack top and bottom for the clothing to grow into. 4. **The same Ortho Scale in all views.** That is what guarantees front, side and back stay aligned and superimposable afterwards. To take a tail out of the frame in the side view, **move the camera**, do not change the scale. 5. **Flat white background** (white World) or transparent. No floor, no shadow, no HDRI — any gradient reads as "lighting" that the model tries to imitate. 6. **PNG**, never JPEG. Compression artefacts on a silhouette edge confuse the model and it reproduces the artefact. **On the side view of a character with a long tail:** let the tail run out of frame. Framing the whole tail forces a horizontal ratio and pushes the body — which is where the clothing is — into a tiny corner. ## 6. Input images (the references) - **Maximum 5** per call. - Formats: PNG, JPEG, WebP. - **They do not need to match the output size**, but they must match the **aspect ratio**. A square reference asking for a 2:3 output makes the model recompose, and the generated view stops aligning with the others. - **Crop reference sheets** down to the relevant half only. A sheet with two views side by side and a caption makes the model reproduce a two-view layout instead of the object. - A reference with a dark background and dramatic lighting (product photography) drags its style along. Either crop the background out, or state explicitly in the prompt that the image informs the design, not the appearance. ## 7. What to send to image-to-3D afterwards The 3D generators (Tripo, Meshy, Rodin, Hunyuan3D, Trellis) want: - **An isolated object**, no character, no mannequin, no floor - **White or removed background**, flat - **`1:1` works better** than 2:3 on most of them — reconstruction assumes a centred volume - **Multi-view**: front and back of the **same** object, same framing, as separate images. Never the two glued into one image. So: generate the clothed view at `2:3` to get detail, isolate the piece, and only then reframe to `1:1` before sending it to the 3D generator. ## 8. Mandatory pre-flight check **Measure the reference images before any `create_asset` call.** Generating from a wrong base burns credit and produces an image that will be discarded. Criteria, per image: | Check | Pass | Fail → what to ask for | |---|---|---| | File aspect ratio | matches the requested `aspectRatio` | re-export at the correct ratio | | Top margin | ≥ what the clothing grows there + 3% | see the per-edge table in section 4 | | Bottom margin | ≥ what the clothing grows there + 3% | see the per-edge table in section 4 | | Side margins | ≥ what the clothing grows there + 3% | see the per-edge table in section 4 | | Body vertical occupancy | 75-85% | above 90% is too tight | | Long tail or appendage in the side view | out of frame | "move the camera, do not change the scale" | | Background | flat white or alpha | remove floor, shadow, gradient | | Format | PNG | re-export without JPEG | | Consistency between views | same Ortho Scale across all three | re-export the set | If any item fails: **say so and ask for the fix, do not generate.** Re-exporting from Blender is cheaper than discovering the crop after the image is finished. Use `../scripts/measure.py` — it reports occupancy and margins for each render in seconds. ## 9. One-line summary Standing character → `2:3`, body at ~76% of the height with 12-15% of margin for the clothing to grow into, orthographic, PNG, same Ortho Scale across all views. Measure before generating. Isolated piece for 3D → `1:1`.
-
-
scripts
-
measure.py 2.8 KB
"""Measure subject occupancy and margins in base renders and generations. Usage: python measure.py input.png output.png ... Reads the alpha channel when one exists; otherwise treats anything that is not near-white as subject. Prints one line per file with vertical and horizontal occupancy plus the four margins, all as a percentage of the frame. Criteria (see SKILL.md and resolutions-and-proportions.md): - input vertical occupancy: 75-85%, or 65-70% in A-pose/T-pose - per-edge margin: how far the clothing grows past the nude silhouette on that edge, plus roughly 3% - ocup_h deviation between input and output: within +-2 points is normal; beyond that the prompt let the model redraw the body """ import os import sys try: from PIL import Image, ImageOps except ImportError as error: raise SystemExit( "Pillow is required. Install it with: " "python -m pip install -r /path/to/character-reference-sheets/requirements.txt" ) from error def measure(path): image = Image.open(path) if image.mode in ("RGBA", "LA"): bbox = image.split()[-1].getbbox() else: grey = ImageOps.invert(image.convert("L")) bbox = grey.point(lambda v: 255 if v > 12 else 0).getbbox() if bbox is None: return None width, height = image.size left, top, right, bottom = bbox return { "name": os.path.basename(path), "dimensions": f"{width}x{height}", "ocup_v": 100 * (bottom - top) / height, "ocup_h": 100 * (right - left) / width, "top": 100 * top / height, "bottom": 100 * (height - bottom) / height, "left": 100 * left / width, "right": 100 * (width - right) / width, } def main(paths): if not paths: print(__doc__) return 1 results = [] for path in paths: result = measure(path) if result is None: print(f"{os.path.basename(path)}: empty frame, nothing measured") continue results.append(result) print( f"{result['name'][:34]:<36}{result['dimensions']:>10}" f" ocup_v={result['ocup_v']:5.1f}% ocup_h={result['ocup_h']:5.1f}%" f" top={result['top']:4.1f}% bottom={result['bottom']:4.1f}%" f" left={result['left']:4.1f}% right={result['right']:4.1f}%" ) if len(results) >= 2: source, generated = results[0], results[-1] drift_h = generated["ocup_h"] - source["ocup_h"] drift_v = generated["ocup_v"] - source["ocup_v"] verdict = "ok" if abs(drift_h) <= 2 else "REGENERATE - the body was redrawn" print( f"\n{source['name'][:24]} -> {generated['name'][:24]}: " f"drift_h={drift_h:+.1f} drift_v={drift_v:+.1f} [{verdict}]" ) return 0 if __name__ == "__main__": sys.exit(main(sys.argv[1:])) -
test_measure.py 939 B
import os import tempfile import unittest from PIL import Image, ImageDraw from measure import measure class MeasureTests(unittest.TestCase): def test_measure_reports_subject_occupancy_and_margins(self): with tempfile.TemporaryDirectory() as directory: path = os.path.join(directory, "subject.png") image = Image.new("RGB", (10, 10), "white") ImageDraw.Draw(image).rectangle((2, 1, 7, 8), fill="black") image.save(path) result = measure(path) self.assertIsNotNone(result) self.assertEqual(result["dimensions"], "10x10") self.assertEqual(result["ocup_v"], 80) self.assertEqual(result["ocup_h"], 60) self.assertEqual(result["top"], 10) self.assertEqual(result["bottom"], 10) self.assertEqual(result["left"], 20) self.assertEqual(result["right"], 20) if __name__ == "__main__": unittest.main()
-
-
requirements.txt 15 B
Pillow>=10.0.0 -
SKILL.md 5.4 KB
--- name: character-reference-sheets description: Dress 3D character base renders with AI-generated clothing while preserving the body, pose and framing, so each garment can be cut out and sent to image-to-3D generators. Use when the request involves a Blender base render in A-pose or T-pose, a character visual sheet, a turnaround, generating clothing over a nude body mesh, or preparing garment pieces for Tripo, Meshy, Rodin, Hunyuan3D or Trellis. Do not use for website, banner or presentation imagery — the image-generation skill covers that. --- # Character reference sheets Pipeline: a nude body render comes out of Blender, the model dresses that body, each garment is cut out, it goes to an image-to-3D generator, and the mesh comes back into Blender. The goal of the generation is **not a beautiful image**. It is the *same body* as the render, now clothed, with every piece legible and cuttable. Everything below exists to protect that. ## Cost rule, before anything else **Never call `create_asset` without asking first.** Every generation spends the user's API credit. Write the full prompt, surface the decisions that change the image, and wait for an explicit go-ahead. This applies to each retry after a bad result too — do not silently fix and re-run. ## Workflow 1. **Measure the input renders** with `scripts/measure.py`. If any criterion in section 8 of `references/resolutions-and-proportions.md` fails, say so and ask for a re-export from Blender. Cheaper than discovering the problem after the image is paid for. 2. **Flatten alpha onto white** if the PNG is RGBA. Alpha often becomes black on upload and contaminates the result. 3. **Build the prompt** using the architecture in `references/prompt-template.md`. 4. **Ask for permission to generate.** 5. **Generate**, one view per call. 6. **Measure the output** and compare against the input (thresholds below). 7. **Copy** from `IMAGE_OUTPUT_DIR` into the character project's own output folder, with a descriptive versioned name: `character_outfit_front_v2.png`. ## Measurement dependency `scripts/measure.py` requires Python and Pillow. Before first use, ask before installing the dependency, then run: ```bash python -m pip install -r /path/to/character-reference-sheets/requirements.txt ``` If Pillow is unavailable and cannot be installed, do not generate: report that the mandatory pre-flight measurement could not be completed. ## The rule that matters most **Never describe the body in the prompt.** Not the build, not shoulder width, not head size, not height. Describing anatomy makes the model *draw a new body from the text* instead of preserving the one in the image. Recorded case: a prompt opening with "heavyset bara-build, very broad shoulders, thick muscular arms, wide barrel chest, heavy thighs, small head" collapsed the character's arm span from 88.9% to 74.3% of the frame width — **14.6 points**. Same character, same render, same model, rebuilt with the correct architecture and zero body description: 89.2%, a 0.3 point deviation. The prompt says **what to add** and **what to preserve**. Never what the body is. ## Parameters | | | |---|---| | Model | `gpt-image-2` | | Aspect ratio | `2:3` for a standing character · `1:1` for an isolated garment or prop | | Quality | Provider default — the current `create_asset` client does not expose `quality` | | `input_fidelity` | Provider default — the current client does not expose this option. [OpenAI documents GPT Image 2](https://developers.openai.com/api/docs/models/gpt-image-2) as supporting high-fidelity image inputs, but this workflow does not explicitly request `high` | | References | 2 to 4, base image **first** | | Turnarounds | never in a single image — one view per call | ## Verification after generating Run `scripts/measure.py` on the input and the output and compare **horizontal occupancy** (`ocup_h`): | `ocup_h` deviation | Reading | |---|---| | within ±2 points | normal, accept | | beyond ±2 points | the prompt let the model redraw the body — regenerate | Empirical basis: crocodile character +1.6 / −1.4 across three generations; tiger v2 +0.3; tiger v1 (wrong prompt) −14.6. Vertical occupancy usually rises 2 to 4 points even when everything is right. On its own it is not a failure signal. ## Known residual: limbs get thinner In **every** recorded generation so far — three of one character, two of another — arms and thighs came out with less volume than the base render. The `PRESERVE` block fixes framing and scale; it does **not** fix muscle mass. Do not treat this as a new bug on each character. Practical consequences: - Leg and foot pieces (pants, boots, sneakers) — safe to cut out, limb volume does not drive the garment's shape. - **Torso pieces** (shirt, vest, jacket) — they were modelled over a narrower torso than the original mesh. The generated 3D tends to come out tight. Warn the user before they send it to an image-to-3D generator. ## Where output lands The server writes to `IMAGE_OUTPUT_DIR` (an MCP environment variable) and rejects any `outputPath` outside it. Pass a bare filename and copy the result into the character's folder afterwards. ## References - `references/prompt-template.md` — the prompt architecture, with a real example - `references/resolutions-and-proportions.md` — aspect ratios, per-edge margins, Blender export settings, the mandatory pre-flight check, and what to feed an image-to-3D generator - `scripts/measure.py` — bounding box, occupancy and margins
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.