Track C: Codex with GPT-6.1-Terra end to end
agent
+11:50The revised recipes are now being rendered through the last few expressions. I’m also checking that any second-round changes stay confined to the intended face presentation rather than altering body geometry.
write_stdinpoll session 61266
input
const r=await tools.write_stdin({session_id:61266,chars:"",yield_time_ms:50000,max_output_tokens:3000});text(JSON.stringify(r));result, 4 lines
Script running with cell ID 33 Wall time 31.0 seconds Output:
waitcell 33
input
{ "cell_id": "33", "yield_time_ms": 20000 }result, 4 lines
Script completed Wall time 2.7 seconds Output: {"chunk_id":"fb2045","wall_time_seconds":35.624325656,"exit_code":0,"original_token_count":151,"output":"arm_f_slender ~/Projects/lowmarch-bench/work/c/shot_r1/surprised/painted_arm_f_slender.png 14s\narm_m_youth ~/Projects/lowmarch-bench/work/c/shot_r1/surprised/painted_arm_m_youth.png 13s\narm_f_slender ~/Projects/lowmarch-bench/work/c/shot_r1/wink/painted_arm_f_slender.png 16s\narm_m_youth ~/Projects/lowmarch-bench/work/c/shot_r1/wink/painted_arm_m_youth.png 16s\nshot r1\n~/Projects/lowmarch-bench/work/c/sheet_r1_woman.png (1968, 1144)\n~/Projects/lowmarch-bench/work/c/sheet_r1_youth.png (1968, 1144)\n2026-10-30T12:56:54+08:00\n"}view_image~/Projects/lowmarch-bench/work/c/sheet_r1_woman.png (+1 more)
input
const results=await Promise.all([ tools.view_image({path:"~/Projects/lowmarch-bench/work/c/sheet_r1_woman.png",detail:"original"}), tools.view_image({path:"~/Projects/lowmarch-bench/work/c/sheet_r1_youth.png",detail:"original"}) ]);for(const r of results)image(r.image_url);result, 4 lines
Script completed Wall time 0.2 seconds Output:
view_image~/Projects/lowmarch-bench/work/c/shot_r1/joy/painted_arm_m_youth.png (+2 more)
input
const r=await Promise.all([ tools.view_image({path:"~/Projects/lowmarch-bench/work/c/shot_r1/joy/painted_arm_m_youth.png",detail:"original"}), tools.view_image({path:"~/Projects/lowmarch-bench/work/c/shot_r1/sad/painted_arm_f_slender.png",detail:"original"}), tools.view_image({path:"~/Projects/lowmarch-bench/work/c/shot_r1/wink/painted_arm_m_youth.png",detail:"original"}) ]);for(const x of r)image(x.image_url);result, 4 lines
Script completed Wall time 0.1 seconds Output:
exec_commandsource ~/Projects/lowmarch-bench/kit/env-c.sh && sed -n '690,730p' tools/vroid_portrait.py && rg -n 'eye=|iris=|arm_m_youth|arm_f_slender' tools/heads.py art/cast/cast.py review/vroid-02/build.py | head -100 && sed -n '810,850p' tools/vroid_portrait.py && rg -n 'draw_curve_mouth|mouth' tools/export_glb.py | head -60
command
source ~/Projects/lowmarch-bench/kit/env-c.sh && sed -n '690,730p' tools/vroid_portrait.py && rg -n 'eye=|iris=|arm_m_youth|arm_f_slender' tools/heads.py art/cast/cast.py review/vroid-02/build.py | head -100 && sed -n '810,850p' tools/vroid_portrait.py && rg -n 'draw_curve_mouth|mouth' tools/export_glb.py | head -60
result, 114 lines
Script completed Wall time 0.2 seconds Output: tex = tex.astype(float) tex[..., :3] *= (1 - dark)[..., None] v._img[src] = np.clip(tex, 0, 255).astype(np.uint8) def reshape(prims, roles, lm, sh): """Face length, sculpting, eye size/tilt and mouth width (skeleton and expression are applied earlier, when the primitives are built).""" ey, cy = lm["eye_y"], lm["chin"][1] span = ey - cy if sh["face_len"]: from vrm import bone_weight for p, r in zip(prims, roles): if r in SCULPT_ROLES: t = np.clip((ey - p["pos"][:, 1]) / span, 0, None) d = sh["face_len"] * span * np.minimum(t, 1.0) if r == "body" and "J" in p: # the neck below the head stays where the clothes were fitted d = d * np.clip(bone_weight(p, ("Head",)), 0, 1) p["pos"][:, 1] -= d lm = dict(lm, chin=lm["chin"] - [0, sh["face_len"] * span, 0]) sculpt(prims, roles, lm, sh) for p, r in zip(prims, roles): P = p["pos"] if sh["mouth"] != 1.0 and r == "mouth": P[:, 0] = lm["mouth"][0] + (P[:, 0] - lm["mouth"][0]) * sh["mouth"] if r in ("iris", "highlight") and sh.get("iris", 1.0) != 1.0: # smaller irises read older for c in (lm["eyeL"], lm["eyeR"]): side = (P[:, 0] < 0) if c[0] < 0 else (P[:, 0] >= 0) q = P[side] - c q[:, :2] *= sh["iris"] P[side] = c + q if r in ("iris", "white", "highlight", "line") and (sh["eye"] != 1 or sh["eye_tilt"]): for c in (lm["eyeL"], lm["eyeR"]): side = (P[:, 0] < 0) if c[0] < 0 else (P[:, 0] >= 0) q = P[side] - c q[:, :2] *= sh["eye"] q[:, 1] += sh["eye_tilt"] * np.sign(c[0]) * q[:, 0] * 0.4 P[side] = c + q class Portrait: tools/heads.py:636: start = dict(dict(eye=1.0, iris=1.0, mouth=1.0), **spec.get("sculpt", {})) # where each control starts art/cast/cast.py:258: "arm_m_youth": _head("young", hair="g", z=0.4, g=0.6), art/cast/cast.py:259: "arm_f_slender": _head("young", hair="j", j=1), art/cast/cast.py:268: "arm_m_heavy": "brown", "arm_m_brute": "black", "arm_m_old": "grey", "arm_m_youth": "blond", art/cast/cast.py:269: "arm_f_slender": "blond", "arm_f_average": "brown", "arm_f_strong": "red", "arm_f_sexy": "black", art/cast/cast.py:271:EYE_COLOURS = {"arm_m_heroic": "blue", "arm_f_sexy": "green", "arm_f_slender": "blue", "arm_m_old": "grey", art/cast/cast.py:272: "arm_f_old": "grey", "arm_m_youth": "amber"} art/cast/cast.py:290: "arm_m_youth": ("Man, youth", "m", "ref_m_youth", dict(relax=4)), art/cast/cast.py:291: "arm_f_slender": ("Woman, slender", "f", "ref_f_slender", dict(relax=4, bust_shape=dict(spread=0.008, drop=0.005, flat=0.25))), art/cast/cast.py:308: shape=dict(eye=1.14, head=0.93, neck=1.14, chest=1.10, shoulders=1.28, arms=1.10, torso=1.06, art/cast/cast.py:347: mh=MH_BRUTE, beard=("full", 0.06), age_lines=0.4, iris=0.88, blush=0.3, art/cast/cast.py:352: mh=MH_F_VETERAN, age_lines=0.5, iris=0.84, blush=0.0, mouth=1.05, art/cast/cast.py:385: skin="fair", mh=MH_BRUTE, beard=("full", 0.06), age_lines=0.4, iris=0.88, blush=0.3, art/cast/cast.py:417: eye=0.92, neck=1.2, chest=1.06, rest={"Fcl_EYE_Close": 0.2, "Fcl_BRW_Angry": 0.35}), art/cast/cast.py:423: nose=0.4, nose_w=1.0, eye=0.95, mouth=1.15, neck=1.45, chest=1.18, art/cast/cast.py:429: shape=dict(head=1.05, face_len=-0.08, jaw=-0.3, chin_len=-0.3, eye=1.08, neck=0.85, chest=0.92), art/cast/cast.py:439: shape=dict(face_len=0.06, jaw=-0.3, chin_len=0.3, eye=0.95, eye_tilt=0.25, mouth=0.9, neck = (Wn[names["J_Bip_C_Neck"]][:3, 3], Wn[names["J_Bip_C_Head"]][:3, 3]) \ if "J_Bip_C_Neck" in names and "J_Bip_C_Head" in names else None face_normals(self.prims, self.roles, lm_now, sh["face_normals"], sh["hair_normals"], neck=neck) for pc, rl in shadow_cards(self.prims, self.roles, lm_now, sh["shadow_cards"], neck): self.prims.append(pc) self.roles.append(rl) if pose is not target_pose and any(not np.allclose(pose.get(k_, np.eye(4)), target_pose.get(k_, np.eye(4))) for k_ in set(pose) | set(target_pose)): repose(self.v, [p for p in self.prims if not p.get("world")], pose, target_pose) names = self.v.nodes_by_name() Wn = self.v.node_world() self.eye = (Wn[names["J_Adj_L_FaceEye"]][:3, 3] + Wn[names["J_Adj_R_FaceEye"]][:3, 3]) / 2 self.chin_y = self.lm["chin"][1] self.tex = {} for k, p in enumerate(self.prims): if self.roles[k] in ("line", "brow", "iris", "highlight", "white", "hair", "mouth"): src = self._hair_v if (hair_from and "_HAIR" in p["material"]) else self.v t = src.material_texture(p["mi"]) if t is not None and self.roles[k] == "line": # VRoid's upper lid is a thick graded band over the iris; keep its dark core only t = t.copy() t[..., 3] = np.where(t[..., :3].mean(-1) < LID_CORE, t[..., 3], 0) if t is not None: self.tex[k] = t # painted face marks (lip line, nose) from the face texture, grown so they survive the vote from scipy.ndimage import binary_dilation, label self.marks = {} self.mouth_pts = None self.mouth_curve = None for k, p in enumerate(self.prims): if self.roles[k] != "face": continue t = self.v.material_texture(p["mi"]) if t is None: continue th, tw = t.shape[:2] vv, uu = np.mgrid[0:th, 0:tw] vv, uu = (vv + 0.5) / th, (uu + 0.5) / tw win = ((uu > MARK_WINDOW["u"][0]) & (uu < MARK_WINDOW["u"][1]) & (vv > MARK_WINDOW["v"][0]) & (vv < MARK_WINDOW["v"][1])) raw = (t[..., :3].mean(-1) / 255 < FACE_MARK) & (t[..., 3] > 0) & win 5:the viewer can toggle and x-ray them. Face, eye, line, brow, mouth and hair keep VRoid's textures 18:TEXTURED = ("face", "iris", "white", "highlight", "line", "brow", "mouth", "hair") 22: "grass": "c", "dirt": "f", "stone": "l", "mouth": "2", "line": "o", "iris": "s", "white": "w", 31: if role in ("face", "body", "shadow", "iris", "white", "highlight", "line", "brow", "mouth"): 185: bands per role, the lights, body colliders, cloth grids and the mouth curve (model space, 197: "mouth": dict(mode="flat", color=hexp("1")), "white": dict(mode="flat", color=hexp("w")), 227: if getattr(portrait, "mouth_curve", None) is not None: 232: _, i = cKDTree(allp).query(portrait.mouth_curve) 233: curve = ((portrait.mouth_curve + alln[i] * 0.0015) * FLIP).tolist() 237: img = Image.fromarray(np.where(m == 1, 128, 0).astype(np.uint8), "L") # nose mark only; the mouth is a line 269: mouth_curve=curve, mouth_bone="J_Bip_C_Head", ink=dict(o=hexp("o"), skin=hexp("1"), hair=hexp("A")),
agent
+12:53The sheets show clearer angry and surprised brows, but the first-round sad and angry mouths read almost flat, and the youth’s wink still looks half open. I’m revising those shapes, strengthening the eyelid closure, and reducing the brow overlay before the next comparison.
exec_commandsource ~/Projects/lowmarch-bench/kit/env-c.sh && cat >> "$WORK/NOTES.md" <<'EOF'
command
source ~/Projects/lowmarch-bench/kit/env-c.sh && cat >> "$WORK/NOTES.md" <<'EOF' ## Round 1 — 12:44:40–12:56:54 (12m 14s) Separated brows, eyes and mouths in the recipes, keeping neutral and the basic vowel targets; added a depth-limited brow-over-bangs pass. The reference relies on clear brow/eyelid silhouettes and distinct mouth shapes, so the recipes aim for independent acting instead of the stock ALL controls. The first capture stopped partway through, so completed the missing images with a resumable copy of the kit script. The sheets and 30-degree views show more legible angry, sad and surprised brows, but the overlay is too strong, particularly at neutral. Sad and angry mouths are nearly flat; youth joy and wink retain visible iris/white through the nearly closed lids. The 30-degree views retain the expressions but expose the same eyelid problem. Surprise is smaller than intended; I is a slightly clearer opening than before. EOF python3 - <<'PY' from pathlib import Path p=Path('review/vroid-02/index.html') s=p.read_text().replace('col = mix(col, brow.rgb, 0.85);','col = mix(col, brow.rgb, 0.55);') p.write_text(s) p=Path('art/expressions/armory.txt') s=p.read_text().replace('Fcl_EYE_Joy:1;Fcl_MTH_Joy:0.8','Fcl_EYE_Joy:1;Fcl_EYE_Close:0.35;Fcl_MTH_Joy:0.8').replace('Fcl_MTH_Down:0.8','Fcl_MTH_Angry:1').replace('Fcl_MTH_Down:0.7','Fcl_MTH_Sorrow:1').replace('Fcl_MTH_O:0.45','Fcl_MTH_O:0.7').replace('Fcl_EYE_Close_R:1;','Fcl_EYE_Close_R:1.5;') p.write_text(s) PY cp art/expressions/armory.txt "$WORK/expr_list.txt" && $KIT/build_expr.sh "$WORK/expr_list.txt" joy angry sad surprised wink && date -Isresult, 4 lines
Script completed Wall time 1.2 seconds Output: {"chunk_id":"9780b4","wall_time_seconds":1.001765008,"session_id":53935,"original_token_count":0,"output":""}write_stdinpoll session 53935
input
const r=await tools.write_stdin({session_id:53935,chars:"",yield_time_ms:50000,max_output_tokens:3000});text(JSON.stringify(r));result, 4 lines
Script running with cell ID 38 Wall time 31.0 seconds Output:
waitcell 38
input
{ "cell_id": "38", "yield_time_ms": 20000 }result, 4 lines
Script completed Wall time 13.5 seconds Output: {"chunk_id":"66006a","wall_time_seconds":46.339387279,"exit_code":0,"original_token_count":22,"output":"built joy\nbuilt angry\nbuilt sad\nbuilt surprised\nbuilt wink\n2026-10-30T12:58:19+08:00\n"}exec_commandsource ~/Projects/lowmarch-bench/kit/env-c.sh && $KIT/shoot_expr.sh "$LOWMARCH_REPO/review/vroid-02/index.html" r2 && $KIT/sheets.sh r2 'Round 2: softer brows and eyelid and mouth revisions' && date -Is
command
source ~/Projects/lowmarch-bench/kit/env-c.sh && $KIT/shoot_expr.sh "$LOWMARCH_REPO/review/vroid-02/index.html" r2 && $KIT/sheets.sh r2 'Round 2: softer brows and eyelid and mouth revisions' && date -Is
result, 4 lines
Script completed Wall time 1.2 seconds Output: {"chunk_id":"1aa7d4","wall_time_seconds":1.001800269,"session_id":25485,"original_token_count":0,"output":""}write_stdinpoll session 25485
input
const r=await tools.write_stdin({session_id:25485,chars:"",yield_time_ms:50000,max_output_tokens:3000});text(JSON.stringify(r));result, 4 lines
Script running with cell ID 40 Wall time 31.0 seconds Output:
waitcell 40
input
{ "cell_id": "40", "yield_time_ms": 20000 }result, 4 lines
Script completed Wall time 17.3 seconds Output: {"chunk_id":"dcdaca","wall_time_seconds":50.000953243,"session_id":25485,"original_token_count":0,"output":""}view_image~/Projects/lowmarch-bench/work/c/shot_r2/angry/painted_arm_f_slender.png
input
const im=await tools.view_image({path:"~/Projects/lowmarch-bench/work/c/shot_r2/angry/painted_arm_f_slender.png",detail:"original"});image(im.image_url);result, 4 lines
Script completed Wall time 0.0 seconds Output:
agent
+15:00The second angry close-up now has a distinct frown, and the softened brow is less dominant. I’m watching for a separate limitation: some closed mouth lines are very faint in the painted renderer.
exec_commandsource ~/Projects/lowmarch-bench/kit/env-c.sh && sed -n '850,920p' tools/vroid_portrait.py && sed -n '215,245p' tools/export_glb.py && rg -n 'mouth_curve|mouthCurve|mouthBone|mouth_bone|mouth' review/vroid-02/index.html | head -70
command
source ~/Projects/lowmarch-bench/kit/env-c.sh && sed -n '850,920p' tools/vroid_portrait.py && sed -n '215,245p' tools/export_glb.py && rg -n 'mouth_curve|mouthCurve|mouthBone|mouth_bone|mouth' review/vroid-02/index.html | head -70
result, 107 lines
Script completed Wall time 0.3 seconds Output: raw = (t[..., :3].mean(-1) / 255 < FACE_MARK) & (t[..., 3] > 0) & win grown = binary_dilation(raw, iterations=MARK_GROW) & win # 2 = mouth (dark line), 1 = nose mark (one tone softer) self.marks[k] = np.where(grown, np.where(vv >= MARK_WINDOW["nose_below"], 2, 1), 0).astype(np.uint8) if self.mouth_pts is None and raw.any(): lab, n = label(raw) if n: widths = [np.ptp(np.nonzero(lab == i)[1]) for i in range(1, n + 1)] ys, xs = np.nonzero(lab == 1 + int(np.argmax(widths))) th, tw = raw.shape ends = [(xs.min() + 0.5, ys[xs == xs.min()].mean()), (xs.max() + 0.5, ys[xs == xs.max()].mean()), (xs.mean(), ys.mean())] face_prims = [q for q, r in zip(self.prims, self.roles) if r == "face"] pts = [uv_to_3d(face_prims, (ex / tw, ey / th)) for ex, ey in ends] if pts[0] is not None and pts[1] is not None: if pts[2] is None: pts[2] = (pts[0] + pts[1]) / 2 self.mouth_pts = pts # the painted line's centre, traced across: a 3D curve that hugs the lips lab_m = lab == 1 + int(np.argmax(widths)) curve = [] for x_ in np.linspace(xs.min(), xs.max(), 24): col = np.nonzero(lab_m[:, int(round(x_))])[0] if len(col): q = uv_to_3d(face_prims, ((x_ + 0.5) / tw, (col.mean() + 0.5) / th)) if q is not None: curve.append(q) self.mouth_curve = np.array(curve) if len(curve) >= 4 else None def frame(self, view="bust", pitch=None, w=None, h=None): """The view's camera (self.camera, which the live viewer uses) without rendering.""" return self._frame(view, pitch, w, h)[0] def _frame(self, view, pitch, w, h): if view == "bust": w, h = w or BUST_SIZE[0], h or BUST_SIZE[1] pitch = 4 if pitch is None else pitch pivot = np.array([0, self.lm["eye_y"] - 0.02, self.eye[2]]) s = BUST_EYE_CHIN * SS / self.span (cx, cy), ref_y = (BUST_EYE_AT[0] * SS, BUST_EYE_AT[1] * SS), self.lm["eye_y"] else: w, h = w or BATTLE_SIZE[0], h or BATTLE_SIZE[1] pitch = 10 if pitch is None else pitch pivot = np.zeros(3) s = BATTLE_PX_PER_M * SS (cx, cy), ref_y = (BATTLE_GROUND_AT[0] * SS, BATTLE_GROUND_AT[1] * SS), 0.0 self.camera = dict(view=view, w=w, h=h, pitch=pitch, px_per_m=s / SS, pivot=(pivot * FLIP).tolist(), pivot_px=[cx / SS, (cy - (pivot[1] - ref_y) * s) / SS]) return self.camera, (w, h, pitch, pivot, s, cx, cy, ref_y) def render(self, yaw=35, pitch=None, view="bust", smooth=None, w=None, h=None): """view 'bust': the 96x80 portrait framed on the face. view 'battle': the 240x160 battle scene, whole figure on the ground; scenery stays put while the character turns.""" _, (w, h, pitch, pivot, s, cx, cy, ref_y) = self._frame(view, pitch, w, h) W, H = w * SS, h * SS R = camera_rotation(yaw, pitch) Rw = camera_rotation(0, pitch) def projector(Rm): def project(P): q = ((P - pivot) * FLIP) @ Rm.T return np.stack([cx + q[:, 0] * s, cy - (q[:, 1] + pivot[1] - ref_y) * s, q[:, 2]], -1) return project project = projector(R) project_w = projector(Rw) keep = [k for k, p in enumerate(self.prims) if self.roles[k] != "skip" and len(p["tri"]) and (view != "bust" or p.get("world") or p["pos"][np.unique(p["tri"])][:, 1].max() > self.chin_y - 0.45)] prims = [dict(self.prims[k], _screen=project_w(self.prims[k]["pos"])) if self.prims[k].get("world") else self.prims[k] for k in keep] t = np.clip(((pts - A) @ ab) / (ab @ ab), 0, 1) d = np.linalg.norm(pts - (A + t[:, None] * ab), axis=1) caps.append(dict(a=(A * FLIP).tolist(), b=(B * FLIP).tolist(), r=float(np.percentile(d, 70) + 0.012), bones=[a, b])) cloth = {} for p in portrait.prims: if p["material"] in CLOTH and "grid" in p: trims, band, collide = CLOTH[p["material"]] cloth[p["material"]] = dict(u=int(p["grid"][0]), v=int(p["grid"][1]), trims=list(trims), band=band, collide=list(collide) if collide else None, closed=bool(p.get("closed")), edges="hem" if p["material"] in CLOTH_HEM_ONLY else "all") curve = None if getattr(portrait, "mouth_curve", None) is not None: face = [p for p, r in zip(portrait.prims, portrait.roles) if r == "face"] allp = np.concatenate([p["pos"] for p in face]) alln = np.concatenate([p["nrm"] for p in face]) from scipy.spatial import cKDTree _, i = cKDTree(allp).query(portrait.mouth_curve) curve = ((portrait.mouth_curve + alln[i] * 0.0015) * FLIP).tolist() marks = None if getattr(portrait, "marks", None): m = next(iter(portrait.marks.values())) img = Image.fromarray(np.where(m == 1, 128, 0).astype(np.uint8), "L") # nose mark only; the mouth is a line b = io.BytesIO() img.save(b, "PNG", optimize=True) import base64 marks = base64.b64encode(b.getvalue()).decode() # painted renderer: a material kind and one base colour per role; the shader builds the ramp pc = dict(signature="#7d1e2c", doublet="#2a2d3d", heraldry="#dfe2e8", leather="#5f3e2b", boot="#4a3326", glove="#5f3e2b", steel="#a6adbb", gold="#b08b3f", hair=hexp("C"), trim="#b08b3f") pc.update(getattr(portrait, "paint", None) or {}) 243:const ROLE_ID = { face: 1, body: 2, hair: 3, line: 4, iris: 5, white: 6, highlight: 7, brow: 8, mouth: 9, cloth: 10, hair_b: 11 };exec_commandsource ~/Projects/lowmarch-bench/kit/env-c.sh && rg -n 'uFaceTex|uSkinTone|face.*tex|mouth_curve' review/vroid-02/index.html tools/export_glb.py | head -90 && sed -n '420,470p' review/vroid-02/index.html
command
source ~/Projects/lowmarch-bench/kit/env-c.sh && rg -n 'uFaceTex|uSkinTone|face.*tex|mouth_curve' review/vroid-02/index.html tools/export_glb.py | head -90 && sed -n '420,470p' review/vroid-02/index.html
result, 66 lines
Script completed Wall time 0.5 seconds Output: tools/export_glb.py:227: if getattr(portrait, "mouth_curve", None) is not None: tools/export_glb.py:232: _, i = cKDTree(allp).query(portrait.mouth_curve) tools/export_glb.py:233: curve = ((portrait.mouth_curve + alln[i] * 0.0015) * FLIP).tolist() tools/export_glb.py:269: mouth_curve=curve, mouth_bone="J_Bip_C_Head", ink=dict(o=hexp("o"), skin=hexp("1"), hair=hexp("A")), review/vroid-02/index.html:345: uniform int uFaceTex; uniform int uDecal; uniform vec3 uMotif; uniform vec3 uBand; uniform vec3 uSkinTone; uniform int uShadeOnly; review/vroid-02/index.html:444: if (uFaceTex == 1) col *= clamp(tex.rgb / uSkinRef, 0.55, 1.05); review/vroid-02/index.html:445: if (uSkinRamp == 0) col *= uSkinTone; // older builds: one tint over the light skin review/vroid-02/index.html:817: uGrain: { value: 0.05 }, uFaceTex: { value: 0 }, uDecal: { value: decal ? 1 : 0 }, uBand: { value: null }, review/vroid-02/index.html:818: uSkinTone: { value: new THREE.Vector3(1, 1, 1) }, uShadeOnly: { value: 0 }, review/vroid-02/index.html:831: const c = hex(P.base); u.uSkinTone.value.set(c.r / 0.973, c.g / 0.882, c.b / 0.835); review/vroid-02/index.html:833: if (role === "face" && map) u.uFaceTex.value = 1; if (uAlpha == 2 && (tex.a < 0.5 || dot(tex.rgb, vec3(1.0 / 3.0)) >= 0.42)) discard; if (uPass == 1) { gl_FragColor = uInfo; return; } vec3 n = normalize(vN); if (!gl_FrontFacing) n = -n; vec3 v = normalize(vView); float lit = dot(n, uKey) * 0.5 + 0.5; if (uShadeOnly == 1) lit = min(lit, 0.37); // shadow cards only ever darken skin, to a soft shade else if (uCastOn == 1 && uKind == 1 && int(uInfo.x * 255.0 + 0.5) == 2 && castShadow() > 0.5) lit = min(lit, 0.37); // body skin under the jaw's or the hair's shadow float g1 = vnoise(vObj * 40.0), g2 = vnoise(vObj * 150.0); vec3 col; if (uKind == 0 || uKind == 5 || uKind == 6) { // cloth, leather, ground vec3 hb = rgb2hsv(uBase); bool cool = hb.x > 0.42 && hb.x < 0.86; float sh = uKind == 5 ? 0.93 : (cool ? 0.70 : 0.96); float li = cool ? 0.52 : 0.13; vec3 c0 = tone(uBase, sh, 0.09, 1.12, 0.40), c1 = tone(uBase, sh, 0.05, 1.08, 0.64); vec3 c3 = tone(uBase, li, 0.03, 0.80, 1.20); float l = lit + (g1 - 0.5) * uGrain - (uKind == 6 ? 0.22 : 0.0); // ground: a flat top sits at the base colour col = mix(c0, c1, st(l, 0.30)); col = mix(col, uBase, st(l, 0.50)); col = mix(col, c3, st(l, 0.91)); if (uKind == 5) col *= 0.965 + 0.07 * vnoise(vObj * 22.0); // mottled leather } else if (uKind == 1) { // skin: pale, nearly unshaded from the front vec3 sL = vec3(0.973, 0.882, 0.835), sS = vec3(0.776, 0.659, 0.608), sC = vec3(0.451, 0.322, 0.310); if (uSkinRamp == 1) { sL = uSkinL; sS = uSkinS; sC = uSkinC; } // the character's tone, designed per tone col = mix(sC, sS, st(lit, 0.20)); col = mix(col, sL, st(lit, 0.38)); if (uFaceTex == 1) col *= clamp(tex.rgb / uSkinRef, 0.55, 1.05); if (uSkinRamp == 0) col *= uSkinTone; // older builds: one tint over the light skin } else if (uKind == 2) { // hair: four even bands, hard strand highlights float strand = dot(tex.rgb, vec3(1.0 / 3.0)); vec3 c0 = tone(uBase, 0.72, 0.07, 1.10, 0.45), c1 = tone(uBase, 0.72, 0.035, 1.05, 0.68); vec3 c2 = tone(uBase, 0.56, 0.02, 0.92, 1.10), c3 = tone(uBase, 0.56, 0.03, 0.55, 1.42); float l = lit + (strand - 0.6) * 0.12; col = mix(c0, c1, st(l, 0.40)); col = mix(col, uBase, st(l, 0.56)); col = mix(col, c2, st(l, 0.84)); float sp = dot(n, normalize(uKey + v)) + (strand - 0.6) * 0.18; col = mix(col, c3, st(sp, 0.90) * (1.0 - st(sp, 0.985))); } else if (uKind == 3 || uKind == 4) { // steel, gold bool plate = vPlate.x > 0.5; float e = vPlate.y, w = vPlate.z; bool gilt = uKind == 4 || (plate && w > 0.0 && e < w); // an outline plate's gold border col = metal(gilt, gilt && uKind == 3 ? uGold : uBase, n, v, lit, plate ? vPlate.w : -1.0); if (plate && w > 0.0) { // engraved lines: one inside the border, one on its seam float aa = fwidth(e) * 1.2 + 1e-5; float l1 = 1.0 - smoothstep(0.0010, 0.0010 + aa, abs(e - (w + 0.0050))); float l2 = 1.0 - smoothstep(0.0006, 0.0006 + aa, abs(e - w)); col = mix(col, col * 0.42, max(l1, l2 * 0.8)); } } else if (uKind == 7) { // iris float l = dot(tex.rgb, vec3(1.0 / 3.0)); col = l < 0.3 ? mix(uEye[0], uEye[1], l / 0.3) : mix(uEye[1], uEye[2], clamp((l - 0.3) / 0.6, 0.0, 1.0)); } else if (uKind == 8) { col = tex.rgb; } else { col = uFlat; } if (vPlate.x > 0.5 && vPlate.z > 0.0 && uKind != 3 && uKind != 4) { // a cloth outline piece's gold border,exec_commandsource ~/Projects/lowmarch-bench/kit/env-c.sh && rg -n 'MARK_WINDOW|FACE_MARK|MARK_GROW' tools/vroid_portrait.py && sed -n '45,85p' tools/vroid_portrait.py && date -Is
command
source ~/Projects/lowmarch-bench/kit/env-c.sh && rg -n 'MARK_WINDOW|FACE_MARK|MARK_GROW' tools/vroid_portrait.py && sed -n '45,85p' tools/vroid_portrait.py && date -Is
result, 54 lines
Script completed Wall time 0.3 seconds Output: 43:FACE_MARK = 0.70 # face-texture texels darker than this are painted lines (lip line, nose mark) 44:MARK_GROW = 4 # texels of dilation so a 1.5 mm painted line survives the 4x4 vote 47:MARK_WINDOW = dict(u=(0.32, 0.68), v=(0.58, 0.86), nose_below=0.70) 848: win = ((uu > MARK_WINDOW["u"][0]) & (uu < MARK_WINDOW["u"][1]) 849: & (vv > MARK_WINDOW["v"][0]) & (vv < MARK_WINDOW["v"][1])) 850: raw = (t[..., :3].mean(-1) / 255 < FACE_MARK) & (t[..., 3] > 0) & win 851: grown = binary_dilation(raw, iterations=MARK_GROW) & win 853: self.marks[k] = np.where(grown, np.where(vv >= MARK_WINDOW["nose_below"], 2, 1), 0).astype(np.uint8) LIP_DROP = 0.014 # UV distance below the lip line that gets the lower-lip shade # VRoid face textures share one layout: marks only count inside the nose-and-mouth window MARK_WINDOW = dict(u=(0.32, 0.68), v=(0.58, 0.86), nose_below=0.70) # High-resolution pixel rendering (2026-10-08): a 640x360 base screen (scales cleanly to 1080p/4K). BUST_SIZE, BUST_EYE_CHIN, BUST_EYE_AT = (192, 160), 38.0, (92, 60) # portrait: canvas, eye-to-chin px, eye line BATTLE_SIZE, BATTLE_PX_PER_M, BATTLE_GROUND_AT = (640, 360), 90.0, (420, 318) # battle: canvas, scale, feet SUN = np.array([-0.30, 0.85, 0.45]) / np.linalg.norm([-0.30, 0.85, 0.45]) # scenery light (camera space) LID_CORE = 70 # eyeline texels darker than this are the lash line LIGHT = np.array([0.08, 0.06, 1.0]) / np.linalg.norm([0.08, 0.06, 1.0]) SKIN_BANDS = [(0.80, "5"), (0.62, "4"), (0.38, "3"), (-9, "2")] HAIR_BANDS = [(0.86, "E"), (0.66, "D"), (0.42, "C"), (-9, "B")] CLOTH_BANDS = [(0.85, "P"), (0.6, "M"), (0.35, "L"), (-9, "K")] # costume materials: role -> bands (metal has a narrow bright streak and hard darks) MATERIALS = {"coat": CLOTH_BANDS, "signature": CLOTH_BANDS, # the character's one colour (tabard, mantle, shield) "doublet": [(0.85, "T"), (0.6, "S"), (0.35, "R"), (-9, "Q")], "heraldry": [(0.85, "O"), (0.6, "N"), (0.35, "J"), (-9, "F")], "cape": [(0.85, "X"), (0.6, "W"), (0.35, "V"), (-9, "U")], "metal": [(0.975, "9"), (0.86, "8"), (0.55, "7"), (-9, "6")], "gold": [(0.80, "I"), (0.45, "H"), (-9, "G")], "leather": [(0.75, "x"), (0.4, "v"), (-9, "u")], "boot": [(0.80, "x"), (0.45, "v"), (-9, "u")], "glove": [(0.75, "x"), (0.4, "v"), (-9, "u")], "steel": [(0.90, "9"), (0.70, "8"), (0.40, "7"), (-9, "6")], "grass": [(0.90, "d"), (0.70, "c"), (0.40, "b"), (-9, "a")], "dirt": [(0.70, "i"), (0.35, "f"), (-9, "e")], "stone": [(0.80, "m"), (0.45, "l"), (-9, "k")]} WORLD_ROLES = ("grass", "dirt", "stone") DARKER = {c: tbl[min(i + 1, len(tbl) - 1)][1] for tbl in MATERIALS.values() for i, (_, c) in enumerate(tbl)} FLIP = np.array([-1.0, 1.0, -1.0]) # VRoid faces -z; we want the face toward +z (the viewer) def role_of(material): for frag, role in ROLES: if frag in material: return role return "cloth" def bands(v, table): 2026-10-30T12:59:37+08:00exec_commandsource ~/Projects/lowmarch-bench/kit/env-c.sh && rg -n 'function rawTex|rawTex =' review/vroid-02/index.html && sed -n '238,260p' review/vroid-02/index.html && date -Is
command
source ~/Projects/lowmarch-bench/kit/env-c.sh && rg -n 'function rawTex|rawTex =' review/vroid-02/index.html && sed -n '238,260p' review/vroid-02/index.html && date -Is
result, 29 lines
Script completed Wall time 0.4 seconds Output: 294:const rawTex = t => { if (!t) return null; const c = t.clone(); c.colorSpace = THREE.NoColorSpace; c.needsUpdate = true; return c; }; sword: "Sword", weapon: "Weapon", helmet: "Helmet", hood: "Hood", padding: "Padded coat", mail: "Mail", terrain: "Ground" }; const COSTUME = new Set(["tunic", "tails", "belt", "trousers", "boots", "gloves", "collar", "pauldron", "cape", "trim", "doublet", "plate", "tabard", "mantle", "shield", "dress", "helmet", "hood", "padding", "mail"]); // role ids for the info pass (features 4-9 get no inner lines; hair 3 and 11 shade the forehead) const ROLE_ID = { face: 1, body: 2, hair: 3, line: 4, iris: 5, white: 6, highlight: 7, brow: 8, mouth: 9, cloth: 10, hair_b: 11 }; let nextRole = 12; const roleId = r => (ROLE_ID[r] ??= nextRole++); const VIEW_YAW = { duel: 0, battle: 60, bust: 30, lineup: 20, compare: 0 }; const state = { view: "duel", who: CAM.characters[0].name, yaw: 0, mode: "painted", skin: "", toon: true, xray: false, hidden: new Set(), cloth: true, wind: false, playing: false, stepped: false, clip: "clash", pose: "out", compare: [], motion: "still", physics: true }; const charDef = name => CAM.characters.find(c => c.name === name); // a workshop page (camera.json "page"): its own title and notes, and no duel const PAGE = CAM.page || null; const NO_DUEL = PAGE?.duel === false; if (PAGE) { document.title = `${PAGE.title} · Lowmarch`; document.querySelector(".brand .eyebrow").textContent = PAGE.eyebrow || "Lowmarch"; document.querySelector(".brand h1").textContent = PAGE.title; if (PAGE.notes) document.querySelector("#panel section ul").innerHTML = PAGE.notes; } // the armory: bodies compared side by side (the Compare view) in three poses, instead of clips and a lineup 2026-10-30T12:59:42+08:00view_image~/Projects/lowmarch-bench/work/c/shot_r2/joy/painted_arm_m_youth.png
input
const im=await tools.view_image({path:"~/Projects/lowmarch-bench/work/c/shot_r2/joy/painted_arm_m_youth.png",detail:"original"});image(im.image_url);result, 4 lines
Script completed Wall time 0.1 seconds Output:
write_stdinpoll session 25485
input
const r=await tools.write_stdin({session_id:25485,chars:"",yield_time_ms:50000,max_output_tokens:3000});text(JSON.stringify(r));result, 4 lines
Script completed Wall time 10.1 seconds Output: {"chunk_id":"cde04a","wall_time_seconds":10.099555241,"exit_code":143,"original_token_count":0,"output":""}exec_commandsource ~/Projects/lowmarch-bench/kit/env-c.sh && bash "$WORK/shoot_resume.sh" "$LOWMARCH_REPO/review/vroid-02/index.html" r2 && "$KIT/sheets.sh" r2 'Round 2: softer brows and eyelid and mouth revisions' && date -Is
command
source ~/Projects/lowmarch-bench/kit/env-c.sh && bash "$WORK/shoot_resume.sh" "$LOWMARCH_REPO/review/vroid-02/index.html" r2 && "$KIT/sheets.sh" r2 'Round 2: softer brows and eyelid and mouth revisions' && date -Is
result, 4 lines
Script completed Wall time 1.2 seconds Output: {"chunk_id":"ca6800","wall_time_seconds":1.000316822,"session_id":73102,"original_token_count":0,"output":""}
agent
+15:44The revised joy now closes the youth’s eyes cleanly at both angles; the first version left a strip of iris visible. I’m finishing the second sheet to check whether the same approach helps the wink.
write_stdinpoll session 73102
input
const r=await tools.write_stdin({session_id:73102,chars:"",yield_time_ms:50000,max_output_tokens:3000});text(JSON.stringify(r));result, 4 lines
Script running with cell ID 49 Wall time 31.0 seconds Output:
waitcell 49
input
{ "cell_id": "49", "yield_time_ms": 20000 }result, 4 lines
Script completed Wall time 13.1 seconds Output: {"chunk_id":"021856","wall_time_seconds":50.000916716,"session_id":73102,"original_token_count":103,"output":"arm_f_slender ~/Projects/lowmarch-bench/work/c/shot_r2/lip_U/painted_arm_f_slender.png 13s\narm_m_youth ~/Projects/lowmarch-bench/work/c/shot_r2/lip_U/painted_arm_m_youth.png 10s\narm_f_slender ~/Projects/lowmarch-bench/work/c/shot_r2/neutral/painted_arm_f_slender.png 11s\narm_m_youth ~/Projects/lowmarch-bench/work/c/shot_r2/neutral/painted_arm_m_youth.png 9s\n"}write_stdinpoll session 73102
input
const r=await tools.write_stdin({session_id:73102,chars:"",yield_time_ms:50000,max_output_tokens:3000});text(JSON.stringify(r));result, 4 lines
Script running with cell ID 50 Wall time 31.0 seconds Output:
waitcell 50
input
{ "cell_id": "50", "yield_time_ms": 20000 }result, 4 lines
Script completed Wall time 16.3 seconds Output: {"chunk_id":"829fc8","wall_time_seconds":50.001212875,"session_id":73102,"original_token_count":101,"output":"arm_f_slender ~/Projects/lowmarch-bench/work/c/shot_r2/sad/painted_arm_f_slender.png 11s\narm_m_youth ~/Projects/lowmarch-bench/work/c/shot_r2/sad/painted_arm_m_youth.png 9s\narm_f_slender ~/Projects/lowmarch-bench/work/c/shot_r2/shout/painted_arm_f_slender.png 10s\narm_m_youth ~/Projects/lowmarch-bench/work/c/shot_r2/shout/painted_arm_m_youth.png 13s\n"}
agent
+17:29The neutral and sad variants have rendered with the softer overlay. The remaining captures will complete the comparison before I settle the final recipe values.
write_stdinpoll session 73102
input
const r=await tools.write_stdin({session_id:73102,chars:"",yield_time_ms:50000,max_output_tokens:3000});text(JSON.stringify(r));result, 4 lines
Script running with cell ID 51 Wall time 31.0 seconds Output:
waitcell 51
input
{ "cell_id": "51", "yield_time_ms": 20000 }result, 4 lines
Script completed Wall time 17.0 seconds Output: {"chunk_id":"ad6344","wall_time_seconds":50.001210595,"session_id":73102,"original_token_count":102,"output":"arm_f_slender ~/Projects/lowmarch-bench/work/c/shot_r2/smile/painted_arm_f_slender.png 15s\narm_m_youth ~/Projects/lowmarch-bench/work/c/shot_r2/smile/painted_arm_m_youth.png 12s\narm_f_slender ~/Projects/lowmarch-bench/work/c/shot_r2/smug/painted_arm_f_slender.png 13s\narm_m_youth ~/Projects/lowmarch-bench/work/c/shot_r2/smug/painted_arm_m_youth.png 11s\n"}write_stdinpoll session 73102
input
const r=await tools.write_stdin({session_id:73102,chars:"",yield_time_ms:50000,max_output_tokens:3000});text(JSON.stringify(r));result, 4 lines
Script running with cell ID 52 Wall time 31.0 seconds Output:






