Track B: Opus 5.5 with a GPT-6.1-Terra reviewer

agent (cont.)

+0:37
  • Bashsource ~/Projects/lowmarch-bench/kit/env-b.sh && cd $LOWMARCH_REPO && grep -n 'PAINT_VS\|PAINT_COMP\|PAINT_FS\|uKind\|const PAL\|hexp(' review/vroid-02/index.html | head -50; sed -n 180,275p tools/export_glb.py

    command

    source ~/Projects/lowmarch-bench/kit/env-b.sh && cd $LOWMARCH_REPO && grep -n 'PAINT_VS\|PAINT_COMP\|PAINT_FS\|uKind\|const PAL\|hexp(' review/vroid-02/index.html | head -50; sed -n 180,275p tools/export_glb.py

    result, 124 lines

    316:const PAINT_VS = `${SKIN_HEAD}
    341:const PAINT_FS = `
    342:  uniform int uKind; uniform vec3 uBase; uniform vec3 uKey; uniform sampler2D uMap; uniform int uAlpha;
    426:    else if (uCastOn == 1 && uKind == 1 && int(uInfo.x * 255.0 + 0.5) == 2 && castShadow() > 0.5)
    430:    if (uKind == 0 || uKind == 5 || uKind == 6) {                    // cloth, leather, ground
    433:      float sh = uKind == 5 ? 0.93 : (cool ? 0.70 : 0.96);
    437:      float l = lit + (g1 - 0.5) * uGrain - (uKind == 6 ? 0.22 : 0.0);  // ground: a flat top sits at the base colour
    439:      if (uKind == 5) col *= 0.965 + 0.07 * vnoise(vObj * 22.0);       // mottled leather
    440:    } else if (uKind == 1) {                                           // skin: pale, nearly unshaded from the front
    446:    } else if (uKind == 2) {                                           // hair: four even bands, hard strand highlights
    454:    } else if (uKind == 3 || uKind == 4) {                             // steel, gold
    457:      bool gilt = uKind == 4 || (plate && w > 0.0 && e < w);            // an outline plate's gold border
    458:      col = metal(gilt, gilt && uKind == 3 ? uGold : uBase, n, v, lit, plate ? vPlate.w : -1.0);
    465:    } else if (uKind == 7) {                                           // iris
    468:    } else if (uKind == 8) { col = tex.rgb; }
    470:    if (vPlate.x > 0.5 && vPlate.z > 0.0 && uKind != 3 && uKind != 4) {   // a cloth outline piece's gold border,
    490:    if (uKind <= 6) {
    492:      col *= uKind == 1 && uSkinRamp == 1 ? mix(vec3(1.0), grade, 0.3) : grade;   // a designed skin ramp takes less of it
    496:      if (uKind != 1) col *= 1.0 + (g2 - 0.5) * 0.06;
    500:const PAINT_COMP = `
    568:const paint = compPass(PAINT_COMP, { tColor: { value: null }, tInfo: { value: null }, tDepth: { value: null }, uRes: { value: new THREE.Vector2() },
    804:  const u = { uKind: { value: 9 }, uBase: { value: new THREE.Color(0.8, 0.8, 0.8) }, uKey: { value: KEY.clone() },
    816:  if (P) { u.uKind.value = KIND[P.kind] ?? 0; if (P.base) u.uBase.value = hex(P.base); if (P.grain != null) u.uGrain.value = P.grain; }
    817:  else if (Rl.bands) { u.uKind.value = Rl.world ? 6 : 0; u.uBase.value = hex(Rl.bands[Math.min(1, Rl.bands.length - 1)][1]); }
    828:  if (role === "iris") { u.uKind.value = 7; u.uAlpha.value = 1; }
    829:  else if (role === "white" || role === "highlight") { u.uKind.value = map ? 8 : 9; if (map) u.uAlpha.value = 1; u.uFlat.value = hex(Rl.color || "#ffffff"); }
    830:  else if (!P && Rl.mode === "flat") { u.uKind.value = 9; u.uFlat.value = hex(Rl.color); if (map) u.uAlpha.value = role === "line" ? 2 : 1; }
    832:  const m = new THREE.ShaderMaterial({ uniforms: u, vertexShader: PAINT_VS, fragmentShader: PAINT_FS, side: THREE.DoubleSide,
    1323:    if (!u || !u.uSkinRamp || u.uKind.value !== 1) continue;
    CLOTH_HEM_ONLY = {"OUTFIT_skirt"}            # border band on the hem row only (its waist has a gold trim)
    
    
    def scene_info(portrait, palette):
        """Everything the browser's pixel renderer and cloth solver need besides the meshes: palette
        bands per role, the lights, body colliders, cloth grids and the mouth curve (model space,
        turned to face +z like the GLB)."""
        import vroid_portrait as vp
        from vrm import bone_weight
        hexp = lambda c: palette[c]
        bands = lambda tbl: [[thr if thr > -5 else -9, hexp(c)] for thr, c in tbl]
        roles = {"face": dict(mode="bands", bands=bands(vp.SKIN_BANDS)),
                 "body": dict(mode="bands", bands=bands(vp.SKIN_BANDS), cap=hexp("4")),
                 "shadow": dict(mode="flat", color=hexp("3")),
                 "hair": dict(mode="bands", bands=bands(vp.HAIR_BANDS)),
                 "cloth": dict(mode="bands", bands=bands(vp.CLOTH_BANDS)),
                 "line": dict(mode="flat", color=hexp("o")), "brow": dict(mode="flat", color=hexp("A")),
                 "mouth": dict(mode="flat", color=hexp("1")), "white": dict(mode="flat", color=hexp("w")),
                 "highlight": dict(mode="flat", color=hexp("w")),
                 "iris": dict(mode="iris", colors=[hexp("r"), hexp("s"), hexp("t")], cuts=[0.25, 0.5])}
        for r, tbl in vp.MATERIALS.items():
            roles[r] = dict(mode="bands", bands=bands(tbl), world=r in vp.WORLD_ROLES)
        names = portrait.v.nodes_by_name()
        W = portrait.v.node_world(portrait.pose_now)
        body = [p for p, r in zip(portrait.prims, portrait.roles) if r == "body"][0]
        caps = []
        for a, b in CAPSULES:
            if a not in names or b not in names:
                continue
            A, B = W[names[a]][:3, 3], W[names[b]][:3, 3]
            wv = bone_weight(body, (a,))
            pts = body["pos"][wv > 0.5]
            if len(pts) < 8:
                continue
            ab = B - A
            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 {})
        skin = dict(kind="skin", base=pc.get("skin") or "#f8e1d5")                       # light skin unless a tone is set
        skin["ramp"] = skin_ramp(skin["base"])                                              # its lit, shade and deep shade
        paint = {"face": dict(skin), "body": dict(skin), "shadow": dict(skin, shade=True),   # shadow cards: skin in shade
                 "hair": dict(kind="hair", base=pc["hair"]),
                 "coat": dict(kind="cloth", base=pc["signature"]), "cape": dict(kind="cloth", base=pc["signature"]),
                 "signature": dict(kind="cloth", base=pc["signature"]), "doublet": dict(kind="cloth", base=pc["doublet"]),
                 "cloth": dict(kind="cloth", base=pc["doublet"]), "heraldry": dict(kind="cloth", base=pc["heraldry"]),
                 "leather": dict(kind="leather", base=pc["leather"]), "boot": dict(kind="leather", base=pc["boot"]),
                 "glove": dict(kind="leather", base=pc["glove"]), "metal": dict(kind="steel", base=pc["steel"]),
                 "steel": dict(kind="steel", base=pc["steel"]), "gold": dict(kind="gold", base=pc["gold"]),
                 "grass": dict(kind="world", base="#5a7a3a"), "dirt": dict(kind="world", base="#6a4a32"),
                 "stone": dict(kind="world", base="#7c7a86"),
                 "motif": dict(kind="cloth", base=pc.get("motif", "#3a44a0"))}       # decal paint on steel (tools/plates.py)
        for role, val in pc.items():                             # extra roles a cast entry names (cloth unless it says)
            if role not in paint and isinstance(val, str) and val.startswith("#"):
                paint[role] = dict(kind="cloth", base=val)
            elif role not in paint and isinstance(val, dict) and "base" in val:
                paint[role] = dict(kind=val.get("kind", "cloth"), base=val["base"])
        for role, g in (pc.get("grain") or {}).items():          # optional per-role brush grain (big flat cloth mottles)
            if role in paint:
                paint[role]["grain"] = g
        return dict(roles=roles, light=vp.LIGHT.tolist(), sun=vp.SUN.tolist(), capsules=caps, cloth=cloth, face_marks=marks,
                    paint=paint,
                    mouth_curve=curve, mouth_bone="J_Bip_C_Head", ink=dict(o=hexp("o"), skin=hexp("1"), hair=hexp("A")),
                    skin=[hexp(c) for c in "12345"], depth_gap=0.012)
    
    
    # ---- skinned export: one rigged character + animation clips --------------------------------------------------------
    F4 = np.diag([-1.0, 1.0, -1.0, 1.0])
  • Bashsource ~/Projects/lowmarch-bench/kit/env-b.sh && cd $LOWMARCH_REPO && sed -n 316,600p review/vroid-02/index.html

    command

    source ~/Projects/lowmarch-bench/kit/env-b.sh && cd $LOWMARCH_REPO && sed -n 316,600p review/vroid-02/index.html

    result, 285 lines

    const PAINT_VS = `${SKIN_HEAD}
      attribute float edge; attribute vec4 _plate;
      varying vec3 vN; varying vec2 vUv; varying vec3 vView; varying vec3 vObj; varying float vEdge; varying vec4 vPlate;
      void main() {
        ${SKIN_BODY}
        vN = normalize(normalMatrix * objectNormal); vUv = uv; vObj = position; vEdge = edge; vPlate = _plate;
        vec4 mv = modelViewMatrix * vec4(transformed, 1.0); vView = -mv.xyz;
        gl_Position = projectionMatrix * mv;
      }`;
    const HSV = `
      vec3 rgb2hsv(vec3 c) {
        vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
        vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
        vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
        float d = q.x - min(q.w, q.y);
        return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + 1e-10)), d / (q.x + 1e-10), q.x);
      }
      vec3 hsv2rgb(vec3 c) {
        vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
        vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
        return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
      }`;
    // painted renderer, after the Unicorn Overlord study: tight terminators, hue-shifted ramps built from
    // one base colour per material, hard reflection bands on steel, strand highlights on hair, a stage
    // grade and a back rim
    const PAINT_FS = `
      uniform int uKind; uniform vec3 uBase; uniform vec3 uKey; uniform sampler2D uMap; uniform int uAlpha;
      uniform int uPass; uniform vec4 uInfo; uniform vec3 uEye[3]; uniform vec3 uFlat; uniform vec3 uSkinRef;
      uniform vec3 uGold; uniform vec3 uAmbient; uniform vec3 uKeyCol; uniform vec3 uRimCol; uniform float uGrain;
      uniform int uFaceTex; uniform int uDecal; uniform vec3 uMotif; uniform vec3 uBand; uniform vec3 uSkinTone; uniform int uShadeOnly;
      uniform int uSkinRamp; uniform vec3 uSkinL; uniform vec3 uSkinS; uniform vec3 uSkinC;
      uniform sampler2D tCastInfo; uniform sampler2D tCastDepth; uniform vec2 uCastRes; uniform int uCastOn;
      uniform float uCastNear; uniform float uCastFar; uniform float uCastPpm;
      // Cast shadows on skin, in screen space (the "depth offset" shadows of anime toon shaders): walk from this pixel
      // toward the key light across the info pass already drawn; if the face (the jaw) or hair stands in front of that
      // ray, this pixel is in its shadow. The shape is the caster's own outline as the camera sees it, at any angle.
      float castShadow() {
        vec2 uv = gl_FragCoord.xy / uCastRes, px = 1.0 / uCastRes;
        float z0 = uCastNear + texture2D(tCastDepth, uv).x * (uCastFar - uCastNear);
        float sxy = length(uKey.xy);
        if (sxy < 0.05) return 0.0;
        vec2 dir = uKey.xy / sxy;
        float lz = uKey.z / sxy;                                    // the ray's rise toward the camera per metre across
        for (int s = 1; s <= 14; s++) {
          float dm = float(s) * 0.003;                              // 3 mm steps across the screen, up to 4.2 cm
          vec2 q = uv + dir * dm * uCastPpm * px;
          vec4 ni = texture2D(tCastInfo, q);
          if (ni.a < 0.5) continue;
          int r = int(ni.r * 255.0 + 0.5);
          if (r != 1 && r != 3 && r != 11) continue;                // casters: the face (jaw, chin) and hair
          float zq = uCastNear + texture2D(tCastDepth, q).x * (uCastFar - uCastNear);
          float zr = z0 - lz * dm;
          if (zq < zr - 0.004 && zq > zr - 0.20) return 1.0;
        }
        return 0.0;
      }
      varying vec3 vN; varying vec2 vUv; varying vec3 vView; varying vec3 vObj; varying float vEdge; varying vec4 vPlate;
      ${HSV}
      float hash(vec3 p) { p = fract(p * 0.3183099 + 0.1); p *= 17.0; return fract(p.x * p.y * p.z * (p.x + p.y + p.z)); }
      float vnoise(vec3 x) {
        vec3 i = floor(x), f = fract(x); f = f * f * (3.0 - 2.0 * f);
        return mix(mix(mix(hash(i), hash(i + vec3(1,0,0)), f.x), mix(hash(i + vec3(0,1,0)), hash(i + vec3(1,1,0)), f.x), f.y),
                   mix(mix(hash(i + vec3(0,0,1)), hash(i + vec3(1,0,1)), f.x), mix(hash(i + vec3(0,1,1)), hash(i + vec3(1,1,1)), f.x), f.y), f.z);
      }
      float toward(float h, float target, float amt) { float d = target - h; d -= floor(d + 0.5); return fract(h + clamp(d, -amt, amt)); }
      vec3 tone(vec3 base, float hue, float amt, float sMul, float vMul) {
        vec3 h = rgb2hsv(base);
        return hsv2rgb(vec3(toward(h.x, hue, amt), clamp(h.y * sMul, 0.0, 1.0), clamp(h.z * vMul, 0.0, 1.0)));
      }
      float st(float x, float t) { return smoothstep(t - 0.03, t + 0.03, x); }
      // Steel and gold. Hard reflection bands (dark below the horizon, a dark core under a white streak)
      // read well where the surface turns fast: rims, tubes, lames. On a broad plate the reflection
      // barely changes, so a band there fills the whole plate (the blotches): bands fade by how sharply
      // the surface curves (normal change per metre on screen), and broad plates get a soft tone that
      // lightens up each outline plate (hgt: height in the plate 0..1, or -1 without plate data).
      vec3 metal(bool gold, vec3 base, vec3 n, vec3 v, float lit, float hgt) {
        vec3 r = reflect(-v, n);
        float ry = r.y + (vnoise(vObj * vec3(3.0, 14.0, 3.0)) - 0.5) * 0.14;   // jitter the bands along their length, not into blobs
        float curv = length(fwidth(n)) / max(length(fwidth(vView)), 1e-5);
        float sharp = smoothstep(5.0, 14.0, curv);
        // a shaped plate's domes (over the bust, a crowned panel) turn the bands into closed rings: plates
        // keep only a little of them and take a crisp highlight toward the light instead
        if (hgt >= 0.0) sharp *= 0.25; else sharp = max(sharp, 0.3);
        vec3 s0, s1, s2, s3;
        if (!gold) { s0 = tone(base, 0.68, 0.10, 2.4, 0.32); s1 = tone(base, 0.68, 0.06, 1.7, 0.76);
                     s2 = tone(base, 0.12, 0.0, 0.8, 0.88); s3 = vec3(0.97, 0.96, 0.92); }
        else { s0 = vec3(0.30, 0.20, 0.30); s1 = tone(base, 0.20, 0.03, 1.0, 0.72); s2 = base; s3 = tone(base, 0.16, 0.03, 0.5, 1.5); }
        vec3 hard = mix(s0, s1, st(ry, -0.42));                          // facing down: dark
        hard = mix(hard, s2, st(ry, -0.08));                             // facing us: the plate's own grey
        hard = mix(hard, s0, st(ry, 0.36));                              // dark core under the streak
        hard = mix(hard, s3, st(ry, 0.47));                              // the white streak
        hard = mix(hard, s2 * 1.06, st(ry, 0.70));
        float k = smoothstep(-0.55, 0.30, r.y);                          // broad: darker toward the ground (no jitter:
        if (hgt >= 0.0) k = clamp(k * 0.45 + hgt * 0.80 - 0.18, 0.0, 1.0);   // on a flat plate it streaks)
        else k = clamp(k * 0.6 + n.y * 0.35 + 0.05, 0.0, 1.0);           // without plate data: lighter facing up
        vec3 soft = mix(s1 * 0.9, s2, k);
        float hl = dot(n, normalize(uKey + v));                          // the key's highlight, a hard-edged shape
        if (hgt >= 0.0) soft = mix(soft, mix(s2, s3, 0.6), st(hl, 0.955) * smoothstep(0.45, 0.8, hgt));   // the upper part only
        vec3 col = mix(soft, hard, sharp);
        return mix(col * 0.72 + s0 * 0.28, col, st(lit, 0.30));
      }
      void main() {
        vec4 tex = texture2D(uMap, vUv);
        if (uAlpha == 1 && tex.a < 0.5) discard;
        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,
          float e = vPlate.y, w = vPlate.z, aa = fwidth(e) * 1.2 + 1e-5;       // and a fine gold line inside it
          float band = 1.0 - smoothstep(w - aa, w, e);
          float l1 = 1.0 - smoothstep(0.0006, 0.0006 + aa, abs(e - (w + 0.0040)));
          col = mix(col, metal(true, uGold, n, v, lit, -1.0), max(band, l1 * 0.9));
        }
        if (uDecal == 1) {                                                 // a design in the piece's own coordinates:
          vec3 dm = tex.rgb;                                               // R paint, G groove, B gold inlay
          float pm = smoothstep(0.3, 0.7, dm.r), gm = smoothstep(0.3, 0.7, dm.g), au = smoothstep(0.3, 0.7, dm.b);
          if (au > 0.0) col = mix(col, metal(true, uGold, n, v, lit, -1.0), au);
          if (pm > 0.0) {
            vec3 pc = mix(tone(uMotif, 0.70, 0.05, 1.10, 0.62), uMotif, st(lit, 0.42));
            col = mix(col, mix(pc, tone(uMotif, 0.56, 0.03, 0.8, 1.25), st(lit, 0.92)), pm);
          }
          if (gm > 0.0) col = mix(col, col * 0.30, gm);
        }
        if (vEdge > 0.5) {                                                 // the cloth's border band
          vec3 gd = tone(uBand, 0.20, 0.03, 1.0, 0.72);
          col = mix(gd, uBand, st(lit, 0.45)); col = mix(col, tone(uBand, 0.16, 0.03, 0.5, 1.45), st(lit, 0.85));
        }
        if (uKind <= 6) {
          vec3 grade = mix(uAmbient, uKeyCol, st(lit, 0.55));
          col *= uKind == 1 && uSkinRamp == 1 ? mix(vec3(1.0), grade, 0.3) : grade;   // a designed skin ramp takes less of it
          float fr = pow(1.0 - max(dot(n, v), 0.0), 4.0);
          float back = clamp(dot(n, normalize(vec3(0.55, 0.45, -0.35))), 0.0, 1.0);
          col += uRimCol * fr * smoothstep(0.1, 0.5, back);
          if (uKind != 1) col *= 1.0 + (g2 - 0.5) * 0.06;
        }
        gl_FragColor = vec4(clamp(col, 0.0, 1.0), 1.0);
      }`;
    const PAINT_COMP = `
      uniform sampler2D tColor; uniform sampler2D tInfo; uniform sampler2D tDepth; uniform vec2 uRes;
      uniform float uNear; uniform float uFar; uniform float uGap; uniform float uSil; uniform float uInner;
      ${HSV}
      float z(vec2 p) { return uNear + texture2D(tDepth, p).x * (uFar - uNear); }
      int rid(vec4 i) { return int(i.r * 255.0 + 0.5); }
      float pid(vec4 i) { return floor(i.g * 255.0 + 0.5) + floor(i.b * 255.0 + 0.5) * 256.0; }
      vec3 ink(vec3 c) { vec3 h = rgb2hsv(c); return hsv2rgb(vec3(h.x, clamp(h.y, 0.20, 0.45), 0.19)); }
      void main() {
        vec2 uv = gl_FragCoord.xy / uRes, px = 1.0 / uRes;
        vec4 inf = texture2D(tInfo, uv);
        if (inf.a < 0.5) {                                          // outer line: grow the silhouette outward
          vec4 best = vec4(0.0); vec2 bq = uv;
          for (int k = 0; k < 12; k++) {
            float a = float(k) * 0.5236;
            for (int s = 1; s <= 2; s++) {
              vec2 q = uv + vec2(cos(a), sin(a)) * uSil * float(s) * 0.5 * px;
              vec4 ni = texture2D(tInfo, q);
              if (ni.a > 0.5) { best = ni; bq = q; }
            }
          }
          if (best.a > 0.5) {
            int r = rid(best);
            if (r >= 4 && r <= 7) { gl_FragColor = vec4(0.0); return; }
            gl_FragColor = vec4(ink(texture2D(tColor, bq).rgb), 1.0); return;
          }
          gl_FragColor = vec4(0.0); return;
        }
        vec3 col = texture2D(tColor, uv).rgb; int r0 = rid(inf); float p0 = pid(inf); float z0 = z(uv);
        bool feature = r0 >= 4 && r0 <= 9;
        if (!feature) {
          for (int k = 0; k < 4; k++) {
            vec2 d = k == 0 ? vec2(1.0, 0.0) : (k == 1 ? vec2(-1.0, 0.0) : (k == 2 ? vec2(0.0, -1.0) : vec2(0.0, 1.0)));
            vec2 q = uv + d * px * uInner;
            vec4 ni = texture2D(tInfo, q);
            if (z(q) > z0 + uGap && pid(ni) != p0) { col = ink(col); break; }
          }
          float acc = 0.0, rad = uSil * 3.0;
          for (int k = 0; k < 8; k++) {
            float a = float(k) * 0.785398 + 0.39;
            vec2 q = uv + vec2(cos(a), sin(a)) * rad * px;
            vec4 ni = texture2D(tInfo, q);
            if (ni.a > 0.5) acc += clamp((z0 - z(q)) / 0.05, 0.0, 1.0);
          }
          col *= 1.0 - 0.22 * acc / 8.0;
          if (r0 == 1) {                                            // the bangs shade the forehead
            float hair = 0.0;
            for (int s = 1; s <= 4; s++) { vec4 a = texture2D(tInfo, uv + vec2(0.0, float(s)) * uSil * px); int ra = rid(a); if (a.a > 0.5 && (ra == 3 || ra == 11)) hair = 1.0; }
            col = mix(col, col * vec3(0.84, 0.74, 0.76), 0.75 * hair);
          }
        }
        gl_FragColor = vec4(col, 1.0);
      }`;
    
    const compCam = new THREE.Camera();
    function compPass(fs, uniforms) {
      const mat = new THREE.ShaderMaterial({ uniforms, vertexShader: `void main() { gl_Position = vec4(position.xy, 0.0, 1.0); }`,
                                             fragmentShader: fs, transparent: true });
      const s = new THREE.Scene(); s.add(new THREE.Mesh(new THREE.PlaneGeometry(2, 2), mat));
      return { mat, scene: s };
    }
    
    // ---- the renderer ---------------------------------------------------------------------------------------------------
    const stageEl = $("stage");
    const R = new THREE.WebGLRenderer({ antialias: false, alpha: true, preserveDrawingBuffer: !!SHEET });
    R.setClearColor(0x000000, 0);
    R.outputColorSpace = THREE.LinearSRGBColorSpace;
    stageEl.appendChild(R.domElement);
    const paint = compPass(PAINT_COMP, { tColor: { value: null }, tInfo: { value: null }, tDepth: { value: null }, uRes: { value: new THREE.Vector2() },
      uNear: { value: 0.1 }, uFar: { value: 40 }, uGap: { value: 0.012 }, uSil: { value: 2 }, uInner: { value: 1 } });
    const ctl = new OrbitControls(camera, R.domElement);
    ctl.enableDamping = true; ctl.zoomToCursor = true; ctl.screenSpacePanning = true;
    ctl.minZoom = 0.3; ctl.maxZoom = 12;
    let freeLook = false;
    ctl.addEventListener("start", () => { freeLook = true; });
    R.domElement.addEventListener("dblclick", focusAt);
    const targets = { rt: null, rtInfo: null, key: "" };
    function targetsFor(w, h) {
      const key = `${w}x${h}`;
      if (targets.key === key) return;
      [targets.rt, targets.rtInfo].forEach(t => t && t.dispose());
      const o = { minFilter: THREE.NearestFilter, magFilter: THREE.NearestFilter };
      targets.rt = new THREE.WebGLRenderTarget(w, h, o);
      targets.rtInfo = new THREE.WebGLRenderTarget(w, h, { ...o, depthTexture: new THREE.DepthTexture(w, h) });
      targets.key = key;
    }
    
    // ---- cloth -------------------------------------------------------------------------------------------------------
    // The skinned cape/tails stay hidden and provide the pinned row (they follow the animated body);
    // a plain display mesh in world space shows the simulated cloth. Colliders ride the bones.
    const _v = new THREE.Vector3(), _a = new THREE.Vector3(), _ab = new THREE.Vector3(), _cp = new THREE.Vector3();
    const _A = new THREE.Vector3(), _B = new THREE.Vector3();
    class Cloth {
      constructor(skinned, U, V, trims, capsules, bone, closed = false, hemOnly = false) {
        this.skinned = skinned; this.U = U; this.V = V; this.trims = trims; this.closed = closed; this.hemOnly = hemOnly;
        this.n = skinned.geometry.attributes.position.count;
        this.caps = capsules.map(c => ({ a: bone(c.bones[0]), b: bone(c.bones[1]), r: c.r + 0.006 })).filter(c => c.a && c.b);
        this.x = new Float32Array(this.n * 3); this.prev = new Float32Array(this.n * 3);
        const idx = (i, j) => i * V + j, links = [], bends = [], edge = new Float32Array(this.n);
        for (let i = 0; i < U; i++) for (let j = 0; j < V; j++) {
          // a closed cloth (a skirt) wraps around: the last column links back to the first
  • Bashsource ~/Projects/lowmarch-bench/kit/env-b.sh && cat ~/Projects/lowmarch-bench/brief/materials/vroid-shapes.txt | head -80; cd $LOWMARCH_REPO && sed -n 980,1000p tools/vroid_portrait.py; grep -n '"1"\|"A"\|"B"' tools/vroid_portrait.py | head

    command

    source ~/Projects/lowmarch-bench/kit/env-b.sh && cat ~/Projects/lowmarch-bench/brief/materials/vroid-shapes.txt | head -80; cd $LOWMARCH_REPO && sed -n 980,1000p tools/vroid_portrait.py; grep -n '"1"\|"A"\|"B"' tools/vroid_portrait.py | head

    result, 42 lines

    The 57 VRoid expression shapes on our faces (morph targets, applied by tools/vrm.py VRM.primitives; a recipe key
    matches a target whose name ends with it):
    Fcl_ALL_Angry Fcl_ALL_Fun Fcl_ALL_Joy Fcl_ALL_Neutral Fcl_ALL_Sorrow Fcl_ALL_Surprised
    Fcl_BRW_Angry Fcl_BRW_Fun Fcl_BRW_Joy Fcl_BRW_Sorrow Fcl_BRW_Surprised
    Fcl_EYE_Angry Fcl_EYE_Close Fcl_EYE_Close_L Fcl_EYE_Close_R Fcl_EYE_Fun Fcl_EYE_Highlight_Hide Fcl_EYE_Iris_Hide
    Fcl_EYE_Joy Fcl_EYE_Joy_L Fcl_EYE_Joy_R Fcl_EYE_Natural Fcl_EYE_Sorrow Fcl_EYE_Spread Fcl_EYE_Surprised
    Fcl_HA_Fung1 Fcl_HA_Fung1_Low Fcl_HA_Fung1_Up Fcl_HA_Fung2 Fcl_HA_Fung2_Low Fcl_HA_Fung2_Up Fcl_HA_Fung3
    Fcl_HA_Fung3_Low Fcl_HA_Fung3_Up Fcl_HA_Hide Fcl_HA_Short Fcl_HA_Short_Low Fcl_HA_Short_Up
    Fcl_MTH_A Fcl_MTH_Angry Fcl_MTH_Close Fcl_MTH_Down Fcl_MTH_E Fcl_MTH_Fun Fcl_MTH_I Fcl_MTH_Joy Fcl_MTH_Large
    Fcl_MTH_Neutral Fcl_MTH_O Fcl_MTH_SkinFung Fcl_MTH_SkinFung_L Fcl_MTH_SkinFung_R Fcl_MTH_Small Fcl_MTH_Sorrow
    Fcl_MTH_Surprised Fcl_MTH_U Fcl_MTH_Up
                elif r == "hair":
                    char[mk] = bands(lit[mk], HAIR_BANDS)
                elif r == "cloth":
                    char[mk] = bands(lit[mk], CLOTH_BANDS)
                elif r in MATERIALS:
                    nn = n[mk]
                    back = nn[:, 2] < 0                      # we see the inside of the piece
                    lv = np.where(back, (-nn) @ LIGHT, lit[mk])
                    c = bands(lv, MATERIALS[r])
                    c[back] = [DARKER.get(x_, x_) for x_ in c[back]]
                    char[mk] = c
                elif r in ("line",):
                    char[mk] = "o"
                elif r == "brow":
                    char[mk] = "A"
                elif r == "mouth":
                    char[mk] = "1"
                elif r == "white":
                    char[mk] = "w"
                elif r == "highlight":
                    char[mk] = "w"
    42:PRIORITY = {"o": 8, "r": 5, "s": 5, "t": 4, "w": 3, "A": 3, "1": 8}   # features win the 4x4 vote
    56:HAIR_BANDS = [(0.86, "E"), (0.66, "D"), (0.42, "C"), (-9, "B")]
    975:                        c[on] = "1"
    994:                char[mk] = "A"
    996:                char[mk] = "1"
    1019:            down = {"E": "D", "D": "C", "C": "B", "B": "A"}
    1060:            rule[skin & skin1] = "1"
    1062:            rule[hair0 & hair1 & (p1 != prim)] = "A"
    1118:        c[y, x] = "3" if end else "1"
    1143:            c[y, x] = "1" if dark[0] <= u <= dark[1] else "2"
  • Bashsource ~/Projects/lowmarch-bench/kit/env-b.sh && cd $WORK/site && python3 -c "

    command

    source ~/Projects/lowmarch-bench/kit/env-b.sh && cd $WORK/site && python3 -c "
    import json;d=json.load(open('arm_f_slender.glb.json'));print(type(d), list(d.keys())[:20] if isinstance(d,dict) else len(d))
    " ; ls -la; head -c 600 camera.json

    result, 55 lines

    <class 'dict'> ['glb']
    total 7476
    drwx------ 2 severian severian    4096 Oct 30 12:42 .
    drwx------ 4 severian severian    4096 Oct 30 12:43 ..
    -rw------- 1 severian severian 4268051 Oct 30 12:42 arm_f_slender.glb.json
    -rw------- 1 severian severian 2785655 Oct 30 12:42 arm_m_youth.glb.json
    -rw------- 1 severian severian  256105 Oct 30 12:42 camera.json
    -rw------- 1 severian severian    5960 Oct 30 12:42 checks.json
    -rw------- 1 severian severian  106760 Oct 30 12:42 index.html
    -rw------- 1 severian severian  206775 Oct 30 12:42 plains.glb.json
    {
     "characters": [
      {
       "name": "arm_m_youth",
       "label": "Man, youth",
       "info": {
        "roles": {
         "face": {
          "mode": "bands",
          "bands": [
           [
            0.8,
            "#fff6d8"
           ],
           [
            0.62,
            "#fbd99c"
           ],
           [
            0.38,
            "#eca067"
           ],
           [
            -9,
            "#b06e4b"
           ]
          ]
         },
         "body": {
          "mode": "bands",
          "bands": [
           [
            0.8,
            "#fff6d8"
           ],
           [
            0.62,
            "#fbd99c"
           ],
           [
            0.38,
            "#eca067"
           ],
           [
            -9
  • Bashsource ~/Projects/lowmarch-bench/kit/env-b.sh && mkdir -p $WORK/tex && cd $WORK && python3 -I - <<'EOF'

    command

    source ~/Projects/lowmarch-bench/kit/env-b.sh && mkdir -p $WORK/tex && cd $WORK && python3 -I - <<'EOF'
    import json,base64,struct,io
    d=json.load(open('site/arm_f_slender.glb.json'))['glb']
    b=base64.b64decode(d)
    L=struct.unpack('<I',b[12:16])[0]; js=json.loads(b[20:20+L]); bin0=20+L+8
    print([m.get('name') for m in js['materials']])
    for i,m in enumerate(js['materials']):
        pbr=m.get('pbrMetallicRoughness',{}); t=pbr.get('baseColorTexture')
        if t is None: continue
        img=js['images'][js['textures'][t['index']]['source']]; bv=js['bufferViews'][img['bufferView']]
        open(f'tex/{i}_{m.get("name")}.png','wb').write(b[bin0+bv.get('byteOffset',0):bin0+bv.get('byteOffset',0)+bv['byteLength']])
    print([ (me.get('name'), me.get('extras')) for me in js['meshes']][:40])
    EOF
    ls $WORK/tex

    result, 12 lines

    ['body:mouth', 'body:iris', 'body:highlight', 'body:face', 'body:white', 'body:brow', 'body:line', 'body:line', 'body:body', 'hair:hair', 'hair:hair', 'underwear:cloth', 'underwear:cloth', 'body:shadow']
    [('body', None), ('body', None), ('body', None), ('body', None), ('body', None), ('body', None), ('body', None), ('body', None), ('body', None), ('hair', None), ('hair', None), ('underwear', None), ('underwear', None), ('body', None)]
    0_body:mouth.png
    10_hair:hair.png
    1_body:iris.png
    2_body:highlight.png
    3_body:face.png
    4_body:white.png
    5_body:brow.png
    6_body:line.png
    7_body:line.png
    9_hair:hair.png
  • Read~/Projects/lowmarch-bench/work/b/tex/0_body:mouth.png

    input

    {
      "file_path": "~/Projects/lowmarch-bench/work/b/tex/0_body:mouth.png"
    }

    result

    no output

    tex_0_body-mouth.png
    tex_0_body-mouth.png
  • Read~/Projects/lowmarch-bench/brief/materials/yin-expressions/shout_y00.png

    input

    {
      "file_path": "~/Projects/lowmarch-bench/brief/materials/yin-expressions/shout_y00.png"
    }

    result, 1 line

    [redacted: reference rig image (Yin/Yang by DillonGoo, personal-use licence)]
  • Bashsource ~/Projects/lowmarch-bench/kit/env-b.sh && cd $LOWMARCH_REPO && grep -n -i 'weight\|morph\|target' tools/vrm.py | head -30; grep -n 'rest' tools/vroid_portrait.py | head -20; grep -n -i 'brow\|bang' docs/portrait-guide.md | head -30

    command

    source ~/Projects/lowmarch-bench/kit/env-b.sh && cd $LOWMARCH_REPO && grep -n -i 'weight\|morph\|target' tools/vrm.py | head -30; grep -n 'rest' tools/vroid_portrait.py | head -20; grep -n -i 'brow\|bang' docs/portrait-guide.md | head -30

    result, 45 lines

    133:    def primitives(self, morphs=None, pose=None):
    135:        morphs: {target name substring: weight} applied to meshes that have targets.
    141:            names = mesh.get("extras", {}).get("targetNames") or \
    142:                mesh["primitives"][0].get("extras", {}).get("targetNames") or []
    148:                if morphs and pr.get("targets"):
    149:                    for key, wgt in morphs.items():
    151:                            if tn.endswith(key) and "POSITION" in pr["targets"][ti]:
    152:                                pos += wgt * self.accessor(pr["targets"][ti]["POSITION"])
    157:                    Wt = self.accessor(at["WEIGHTS_0"]).astype(np.float64)
    171:    def target_names(self):
    173:            names = mesh.get("extras", {}).get("targetNames") or \
    174:                mesh["primitives"][0].get("extras", {}).get("targetNames")
    251:def bone_weight(prim, match):
    252:    """Per-vertex total skin weight on bones whose name contains any of `match` (substrings)."""
    121:    the winning char per pixel plus the depth / primitive / role of its nearest sample."""
    161:#  3. resting expression: VRoid's own shapes (hooded eyes, stern brows) held at a low weight
    167:               face_normals=1.0, hair_normals=0.0, shadow_cards=1.0, rest={})
    476:    weights at the nearest vertex, so it rides and bends with the skin beneath."""
    601:        """A point on the face seen straight on: the nearest surface hit from the front."""
    739:        mo = dict(sh["rest"])
    1093:    # no triangle contains it (a gap between UV islands): take the nearest vertex in UV space
    16:material's own darkest tone: rosy brown in skin, darkest hair tone between locks.
    19:steps (yellow-cream → orange → brown → line). Shadows go: under the bangs (cast), the far side
    28:**Brows.** Men: heavy, sitting right on the lash line. Women: thin, high.
    34:upper left) and a shadow side; the separating line sits on the shadow side. Bangs sweep
    41:Heavy builds: round masses. Women: rounder cheeks, more eye white, thin high brows.
    52:   separating lines. Then `pix.py shadow` casts the bangs onto the face.
    63:- Bangs hanging straight down read as a curtain. Sweep them toward the face's turn.
    68:- Bare forehead between bangs looked like light columns. Always run the cast-shadow pass.
    96:- **Flat eye plane.** A cylinder-like face squeezes the far eye even at 20° ("cursed"). Keep brow and
    121:- **Features from geometry and masks.** Eyes, brows and lashes come from VRoid's alpha-tested face
    126:- **Archetypes are shape controls on the mesh** (face length, jaw, chin, cheeks, eyes, brows, nose,
    157:  inside the nose-and-mouth window of the shared VRoid face layout, or the ear shading turns brown.
    202:- **Cloth in the viewer:** the cape and tails export as grids (`grid`); the browser runs Verlet with
    321:  leaves the bangs and side locks.
    540:  - Bangs read as separate pointed locks when they are narrow (2.2-2.8 cm) with long tapers.
    542:- **Bangs from a study, not a formula.** The user found seven evenly spaced matching points jarring.
    550:  `lock(profile=...)` takes a width profile (`hair.clump`). Elaine's bangs: a side part over her
    616:- The eyes, brows and mouth are anime drawings in textures, so moving the skull under them changes
    633:  smoothed brow strips, and a lip line.
    834:brows, mouth and expression shapes) by landmarks onto MakeHuman's skull, keeping MakeHuman's structure and
    1164:  length, cheeks, eye size), and leave the jaw, brow and nose to the design.
    1231:face, brows, lines, mouth and skull are shaded from normals that point away from a short vertical line inside the
    1329:  and the stage's blue shade turned brown skin grey. A ramp per tone, with shade hue nudged warm on people (cool on
    1332:  and stopped at a mid brown.
  • Bashsource ~/Projects/lowmarch-bench/kit/env-b.sh && cd $LOWMARCH_REPO && sed -n 800,840p review/vroid-02/index.html; grep -n 'SKIN_BODY =\|SKIN_HEAD =' review/vroid-02/index.html

    command

    source ~/Projects/lowmarch-bench/kit/env-b.sh && cd $LOWMARCH_REPO && sed -n 800,840p review/vroid-02/index.html; grep -n 'SKIN_BODY =\|SKIN_HEAD =' review/vroid-02/index.html

    result, 43 lines

                    bust: { ambient: [0.90, 0.90, 0.98], key: [1.03, 1.0, 0.96], rim: [0.24, 0.24, 0.34] } };
    const KIND = { cloth: 0, skin: 1, hair: 2, steel: 3, gold: 4, leather: 5, world: 6 };
    function paintMaterial(V, role, map, index, infoRole = role, decal = false) {
      const Rl = V.roles[role] || { mode: "flat", color: "#ff00ff" }, P = (V.paint || {})[role];
      const u = { uKind: { value: 9 }, uBase: { value: new THREE.Color(0.8, 0.8, 0.8) }, uKey: { value: KEY.clone() },
        uMap: { value: map || white }, uAlpha: { value: 0 }, uPass: { value: 0 },
        uInfo: { value: new THREE.Vector4(roleId(infoRole) / 255, (index % 256) / 255, Math.floor(index / 256) / 255, 1) },
        uEye: { value: V.roles.iris.colors.map(hex) }, uFlat: { value: new THREE.Color() }, uSkinRef: { value: new THREE.Vector3(0.965, 0.878, 0.80) },
        uGold: { value: hex((V.paint && V.paint.gold && V.paint.gold.base) || "#b08b3f") },
        uAmbient: { value: new THREE.Vector3(1, 1, 1) }, uKeyCol: { value: new THREE.Vector3(1, 1, 1) }, uRimCol: { value: new THREE.Vector3() },
        uGrain: { value: 0.05 }, uFaceTex: { value: 0 }, uDecal: { value: decal ? 1 : 0 }, uBand: { value: null },
        uSkinTone: { value: new THREE.Vector3(1, 1, 1) }, uShadeOnly: { value: 0 },
        uSkinRamp: { value: 0 }, uSkinL: { value: new THREE.Color() }, uSkinS: { value: new THREE.Color() }, uSkinC: { value: new THREE.Color() },
        tCastInfo: { value: null }, tCastDepth: { value: null }, uCastRes: { value: new THREE.Vector2(1, 1) }, uCastOn: { value: 0 },
        uCastNear: { value: 0.1 }, uCastFar: { value: 40 }, uCastPpm: { value: 1 },
        uMotif: { value: hex((V.paint && V.paint.motif && V.paint.motif.base) || "#3a44a0") } };
      if (P) { u.uKind.value = KIND[P.kind] ?? 0; if (P.base) u.uBase.value = hex(P.base); if (P.grain != null) u.uGrain.value = P.grain; }
      else if (Rl.bands) { u.uKind.value = Rl.world ? 6 : 0; u.uBase.value = hex(Rl.bands[Math.min(1, Rl.bands.length - 1)][1]); }
      if (P && P.kind === "world") { u.uKey.value = new THREE.Vector3(...V.sun); u.uGrain.value = 0.12; }
      if (P && P.shade) u.uShadeOnly.value = 1;         // shadow cards: skin, always in its shade tone
      if (P && P.kind === "skin" && P.ramp) {           // a designed ramp: lit, shade, deep shade
        u.uSkinRamp.value = 1; u.uSkinL.value = hex(P.ramp[0]); u.uSkinS.value = hex(P.ramp[1]); u.uSkinC.value = hex(P.ramp[2]);
      }
      if (P && P.kind === "skin" && P.base) {           // skin tone: the base colour against the default light skin
        const c = hex(P.base); u.uSkinTone.value.set(c.r / 0.973, c.g / 0.882, c.b / 0.835);
      }
      if (role === "face" && map) u.uFaceTex.value = 1;
      if (role === "hair" && map) u.uAlpha.value = 1;
      if (role === "iris") { u.uKind.value = 7; u.uAlpha.value = 1; }
      else if (role === "white" || role === "highlight") { u.uKind.value = map ? 8 : 9; if (map) u.uAlpha.value = 1; u.uFlat.value = hex(Rl.color || "#ffffff"); }
      else if (!P && Rl.mode === "flat") { u.uKind.value = 9; u.uFlat.value = hex(Rl.color); if (map) u.uAlpha.value = role === "line" ? 2 : 1; }
      u.uBand.value = u.uGold.value.clone();
      const m = new THREE.ShaderMaterial({ uniforms: u, vertexShader: PAINT_VS, fragmentShader: PAINT_FS, side: THREE.DoubleSide,
                                           extensions: { derivatives: true } });
      // meshes without plate data or a cloth edge read zeros, not whatever another program left in that slot
      m.defaultAttributeValues = { ...m.defaultAttributeValues, _plate: [0, 0, 0, 0], edge: [0] };
      return m;
    }
    
    // ---- models ------------------------------------------------------------------------------------------------------
    const loader = new GLTFLoader();
    309:const SKIN_HEAD = `#include <common>
    311:const SKIN_BODY = `#include <beginnormal_vertex>
  • Bashsource ~/Projects/lowmarch-bench/kit/env-b.sh && cd $LOWMARCH_REPO && python3 -I - <<'EOF'

    command

    source ~/Projects/lowmarch-bench/kit/env-b.sh && cd $LOWMARCH_REPO && python3 -I - <<'EOF'
    p='review/vroid-02/index.html'; s=open(p).read()
    def rep(a,b):
        global s
        assert s.count(a)==1,a; s=s.replace(a,b)
    rep("""  attribute float edge; attribute vec4 _plate;
      varying vec3 vN;""","""  attribute float edge; attribute vec4 _plate; uniform float uLift;
      varying vec3 vN;""")
    rep("""    vec4 mv = modelViewMatrix * vec4(transformed, 1.0); vView = -mv.xyz;
        gl_Position""","""    vec4 mv = modelViewMatrix * vec4(transformed, 1.0); vView = -mv.xyz;
        mv.z += uLift;                                              // brows: drawn over the bangs (depth lift toward the camera)
        gl_Position""")
    rep("""    } else if (uKind == 8) { col = tex.rgb; }""","""    } else if (uKind == 8) { col = tex.rgb; }
        else if (uKind == 10) {                                            // open mouth: deep maroon, pink tongue, white teeth
          float l = dot(tex.rgb, vec3(1.0 / 3.0));
          vec3 deep = vec3(0.34, 0.12, 0.15), tongue = vec3(0.88, 0.47, 0.49);
          col = mix(deep, tongue, smoothstep(0.65, 0.70, l));
          col = mix(col, vec3(0.99, 0.97, 0.96), smoothstep(0.84, 0.90, l));
        }""")
    rep("""    uMotif: { value: hex((V.paint && V.paint.motif && V.paint.motif.base) || "#3a44a0") } };""",
    """    uMotif: { value: hex((V.paint && V.paint.motif && V.paint.motif.base) || "#3a44a0") }, uLift: { value: 0 } };""")
    rep("""  u.uBand.value = u.uGold.value.clone();""","""  if (role === "brow") u.uLift.value = BROW_LIFT;
      if (role === "mouth" && map) { u.uKind.value = 10; u.uAlpha.value = 1; }
      u.uBand.value = u.uGold.value.clone();""")
    rep("""const KIND = { cloth: 0,""","""// Brows draw over the bangs: they are lifted this far (m) toward the camera, more than the bangs stand off the
    // forehead and much less than the head is deep, so a brow still hides behind the skull when the head turns away.
    const BROW_LIFT = 0.04;
    const KIND = { cloth: 0,""")
    open(p,'w').write(s)
    EOF
    grep -n 'uniform vec3 uGold' review/vroid-02/index.html

    result, 1 line

    345:  uniform vec3 uGold; uniform vec3 uAmbient; uniform vec3 uKeyCol; uniform vec3 uRimCol; uniform float uGrain;
  • Bashsource ~/Projects/lowmarch-bench/kit/env-b.sh && cp $WORK/expr_list.txt $WORK/expr_list.orig.txt && cat > $WORK/expr_list.txt <<'EOF'

    command

    source ~/Projects/lowmarch-bench/kit/env-b.sh && cp $WORK/expr_list.txt $WORK/expr_list.orig.txt && cat > $WORK/expr_list.txt <<'EOF'
    # expression recipes: name|VRoid shapes baked at build (Fcl_* names, weight; ';' between; 'none' = neutral)
    # the 14 the sheets show; keep these names (front_sheet.py reads them). Edit the recipes freely.
    neutral|none
    joy|Fcl_BRW_Joy:1;Fcl_EYE_Joy:1;Fcl_MTH_Joy:0.6
    smile|Fcl_BRW_Fun:1;Fcl_EYE_Fun:0.5;Fcl_MTH_Fun:1
    angry|Fcl_BRW_Angry:1.4;Fcl_EYE_Angry:1;Fcl_MTH_Angry:1
    sad|Fcl_BRW_Sorrow:1.3;Fcl_EYE_Sorrow:1;Fcl_MTH_Sorrow:1
    surprised|Fcl_BRW_Surprised:1.2;Fcl_EYE_Surprised:1;Fcl_MTH_Surprised:0.6
    shout|Fcl_BRW_Angry:1.3;Fcl_EYE_Angry:0.8;Fcl_MTH_A:0.8
    wink|Fcl_EYE_Close_R:1;Fcl_BRW_Fun:0.6;Fcl_MTH_Fun:1
    smug|Fcl_EYE_Close:0.35;Fcl_BRW_Angry:0.5;Fcl_MTH_Fun:0.6
    lip_A|Fcl_MTH_A:0.75
    lip_I|Fcl_MTH_I:1
    lip_U|Fcl_MTH_U:1
    lip_E|Fcl_MTH_E:0.9
    lip_O|Fcl_MTH_O:0.75
    EOF
    cd $LOWMARCH_REPO && time $KIT/build_expr.sh $WORK/expr_list.txt neutral joy smile angry sad surprised shout

    result, 11 lines

    built neutral
    built joy
    built smile
    built angry
    built sad
    built surprised
    built shout
    
    real	1m44.552s
    user	1m28.765s
    sys	1m7.160s
  • Bashsource ~/Projects/lowmarch-bench/kit/env-b.sh && cd $LOWMARCH_REPO && time $KIT/build_expr.sh $WORK/expr_list.txt wink smug lip_A lip_I lip_U lip_E lip_O && time $KIT/shoot_expr.sh $LOWMARCH_REPO/review/vroid-02/index.html r1 && $KIT/sheets.sh r1 "Round 1: brows over bangs, textured mouth, tuned recipes"

    command

    source ~/Projects/lowmarch-bench/kit/env-b.sh && cd $LOWMARCH_REPO && time $KIT/build_expr.sh $WORK/expr_list.txt wink smug lip_A lip_I lip_U lip_E lip_O && time $KIT/shoot_expr.sh $LOWMARCH_REPO/review/vroid-02/index.html r1 && $KIT/sheets.sh r1 "Round 1: brows over bangs, textured mouth, tuned recipes"

    result, 18 lines

    built wink
    built smug
    built lip_A
    built lip_I
    built lip_U
    built lip_E
    built lip_O
    
    real	1m42.031s
    user	1m32.035s
    sys	1m10.588s
    shot r1
    
    real	7m59.116s
    user	0m32.270s
    sys	0m27.314s
    ~/Projects/lowmarch-bench/work/b/sheet_r1_woman.png (1968, 1144)
    ~/Projects/lowmarch-bench/work/b/sheet_r1_youth.png (1968, 1144)
  • Read~/Projects/lowmarch-bench/work/b/sheet_r1_woman.png

    input

    {
      "file_path": "~/Projects/lowmarch-bench/work/b/sheet_r1_woman.png"
    }

    result

    no output

    sheet_r1_woman.jpg
    sheet_r1_woman.jpg
  • Read~/Projects/lowmarch-bench/work/b/sheet_r1_youth.png

    input

    {
      "file_path": "~/Projects/lowmarch-bench/work/b/sheet_r1_youth.png"
    }

    result

    no output

    sheet_r1_youth.jpg
    sheet_r1_youth.jpg
  • Bashsource ~/Projects/lowmarch-bench/kit/env-b.sh && cd $WORK && python3 -I -c "

    command

    source ~/Projects/lowmarch-bench/kit/env-b.sh && cd $WORK && python3 -I -c "
    from PIL import Image
    im=Image.open('shot_r1/shout/painted_arm_f_slender.png'); print(im.size)
    w,h=im.size; im.crop((300,560,700,860)).resize((800,600)).save('$WORK/crop_shout.png')
    im.crop((w//2+250,560,w//2+650,860)).resize((800,600)).save('$WORK/crop_shout30.png')
    "

    result, 1 line

    (1938, 1024)
  • Read~/Projects/lowmarch-bench/work/b/crop_shout.png

    input

    {
      "file_path": "~/Projects/lowmarch-bench/work/b/crop_shout.png"
    }

    result

    no output

    crop_shout.png
    crop_shout.png
  • Read~/Projects/lowmarch-bench/work/b/crop_shout30.png

    input

    {
      "file_path": "~/Projects/lowmarch-bench/work/b/crop_shout30.png"
    }

    result

    no output

    crop_shout30.png
    crop_shout30.png
  • Bashsource ~/Projects/lowmarch-bench/kit/env-b.sh && time $KIT/terra_review.sh r1 $WORK/sheet_r1_woman.png $WORK/sheet_r1_youth.png

    command

    source ~/Projects/lowmarch-bench/kit/env-b.sh && time $KIT/terra_review.sh r1 $WORK/sheet_r1_woman.png $WORK/sheet_r1_youth.png

    result, 18 lines

    exit=0
    The current round makes the brows easier to read, especially for Angry and Surprised, but drawing them over the bangs creates a floating, pasted-on look. The new pink mouths also lose some of the depth and clarity of the darker Before mouths.
    
    **Woman:** Joy and Wink read clearly through the closed eyes; Angry reads through the sharply slanted brows. Neutral and Smile are pleasant but very similar. Sad reads mostly from the brows and small mouth; the eyes still look fairly neutral. Surprised and Shout are harder to tell apart: both mouths are small, horizontal pink shapes, and Surprised lacks a convincing open “O.” Smug reads close to Neutral because the eyes and mouth barely change.
    
    **Youth:** Joy, Angry and Surprised read through their eye and brow shapes. Wink reads, though the closed eye still shows enough iris to look half-lidded. Smile, Sad and Smug are subtle; Smug especially needs a more asymmetric or self-satisfied mouth. Shout looks more like a small smile than a forceful call.
    
    For both bodies, the lip-sync shapes have regressed: A and O are flattened and similarly pink, I is nearly invisible, U is a tiny mark, and E is a thin smile. White rims and dark corner fragments make several mouths look outlined or detached.
    
    The three highest-impact changes for the next round:
    
    1. **Integrate the brows with the hair:** keep their expressive angles, but break or soften strokes where bangs cross them so they don’t appear painted on top.
    2. **Restore mouth depth:** use a dark interior with restrained tongue or lip colour; remove the white rims and corner fragments. Give Shout a substantially taller opening.
    3. **Separate the phonemes:** make A tall and open, I wide and narrow, U small and rounded, E wide with visible teeth, and O distinctly round.
    
    real	0m14.235s
    user	0m0.797s
    sys	0m0.729s