Cast portraits round 3: re-render Aqua, Nibu and Void under batch A's block; final contact sheet
Kept libby, heimdall, kiko, weksa and eureka r2a. Nibu's connector clip lands in r3a (r3b tests a named-object clip description). Void fills the frame; Aqua gains scales but the beak returns. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
@ -202,3 +202,33 @@ non-human figures: Aqua and Void sit smaller in frame than the busts.
|
|||
- The scale of Aqua and Void needs a framing statement in their character blocks, for example "fills the frame
|
||||
as fully as the others".
|
||||
- Weksa's dust smudge may need toning down.
|
||||
|
||||
# Round 3
|
||||
|
||||
Operator direction: "keep the renders that are already fine, no?" Batch A is the set: libby-r2a,
|
||||
heimdall-r2a, kiko-r2a, weksa-r2a and eureka-r2a stay as they are. Only the misses are re-rendered, with
|
||||
batch A's shared block byte for byte (two heads tall), so the new renders match the kept ones. There are four
|
||||
renders and no re-rolls. Files are in `r3/<name>/` in the same layout as round 2, and the 2k originals are in
|
||||
`F:\Projects\cast-art-originals\r3\`. `r3/render_r3.py` and `r3/matte_r3.py` hold the prompts and the same
|
||||
matte as round 2. `r3/contact-final.png` shows the chosen set of eight at one scale.
|
||||
|
||||
- **aqua-r3a**: the character block says he fills the frame like the busts and draws the scales as rows of
|
||||
outlined curved shapes.
|
||||
- **void-r3a**: the character block says he fills the frame like the busts.
|
||||
- **nibu-r3a**: the same prompt as nibu-r2a, a fresh render. It is the baseline for r3b.
|
||||
- **nibu-r3b**: one variable against r3a, the way the clip is described. The geometric description ("a short
|
||||
rectangular plug body with a round pink bead at each end") became a named object ("shaped exactly like a tiny
|
||||
USB cable plug, a rectangular metal-and-pink connector head with a short cable stub").
|
||||
|
||||
| Render | Observation | Agent verdict | Operator verdict |
|
||||
|---|---|---|---|
|
||||
| aqua-r3a | Scales all over the body, clearly outlined. He is larger in frame than aqua-r2a but still smaller than the busts, with the lower part of the frame empty. The mouth came out as a small pointed beak again, despite "no beak". | Partial: scales fixed; the beak is back and the scale is only partly fixed. | |
|
||||
| nibu-r3a | Under A's proportions, the clip is a pink rectangular plug with a bead at each end, matching the sheet's connector clip. Calm, arms folded, circuit sleeves, cyan device. | Holds. Chosen for the set. | |
|
||||
| nibu-r3b | The clip is a recognisable USB plug with a cable stub, but it is grey and pink and drops the sheet's pink end beads. | Holds on the variable (a recognisable connector), but further from canon than r3a. | |
|
||||
| void-r3a | The hood and scarf now fill the frame like the busts, cut at mid-chest. Canon kept: black face, white oval eyes, frayed orange scarf, gloves. | Holds. | |
|
||||
|
||||
The set in `contact-final.png` is libby-r2a, heimdall-r2a, kiko-r2a, aqua-r3a, weksa-r2a, nibu-r3a,
|
||||
eureka-r2a and void-r3a. No halo shows on any of the round-3 cutouts on a dark or a light checker.
|
||||
|
||||
Still open: Aqua's mouth. A negative ("no beak") does not hold. A positive description of the shape may do
|
||||
better, for example the icon's wide open smile, or a mouth drawn as a small round "o" with no point.
|
||||
|
|
|
|||
BIN
cast-portraits/r3/aqua/aqua-r3a-cutout.png
Normal file
|
After Width: | Height: | Size: 489 KiB |
25
cast-portraits/r3/aqua/aqua-r3a.txt
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
# Aqua r3a
|
||||
|
||||
## Hypothesis
|
||||
|
||||
Batch A's shared block unchanged; the character block states that Aqua fills the frame as the busts do and draws scales as rows of outlined curved shapes, so he matches the batch in scale and gets his canon scales.
|
||||
|
||||
## Variable changed
|
||||
|
||||
Against aqua-r2a: character block only. Added the frame-filling statement; scales described as rows of outlined curved scale shapes; 'soft lips' on the mouth. Shared block identical to batch A.
|
||||
|
||||
## Render record
|
||||
|
||||
- Model: FLUX 3 Image, `POST https://api.bfl.ai/v1/flux-3-image`
|
||||
- Parameters: aspect_ratio 4:5, resolution 2k, safety_tolerance default, grounding default; no seed field; rendered from scratch with no reference image or edit
|
||||
- Output: 1824x2288, source format PNG; 2k original kept out of git at F:/Projects/cast-art-originals/r3/aqua-r3a.png
|
||||
- Committed: aqua-r3a.webp (lossless, 1024 px long side) and aqua-r3a-cutout.png (transparent, 1024 px long side)
|
||||
- Request id: b25a9f19-7f5d-40a7-8d75-4be317c2bef8
|
||||
- Date: 2026-10-10
|
||||
- Composition: shared style block (batch A's block, byte-identical to r2a), blank line, character block
|
||||
|
||||
## Prompt
|
||||
|
||||
Character portrait for a game cast lineup: a bust, head and shoulders cropped at mid-chest by the bottom edge of the frame, the character in three-quarter view turned toward the right side of the frame, the head centred horizontally with its top a small margin below the top edge, the same crop and scale for every character. Super-deformed chibi proportions: the character is two heads tall in total, so the head is very large compared with the small shoulders and narrow torso. Clean 2D anime illustration drawn to be traced into vector art: one bold dark outline of even weight around the whole silhouette, thinner inner lines, flat cel shading with exactly one base tone and one shadow tone per material, light from the upper left. No gradients, no texture, no painterly blending, no glow halos, no pixel art, no 3D rendering. A limited palette of five or six flat colours taken from the character's key colours. Large expressive anime eyes with two white highlights. The background is one perfectly flat, uniform, solid bright chroma-key green from edge to edge: no gradient, no vignette, no floor, no cast shadow, no particles, no props or scenery behind the figure.
|
||||
|
||||
Aqua, a cartoon goldfish DJ. He is a fish, so instead of a bust his round body fills the frame as fully as the human busts do: the top of the head a small margin below the top edge, the figure spanning most of the frame width, with the tail fin allowed to touch the frame edge: a round chubby goldfish with a golden-yellow face and an orange body covered all over in clearly outlined overlapping fish scales, drawn as rows of small curved scale shapes on the body; big round blue eyes with white highlights, a small round fish mouth with soft lips, no beak, no bill, no legs and no feet; a little orange crest fin on top of the head; large black over-ear studio headphones with cyan rings on the ear cups. Bright orange pectoral fins, one raised, and a flowing forked orange tail fin. Key colours: orange and cyan.
|
||||
BIN
cast-portraits/r3/aqua/aqua-r3a.webp
Normal file
|
After Width: | Height: | Size: 568 KiB |
BIN
cast-portraits/r3/contact-final.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
44
cast-portraits/r3/matte_r3.py
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
"""Round 3: same matte as matte_r2.py on the four re-renders, then the final contact sheet.
|
||||
Usage: matte_r3.py [nibu-pick] (nibu-pick is r3a or r3b; omitted, only the cutouts and checks are made)."""
|
||||
import pathlib, sys
|
||||
from PIL import Image, ImageDraw
|
||||
import matte_r2 as m
|
||||
|
||||
ORIG = pathlib.Path(r"F:/Projects/cast-art-originals/r3")
|
||||
R2 = pathlib.Path(r"F:/Projects/gamecult-site-wt-portraits/cast-portraits/r2")
|
||||
R3 = pathlib.Path(r"F:/Projects/gamecult-site-wt-portraits/cast-portraits/r3")
|
||||
JOBS = [("aqua", "r3a"), ("nibu", "r3a"), ("nibu", "r3b"), ("void", "r3a")]
|
||||
|
||||
def cutouts():
|
||||
m.SCR.mkdir(exist_ok=True)
|
||||
for n, suf in JOBS:
|
||||
im = Image.open(ORIG / f"{n}-{suf}.png")
|
||||
out, cg, std, rc = m.matte(im)
|
||||
d = R3 / n; d.mkdir(parents=True, exist_ok=True)
|
||||
m.fit(im.convert("RGB")).save(d / f"{n}-{suf}.webp", "WEBP", lossless=True, quality=100, method=6)
|
||||
c = m.fit(out); c.save(d / f"{n}-{suf}-cutout.png", optimize=True)
|
||||
pair = Image.new("RGB", (c.width * 2, c.height))
|
||||
for i, dark in enumerate((True, False)):
|
||||
bg = m.checker(c.size, dark); bg.paste(c, (0, 0), c); pair.paste(bg, (i * c.width, 0))
|
||||
pair.resize((pair.width // 2, pair.height // 2)).save(m.SCR / f"{n}-{suf}-check.png")
|
||||
print(f"{n}-{suf}: corner greenness {[round(x) for x in cg]}, corner std {std}, residual green px {rc}")
|
||||
|
||||
def final(nibu):
|
||||
picks = [("libby", R2, "r2a"), ("heimdall", R2, "r2a"), ("kiko", R2, "r2a"), ("aqua", R3, "r3a"),
|
||||
("weksa", R2, "r2a"), ("nibu", R3, nibu), ("eureka", R2, "r2a"), ("void", R3, "r3a")]
|
||||
cw, ch, pad, lab = 400, 500, 16, 44
|
||||
W = pad + len(picks) * (cw + pad); H = lab + ch + pad
|
||||
sheet = Image.new("RGB", (W, H), (128, 128, 128)); d = ImageDraw.Draw(sheet); f = m.font(26)
|
||||
for i, (n, root, suf) in enumerate(picks):
|
||||
x = pad + i * (cw + pad)
|
||||
d.text((x, 10), f"{n} {suf}", fill=(20, 20, 20), font=f)
|
||||
c = Image.open(root / n / f"{n}-{suf}-cutout.png").resize((cw, ch), Image.LANCZOS)
|
||||
sheet.paste(c, (x, lab), c)
|
||||
p = R3 / "contact-final.png"; sheet.save(p, optimize=True)
|
||||
print(f"{p.name}: {sheet.size}, {p.stat().st_size / 1e6:.2f} MB")
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) > 1:
|
||||
final(sys.argv[1])
|
||||
else:
|
||||
cutouts()
|
||||
BIN
cast-portraits/r3/nibu/nibu-r3a-cutout.png
Normal file
|
After Width: | Height: | Size: 601 KiB |
25
cast-portraits/r3/nibu/nibu-r3a.txt
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
# Nibu r3a
|
||||
|
||||
## Hypothesis
|
||||
|
||||
Batch A's shared block unchanged with the round-2 clip wording (which came right once, in nibu-r2b): a fresh render under A's proportions tests whether that wording carries the connector clip.
|
||||
|
||||
## Variable changed
|
||||
|
||||
None against nibu-r2a: identical prompt, a fresh render (baseline for nibu-r3b).
|
||||
|
||||
## Render record
|
||||
|
||||
- Model: FLUX 3 Image, `POST https://api.bfl.ai/v1/flux-3-image`
|
||||
- Parameters: aspect_ratio 4:5, resolution 2k, safety_tolerance default, grounding default; no seed field; rendered from scratch with no reference image or edit
|
||||
- Output: 1824x2288, source format PNG; 2k original kept out of git at F:/Projects/cast-art-originals/r3/nibu-r3a.png
|
||||
- Committed: nibu-r3a.webp (lossless, 1024 px long side) and nibu-r3a-cutout.png (transparent, 1024 px long side)
|
||||
- Request id: 55e93567-b9d1-4e8a-8151-545938919321
|
||||
- Date: 2026-10-10
|
||||
- Composition: shared style block (batch A's block, byte-identical to r2a), blank line, character block
|
||||
|
||||
## Prompt
|
||||
|
||||
Character portrait for a game cast lineup: a bust, head and shoulders cropped at mid-chest by the bottom edge of the frame, the character in three-quarter view turned toward the right side of the frame, the head centred horizontally with its top a small margin below the top edge, the same crop and scale for every character. Super-deformed chibi proportions: the character is two heads tall in total, so the head is very large compared with the small shoulders and narrow torso. Clean 2D anime illustration drawn to be traced into vector art: one bold dark outline of even weight around the whole silhouette, thinner inner lines, flat cel shading with exactly one base tone and one shadow tone per material, light from the upper left. No gradients, no texture, no painterly blending, no glow halos, no pixel art, no 3D rendering. A limited palette of five or six flat colours taken from the character's key colours. Large expressive anime eyes with two white highlights. The background is one perfectly flat, uniform, solid bright chroma-key green from edge to edge: no gradient, no vignette, no floor, no cast shadow, no particles, no props or scenery behind the figure.
|
||||
|
||||
Nibu, a quiet, serious worldbuilder girl: very long pale lavender hair with a swept side fringe, a pink hair clip on the left shaped like a small data connector plug, a short rectangular plug body with a round pink bead at each end; a large pink ribbon bow on the right, half-lidded violet eyes, a calm unsmiling expression, arms folded. Wears a sleeveless lilac blouse with a frilled collar, detached dark purple sleeves with circuit-pattern embroidery, a small cyan ring device on the shoulder, and a long dark purple coat. Key colours: violet and pink with a cyan accent.
|
||||
BIN
cast-portraits/r3/nibu/nibu-r3a.webp
Normal file
|
After Width: | Height: | Size: 566 KiB |
BIN
cast-portraits/r3/nibu/nibu-r3b-cutout.png
Normal file
|
After Width: | Height: | Size: 711 KiB |
25
cast-portraits/r3/nibu/nibu-r3b.txt
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
# Nibu r3b
|
||||
|
||||
## Hypothesis
|
||||
|
||||
Naming a familiar object (a tiny USB cable plug) instead of describing geometry (a rectangular body with a bead at each end) makes FLUX draw a recognisable connector clip.
|
||||
|
||||
## Variable changed
|
||||
|
||||
Against nibu-r3a: the clip description only. Geometric description became a named object: 'shaped exactly like a tiny USB cable plug, a rectangular metal-and-pink connector head with a short cable stub, worn sideways in her hair'.
|
||||
|
||||
## Render record
|
||||
|
||||
- Model: FLUX 3 Image, `POST https://api.bfl.ai/v1/flux-3-image`
|
||||
- Parameters: aspect_ratio 4:5, resolution 2k, safety_tolerance default, grounding default; no seed field; rendered from scratch with no reference image or edit
|
||||
- Output: 1824x2288, source format PNG; 2k original kept out of git at F:/Projects/cast-art-originals/r3/nibu-r3b.png
|
||||
- Committed: nibu-r3b.webp (lossless, 1024 px long side) and nibu-r3b-cutout.png (transparent, 1024 px long side)
|
||||
- Request id: 9f5d1c36-2347-407d-b45f-e7cc6c319c34
|
||||
- Date: 2026-10-10
|
||||
- Composition: shared style block (batch A's block, byte-identical to r2a), blank line, character block
|
||||
|
||||
## Prompt
|
||||
|
||||
Character portrait for a game cast lineup: a bust, head and shoulders cropped at mid-chest by the bottom edge of the frame, the character in three-quarter view turned toward the right side of the frame, the head centred horizontally with its top a small margin below the top edge, the same crop and scale for every character. Super-deformed chibi proportions: the character is two heads tall in total, so the head is very large compared with the small shoulders and narrow torso. Clean 2D anime illustration drawn to be traced into vector art: one bold dark outline of even weight around the whole silhouette, thinner inner lines, flat cel shading with exactly one base tone and one shadow tone per material, light from the upper left. No gradients, no texture, no painterly blending, no glow halos, no pixel art, no 3D rendering. A limited palette of five or six flat colours taken from the character's key colours. Large expressive anime eyes with two white highlights. The background is one perfectly flat, uniform, solid bright chroma-key green from edge to edge: no gradient, no vignette, no floor, no cast shadow, no particles, no props or scenery behind the figure.
|
||||
|
||||
Nibu, a quiet, serious worldbuilder girl: very long pale lavender hair with a swept side fringe, a pink hair clip on the left shaped exactly like a tiny USB cable plug, a rectangular metal-and-pink connector head with a short cable stub, worn sideways in her hair; a large pink ribbon bow on the right, half-lidded violet eyes, a calm unsmiling expression, arms folded. Wears a sleeveless lilac blouse with a frilled collar, detached dark purple sleeves with circuit-pattern embroidery, a small cyan ring device on the shoulder, and a long dark purple coat. Key colours: violet and pink with a cyan accent.
|
||||
BIN
cast-portraits/r3/nibu/nibu-r3b.webp
Normal file
|
After Width: | Height: | Size: 571 KiB |
153
cast-portraits/r3/render_r3.py
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
"""Round 2 cast portraits. Key read from F:/Projects/bfl-api.txt inside this process only; never printed or written."""
|
||||
import json, time, urllib.request, urllib.error, io, sys, datetime, pathlib, concurrent.futures as cf
|
||||
from PIL import Image
|
||||
|
||||
REC = pathlib.Path(r"F:/Projects/gamecult-site-wt-portraits/cast-portraits/r3")
|
||||
ORIG = pathlib.Path(r"F:/Projects/cast-art-originals/r3")
|
||||
ENDPOINT = "https://api.bfl.ai/v1/flux-3-image"
|
||||
|
||||
STYLE_T = (
|
||||
"Character portrait for a game cast lineup: a bust, head and shoulders cropped at mid-chest by the bottom edge of the frame, "
|
||||
"the character in three-quarter view turned toward the right side of the frame, the head centred horizontally with its top a small margin "
|
||||
"below the top edge, the same crop and scale for every character. "
|
||||
"Super-deformed chibi proportions: the character is {N} heads tall in total, so the head is very large compared with the small shoulders and narrow torso. "
|
||||
"Clean 2D anime illustration drawn to be traced into vector art: one bold dark outline of even weight around the whole silhouette, "
|
||||
"thinner inner lines, flat cel shading with exactly one base tone and one shadow tone per material, light from the upper left. "
|
||||
"No gradients, no texture, no painterly blending, no glow halos, no pixel art, no 3D rendering. "
|
||||
"A limited palette of five or six flat colours taken from the character's key colours. Large expressive anime eyes with two white highlights. "
|
||||
"The background is one perfectly flat, uniform, solid bright chroma-key green from edge to edge: no gradient, no vignette, no floor, "
|
||||
"no cast shadow, no particles, no props or scenery behind the figure."
|
||||
)
|
||||
RATIO = {"r2a": "two", "r2b": "three"}
|
||||
|
||||
C = {}
|
||||
C["libby"] = ("Libby, a cheerful young librarian-witch, warm and bookish: thick voluminous wavy hair in a deep dusky violet-lavender with a big swept side fringe, "
|
||||
"gathered into one loose, fat wavy braid that falls forward over her right shoulder; a white crossed-bone hair clip on the left side of her head; "
|
||||
"a dark purple ribbon bow with a mauve diamond pattern tied at the top of the braid. Round thin black-framed glasses, large grey-violet eyes, "
|
||||
"small gold drop earrings, pale skin with rosy cheeks, a big open-mouthed happy smile. She wears a high-collared black scholar's robe with wide sleeves, "
|
||||
"embroidered in gold and dusky mauve diamond and rune patterns, with a violet gem brooch in a gold setting at the collar. "
|
||||
"She hugs an old brown leather book with gold corners against her chest, a faint violet light along its page edges. Key colours: black and gold with violet.")
|
||||
C["heimdall"] = ("Heimdall, a stern young gatekeeper: dark brown skin, a mop of messy dark brown curly hair with golden highlights, "
|
||||
"glowing golden amber eyes, a serious frown, one small gold earring. He wears a high-collared black coat with royal blue lapels and a royal blue cape "
|
||||
"trimmed in gold filigree, small blue gems on the shoulder armour, and a gold key-shaped clasp at the throat. "
|
||||
"He holds an ornate golden key raised beside his shoulder. Key colours: gold and cobalt blue.")
|
||||
C["kiko"] = ("Kiko, an excitable fox-girl streamer: messy white shoulder-length hair, tall white fox ears with pink insides, "
|
||||
"a white kitsune fox mask with red and magenta markings worn pushed up on top of her head, black hair ornaments with gold bells and magenta tassels, "
|
||||
"bright cyan eyes, a wide open-mouthed grin with one small fang, one hand raised in a wave. "
|
||||
"She wears a black kimono-style jacket with magenta and teal trim and a gold bell at the collar. "
|
||||
"A fluffy white fox tail with pink tips curls up behind one shoulder. Key colours: magenta and cyan.")
|
||||
C["aqua"] = ("Aqua, a cartoon goldfish DJ. He is a fish, so his whole body is in the frame instead of a bust: a round chubby goldfish with a golden-yellow face "
|
||||
"and an orange body covered in clearly drawn overlapping fish scales, big round blue eyes with white highlights, a small round fish mouth, "
|
||||
"no beak, no bill, no legs and no feet; a little orange crest fin on top of the head; large black over-ear studio headphones with cyan rings on the ear cups. "
|
||||
"Bright orange pectoral fins, one raised, and a flowing forked orange tail fin. Key colours: orange and cyan.")
|
||||
C["weksa"] = ("Weksa, a tomboyish young woman, an adventurous field archaeologist in the Indiana Jones mould: warm brown skin, a confident lopsided grin, "
|
||||
"a smudge of dust on one cheek, messy dark brown shoulder-length hair tied partly up in a topknot with turquoise and amber beads and small feathers, "
|
||||
"large round gold-rimmed glasses, warm amber-brown eyes, dangling turquoise earrings. She wears a cream linen robe with teal embroidered trim, "
|
||||
"its sleeves rolled up to the elbows, over a weathered brown leather vest, with beaded necklaces and wooden bead bracelets and a leather strap across her chest; "
|
||||
"a battered brown leather backpack stuffed with rolled scrolls and a small carved idol shows behind one shoulder. "
|
||||
"She holds up a small paper card with a hand-drawn glyph between two fingers. No hat. Key colours: teal and amber on earthy browns.")
|
||||
C["nibu"] = ("Nibu, a quiet, serious worldbuilder girl: very long pale lavender hair with a swept side fringe, "
|
||||
"a pink hair clip on the left shaped like a small data connector plug, a short rectangular plug body with a round pink bead at each end; "
|
||||
"a large pink ribbon bow on the right, half-lidded violet eyes, a calm unsmiling expression, arms folded. "
|
||||
"Wears a sleeveless lilac blouse with a frilled collar, detached dark purple sleeves with circuit-pattern embroidery, "
|
||||
"a small cyan ring device on the shoulder, and a long dark purple coat. Key colours: violet and pink with a cyan accent.")
|
||||
C["eureka"] = ("Eureka, a neon-noir bug hunter: a young woman with messy shoulder-length black hair with one bright orange streak in the fringe, "
|
||||
"sharp focused blue-grey eyes, a slight knowing smile. She wears a dark charcoal trenchcoat with the hood up, framing her face, and a high collar; "
|
||||
"the hood's edge and the coat's seams are piped with ember-orange lines, over tactical gear: chest straps, buckles and pouches. "
|
||||
"Fingerless gloves; she holds a slim orange metal probe. Key colour: ember orange.")
|
||||
C["void"] = ("Void, a small hooded shadow figure: a deep indigo-violet robe with a large pointed hood, the face inside the hood completely black "
|
||||
"with no features except two tall white glowing oval eyes, a thick bright orange scarf wrapped around the neck with frayed ends trailing to one side, "
|
||||
"dark gloved hands. Key colours: indigo violet and orange.")
|
||||
|
||||
HYP = {
|
||||
"r2a": ("Consistency: one shared style block, byte-identical across all eight prompts, states the proportions as an explicit head count "
|
||||
"(two heads tall) instead of the bare word chibi that failed in round 1, and fixes framing, line, shading, palette rule and a flat "
|
||||
"chroma-key green ground for a deterministic cutout. Per-character text describes only the character."),
|
||||
"r2b": ("Same as r2a with one variable changed: the figure is three heads tall instead of two, testing whether a milder, more achievable "
|
||||
"ratio is followed more uniformly across the cast."),
|
||||
}
|
||||
VAR = {"r2a": "Batch A baseline: shared style block with ratio two heads tall, then the character block.",
|
||||
"r2b": "Ratio only: 'two heads tall' became 'three heads tall' in the shared block, against the same character's r2a. Character block identical."}
|
||||
|
||||
# Round 3: re-render only the batch-A misses with batch A's shared block byte for byte (two heads tall).
|
||||
RATIO = {"r3a": "two", "r3b": "two"}
|
||||
FILL = ("fills the frame as fully as the human busts do: the top of the head a small margin below the top edge, "
|
||||
"the figure spanning most of the frame width, cut by the bottom edge at mid-chest")
|
||||
C["aqua"] = ("Aqua, a cartoon goldfish DJ. He is a fish, so instead of a bust his round body " + FILL.replace(", cut by the bottom edge at mid-chest", "") +
|
||||
", with the tail fin allowed to touch the frame edge: a round chubby goldfish with a golden-yellow face "
|
||||
"and an orange body covered all over in clearly outlined overlapping fish scales, drawn as rows of small curved scale shapes on the body; "
|
||||
"big round blue eyes with white highlights, a small round fish mouth with soft lips, no beak, no bill, no legs and no feet; "
|
||||
"a little orange crest fin on top of the head; large black over-ear studio headphones with cyan rings on the ear cups. "
|
||||
"Bright orange pectoral fins, one raised, and a flowing forked orange tail fin. Key colours: orange and cyan.")
|
||||
C["void"] = C["void"].replace("Void, a small hooded shadow figure:", "Void, a hooded shadow figure who " + FILL + ":")
|
||||
NIBU_CLIP_A = "a pink hair clip on the left shaped like a small data connector plug, a short rectangular plug body with a round pink bead at each end; "
|
||||
NIBU_CLIP_B = "a pink hair clip on the left shaped exactly like a tiny USB cable plug, a rectangular metal-and-pink connector head with a short cable stub, worn sideways in her hair; "
|
||||
assert NIBU_CLIP_A in C["nibu"]
|
||||
C["nibu_b"] = C["nibu"].replace(NIBU_CLIP_A, NIBU_CLIP_B)
|
||||
|
||||
HYP = {
|
||||
("aqua", "r3a"): "Batch A's shared block unchanged; the character block states that Aqua fills the frame as the busts do and draws scales as rows of outlined curved shapes, so he matches the batch in scale and gets his canon scales.",
|
||||
("void", "r3a"): "Batch A's shared block unchanged; the character block states that Void fills the frame as the busts do, so he matches the batch in scale.",
|
||||
("nibu", "r3a"): "Batch A's shared block unchanged with the round-2 clip wording (which came right once, in nibu-r2b): a fresh render under A's proportions tests whether that wording carries the connector clip.",
|
||||
("nibu", "r3b"): "Naming a familiar object (a tiny USB cable plug) instead of describing geometry (a rectangular body with a bead at each end) makes FLUX draw a recognisable connector clip.",
|
||||
}
|
||||
VAR = {
|
||||
("aqua", "r3a"): "Against aqua-r2a: character block only. Added the frame-filling statement; scales described as rows of outlined curved scale shapes; 'soft lips' on the mouth. Shared block identical to batch A.",
|
||||
("void", "r3a"): "Against void-r2a: character block only. 'a small hooded shadow figure' became 'a hooded shadow figure who fills the frame as fully as the human busts do ...'. Shared block identical to batch A.",
|
||||
("nibu", "r3a"): "None against nibu-r2a: identical prompt, a fresh render (baseline for nibu-r3b).",
|
||||
("nibu", "r3b"): "Against nibu-r3a: the clip description only. Geometric description became a named object: 'shaped exactly like a tiny USB cable plug, a rectangular metal-and-pink connector head with a short cable stub, worn sideways in her hair'.",
|
||||
}
|
||||
NAMES = ["aqua", "nibu", "void"]
|
||||
JOBS = [("aqua", "r3a"), ("nibu", "r3a"), ("nibu", "r3b"), ("void", "r3a")]
|
||||
|
||||
def prompt_for(n, suf):
|
||||
return STYLE_T.format(N=RATIO[suf]) + "\n\n" + C["nibu_b" if (n, suf) == ("nibu", "r3b") else n]
|
||||
|
||||
def req(url, key, data=None):
|
||||
r = urllib.request.Request(url, data=json.dumps(data).encode() if data else None,
|
||||
headers={"x-key": key, "Content-Type": "application/json", "accept": "application/json"})
|
||||
return json.load(urllib.request.urlopen(r, timeout=60))
|
||||
|
||||
def run(job, key):
|
||||
n, suf = job
|
||||
d = REC / n; d.mkdir(parents=True, exist_ok=True)
|
||||
png = ORIG / f"{n}-{suf}.png"
|
||||
if png.exists():
|
||||
return f"{n}-{suf}: exists, skipped"
|
||||
prompt = prompt_for(n, suf)
|
||||
try:
|
||||
j = req(ENDPOINT, key, {"prompt": prompt, "aspect_ratio": "4:5", "resolution": "2k"})
|
||||
except urllib.error.HTTPError as e:
|
||||
return f"{n}-{suf}: submit HTTP {e.code} {e.read()[:300]!r}"
|
||||
rid, poll = j.get("id"), j.get("polling_url")
|
||||
for _ in range(240):
|
||||
time.sleep(6)
|
||||
try: s = req(poll, key)
|
||||
except Exception: continue
|
||||
st = s.get("status")
|
||||
if st == "Ready":
|
||||
raw = urllib.request.urlopen(s["result"]["sample"], timeout=120).read()
|
||||
im = Image.open(io.BytesIO(raw)); fmt = im.format; im.save(png, "PNG")
|
||||
txt = (f"# {n.capitalize()} {suf}\n\n## Hypothesis\n\n{HYP[(n, suf)]}\n\n## Variable changed\n\n{VAR[(n, suf)]}\n\n"
|
||||
f"## Render record\n\n- Model: FLUX 3 Image, `POST {ENDPOINT}`\n"
|
||||
f"- Parameters: aspect_ratio 4:5, resolution 2k, safety_tolerance default, grounding default; no seed field; "
|
||||
f"rendered from scratch with no reference image or edit\n- Output: {im.size[0]}x{im.size[1]}, source format {fmt}; "
|
||||
f"2k original kept out of git at F:/Projects/cast-art-originals/r3/{n}-{suf}.png\n"
|
||||
f"- Committed: {n}-{suf}.webp (lossless, 1024 px long side) and {n}-{suf}-cutout.png (transparent, 1024 px long side)\n"
|
||||
f"- Request id: {rid}\n- Date: {datetime.date.today().isoformat()}\n"
|
||||
f"- Composition: shared style block (batch A's block, byte-identical to r2a), blank line, character block\n\n"
|
||||
f"## Prompt\n\n{prompt}\n")
|
||||
(d / f"{n}-{suf}.txt").write_text(txt, encoding="utf-8")
|
||||
return f"{n}-{suf}: Ready {im.size}"
|
||||
if st in ("Error", "Failed", "Content Moderated", "Request Moderated", "Task not found"):
|
||||
return f"{n}-{suf}: {st} {str(s)[:200]}"
|
||||
return f"{n}-{suf}: timeout"
|
||||
|
||||
if __name__ == "__main__":
|
||||
key = pathlib.Path(r"F:/Projects/bfl-api.txt").read_text().strip()
|
||||
only = sys.argv[1:]
|
||||
jobs = [j for j in JOBS if not only or f"{j[0]}-{j[1]}" in only]
|
||||
with cf.ThreadPoolExecutor(max_workers=6) as ex:
|
||||
for r in ex.map(lambda j: run(j, key), jobs):
|
||||
print(r, flush=True)
|
||||
print("DONE", flush=True)
|
||||
BIN
cast-portraits/r3/void/void-r3a-cutout.png
Normal file
|
After Width: | Height: | Size: 526 KiB |
25
cast-portraits/r3/void/void-r3a.txt
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
# Void r3a
|
||||
|
||||
## Hypothesis
|
||||
|
||||
Batch A's shared block unchanged; the character block states that Void fills the frame as the busts do, so he matches the batch in scale.
|
||||
|
||||
## Variable changed
|
||||
|
||||
Against void-r2a: character block only. 'a small hooded shadow figure' became 'a hooded shadow figure who fills the frame as fully as the human busts do ...'. Shared block identical to batch A.
|
||||
|
||||
## Render record
|
||||
|
||||
- Model: FLUX 3 Image, `POST https://api.bfl.ai/v1/flux-3-image`
|
||||
- Parameters: aspect_ratio 4:5, resolution 2k, safety_tolerance default, grounding default; no seed field; rendered from scratch with no reference image or edit
|
||||
- Output: 1824x2288, source format PNG; 2k original kept out of git at F:/Projects/cast-art-originals/r3/void-r3a.png
|
||||
- Committed: void-r3a.webp (lossless, 1024 px long side) and void-r3a-cutout.png (transparent, 1024 px long side)
|
||||
- Request id: ad1e14d3-789d-4fb5-af39-51cfe6b8e2da
|
||||
- Date: 2026-10-10
|
||||
- Composition: shared style block (batch A's block, byte-identical to r2a), blank line, character block
|
||||
|
||||
## Prompt
|
||||
|
||||
Character portrait for a game cast lineup: a bust, head and shoulders cropped at mid-chest by the bottom edge of the frame, the character in three-quarter view turned toward the right side of the frame, the head centred horizontally with its top a small margin below the top edge, the same crop and scale for every character. Super-deformed chibi proportions: the character is two heads tall in total, so the head is very large compared with the small shoulders and narrow torso. Clean 2D anime illustration drawn to be traced into vector art: one bold dark outline of even weight around the whole silhouette, thinner inner lines, flat cel shading with exactly one base tone and one shadow tone per material, light from the upper left. No gradients, no texture, no painterly blending, no glow halos, no pixel art, no 3D rendering. A limited palette of five or six flat colours taken from the character's key colours. Large expressive anime eyes with two white highlights. The background is one perfectly flat, uniform, solid bright chroma-key green from edge to edge: no gradient, no vignette, no floor, no cast shadow, no particles, no props or scenery behind the figure.
|
||||
|
||||
Void, a hooded shadow figure who fills the frame as fully as the human busts do: the top of the head a small margin below the top edge, the figure spanning most of the frame width, cut by the bottom edge at mid-chest: a deep indigo-violet robe with a large pointed hood, the face inside the hood completely black with no features except two tall white glowing oval eyes, a thick bright orange scarf wrapped around the neck with frayed ends trailing to one side, dark gloved hands. Key colours: indigo violet and orange.
|
||||
BIN
cast-portraits/r3/void/void-r3a.webp
Normal file
|
After Width: | Height: | Size: 522 KiB |