<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
  <title>Alienrobot Devlog — John Huikku</title>
  <link>https://alienrobot.com/blog.html</link>
  <atom:link href="https://alienrobot.com/blog/feed.xml" rel="self" type="application/rss+xml"/>
  <description>Working notes on hybrid CG/ML pipelines, ComfyUI tooling, agentic AI, and VFX R&amp;D, posted as it ships.</description>
  <language>en-us</language>
  <lastBuildDate>Sun, 19 Jul 2026 12:00:00 GMT</lastBuildDate>
  <item>
    <title>GNM Head Studio — a parametric face rig for ComfyUI, and why the clay head isn&#x27;t the point</title>
    <link>https://alienrobot.com/blog-post.html?p=2026-07-19-gnm-head-studio</link>
    <guid isPermaLink="false">alienrobot-blog-2026-07-19-gnm-head-studio</guid>
    <pubDate>Sun, 19 Jul 2026 12:00:00 GMT</pubDate>
    <category>comfyui</category>
    <category>3d</category>
    <category>controlnet</category>
    <category>face</category>
    <description><![CDATA[<p>Google&#x27;s GNM is a parametric statistical 3D head model — sliders for identity, expression and pose. I put it behind two ComfyUI nodes and a browser app so it&#x27;s actually drivable. <a href="https://huikku.github.io/gnm-head-studio/">Live app</a> · <a href="https://github.com/huikku/gnm-head-studio">repo</a>.</p>
<p>The honest part first, same as I put in the README: as a sculpting toy it loses to any realtime WebGL viewer. ComfyUI renders on Queue Prompt, not continuous drag, so even at ~0.15s a render you get discrete updates, not a smooth morph. The clay head was never the point.</p>
<p>The point is that GNM becomes a deterministic control signal. The head renders to depth and normal maps, those maps drive a depth ControlNet, and out comes a photoreal face at an <em>exact</em> pose, proportion and framing — control a random reference photo can&#x27;t give you. A slider moves, the depth map changes, the generated face follows. Same identity vector, same skull, every time.</p>
<p><img src="https://alienrobot.com/blog/gnm-controlnet.webp" alt="GNM depth and normal maps driving a depth ControlNet to a photoreal face"></p>
<p>Two caveats I didn&#x27;t bury: depth control nails pose and proportion, but subtle expressions transfer weakly through a 512px map, and depth alone doesn&#x27;t lock identity across angles — you still want a reference adapter for that. That&#x27;s the real ceiling of geometry-as-control, and it&#x27;s why this is a control input, not a finished-face generator.</p>
<p>The actual work was the environment. GNM pulls in TensorFlow, which upgrades protobuf and breaks onnx / insightface / ReActor in a normal ComfyUI env. So the heavy stuff runs in an isolated venv with a warm render server over localhost, and rendering goes through nvdiffrast instead of GNM&#x27;s TF/pyrender path. Your main ComfyUI never gets touched. That isolation is the whole trick.</p>
<p>There&#x27;s also a client-side web app that sculpts a head and exports depth/normal maps entirely in the browser, on your own GPU — no Python, no backend. The GNM deformations are precomputed as a linear blend-shape model (6.6MB, verified 0.00% error against the real model), so the browser just does <code>neutral + Σ slider×delta</code>. The exported maps drop straight into the ComfyUI graphs above.</p>]]></description>
  </item>
  <item>
    <title>One product photo, a whole campaign — a Nano Banana Pro field guide</title>
    <link>https://alienrobot.com/blog.html#2026-07-18-nano-banana-pro-field-guide</link>
    <guid isPermaLink="false">alienrobot-blog-2026-07-18-nano-banana-pro-field-guide</guid>
    <pubDate>Sat, 18 Jul 2026 12:00:00 GMT</pubDate>
    <category>generative-ai</category>
    <category>brand</category>
    <category>claude-skill</category>
    <description><![CDATA[<p>Google&#x27;s Nano Banana Pro — the Gemini 3 Pro image model — is genuinely good for brand work, but almost everything written about it is viral one-offs, not a method you can run twice and get the same brand back. So I wrote a field guide for it. <a href="https://huikku.github.io/NBPro-campaign-guide/">Companion site</a> · <a href="https://github.com/huikku/NBPro-campaign-guide">repo</a>.</p>
<p>The whole guide collapses to one move: mint a single product master first — one file, the product from a few angles with its real label — then attach it to every image you generate afterward. The world changes, the product stays. That&#x27;s what stops variation #47 from looking like a different brand than #1.</p>
<p><img src="https://alienrobot.com/blog/nbpro-consistency.webp" alt="One product master, attached to three different scenes — same bottle, same label, three worlds"></p>
<p>I also ran a fair tier bake-off — Pro vs 2 vs Lite, same prompt, same seed, master attached to <em>all</em> of them — instead of the usual test where each model invents its own label from scratch. Once there&#x27;s a reference attached, all four hold the brand, and the difference collapses to render quality, speed and price. Nano Banana 2 came out the value pick: richest result at 2K for half of Pro&#x27;s cost. And &#x27;Lite&#x27; is misnamed — it&#x27;s faster (~7s), but at $1/unit it isn&#x27;t cheaper, so it&#x27;s a sketchpad, not a volume play.</p>
<p>Everything in the guide was generated by a Claude skill that ships in the repo, so the images are reproducible rather than cherry-picked. The site runs beginner-to-advanced; the skill is the part I&#x27;d actually keep.</p>]]></description>
  </item>
  <item>
    <title>comfyui-loop-mcp: a ratchet that survives context, and every tool under test</title>
    <link>https://alienrobot.com/blog.html#2026-07-15-comfyui-loop-mcp-ratchet</link>
    <guid isPermaLink="false">alienrobot-blog-2026-07-15-comfyui-loop-mcp-ratchet</guid>
    <pubDate>Wed, 15 Jul 2026 12:00:00 GMT</pubDate>
    <category>comfyui</category>
    <category>mcp</category>
    <category>agentic-ai</category>
    <description><![CDATA[<p>comfyui-loop-mcp got the work that actually makes it trustworthy over the last few days — the loop discipline moved from prose in the tool descriptions to state on disk. <a href="https://github.com/huikku/comfyui-loop-mcp">repo</a>.</p>
<p>The ratchet is the whole idea: hold a best-so-far, keep a change only if it beats it, otherwise revert. Before this, that lived in the model&#x27;s head — which means one context compaction wipes it and the agent quietly starts handing back regressions. Now the best graph and the decision ledger sit in a file. A revert is a tool call, not an act of recall.</p>
<p><img src="https://alienrobot.com/comfyui-loop-mcp-proof.webp" alt="One real loop where the objective seam score overruled the model&#x27;s own claim and reverted to the better pass"></p>
<p>Proof matters more than the claim, so there&#x27;s a run in the repo where the ratchet caught the model lying about its own work. Pass 3 of a tiling texture read as &quot;better&quot; to the model; the objective seam score said otherwise, and it reverted to pass 2 on its own. An agent that wants to be finished will call a regression an improvement — the gate is what stops it.</p>
<p>The unglamorous half was correctness. Every one of the MCP tools now has a passing test — the ones that install nodes, the ones that look at the rendered image, the ratchet itself. Two bugs fell out of writing them: <code>restart_comfyui</code> was reporting success even when the restart failed, and the litegraph→API converter dropped connections that passed through Reroute nodes instead of resolving them. Both are the kind of thing that only shows up when you run the tool and read what it returns, not when you eyeball the code.</p>
<p>loop_report also landed: a finished run renders to one self-contained HTML page — every pass, what moved, what got kept or reverted — so the loop leaves a trail you can read after the fact.</p>]]></description>
  </item>
  <item>
    <title>Plate to HDRI: a real 360° IBL from one photo, with an emitter gate that knows what glows</title>
    <link>https://alienrobot.com/blog.html#2026-07-03-plate-to-hdri-ibl</link>
    <guid isPermaLink="false">alienrobot-blog-2026-07-03-plate-to-hdri-ibl</guid>
    <pubDate>Fri, 03 Jul 2026 12:00:00 GMT</pubDate>
    <category>vfx</category>
    <category>hdri</category>
    <category>hunyuanworld</category>
    <category>comfyui</category>
    <description><![CDATA[<p>A single plate becomes a scene-linear 360° HDRI you can light a shot with — that&#x27;s the whole job of the env-to-hdri stage in my VFX pipeline. This is the real version of the thing I relabeled a few days ago: the drag-in ComfyUI graph fakes a latlong and leaves a faint seam, this one builds the actual sphere and heals it. I wrote the whole method up publicly, failures and all — <a href="https://github.com/huikku/comfyui-examples/tree/main/examples/10-env-to-hdri">comfyui-examples/10-env-to-hdri</a>.</p>
<p><img src="https://alienrobot.com/blog/hdri-forest-vs-input.webp" alt="Input backplate vs the HunyuanWorld true-360 equirect — one forest plate extrapolated to a full seamless sphere"></p>
<p>The pipeline is four models in a trench coat. HunyuanWorld-1.0 does the true-360 extrapolation — one plate in, a 1920×960 equirectangular panorama out — running as a subprocess in its own venv (torch 2.5 / diffusers 0.34) so its FLUX-Fill dependency never collides with the rest of the stack. A ComfyUI pass then wrap-pads and upscales it 2× (4x-UltraSharp + TiledDiffusion, cropped back), and a second ComfyUI pass heals the wrap seam by rolling the pano 50%, inpainting the centre strip, and rolling it back. The result lands at 3840×1920. A BLIP caption of the plate steers the extrapolation when no prompt is given, so the invented half of the sphere stays on-theme instead of wandering off into a different scene.</p>
<p>The interesting part is the light, not the picture. A panorama is just pixels; an HDRI has to know what actually emits. Naive exposure lifts every bright region at once and the whole frame glows — white flowers, a pale wall, an overcast sky — so the scene ends up lit by a daisy. An emitter gate (DINO + SegFormer) classifies the scene first and only lets real sources — sky, sun, windows, practicals — cross 1.0. It treats interiors and exteriors differently, and it deliberately doesn&#x27;t blow out an overcast sky into a fake sun.</p>
<p>The output is more than one file. The stage writes a scene-linear EXR, an LDR preview, and a six-face cube map with a PolyHaven-style cross — in both EXR and Radiance .hdr, so it drops into UE5 or GIMP as easily as Nuke or Houdini. An optional first step removes people: stills go through FLUX-Fill, moving clips through VOID clean-plate, so the light of the location stays but the crew doesn&#x27;t.</p>
<p>The genuinely hard part was memory. FLUX-Fill wants ~34GB of RAM and won&#x27;t share a GPU politely with a loaded ComfyUI, so the orchestration restarts ComfyUI lean right before the FLUX step and frees VRAM around it. A 128GB unified box eases that pressure, though the aarch64 model stack has to be built first. None of that is glamorous, and all of it is the gap between a pipeline that survives a real shot and a demo that only runs on the developer&#x27;s machine.</p>
<p>The whole thing sits behind a modal in my VFX Tools front end — auto-caption the plate, adjust the prompt, submit — because an artist should get an IBL back, not a pipeline to operate.</p>]]></description>
  </item>
  <item>
    <title>Five production trackers, one contract — a tracker-MCP quintet and a hub</title>
    <link>https://alienrobot.com/blog.html#2026-06-21-tracker-mcp-hub</link>
    <guid isPermaLink="false">alienrobot-blog-2026-06-21-tracker-mcp-hub</guid>
    <pubDate>Sun, 21 Jun 2026 12:00:00 GMT</pubDate>
    <category>mcp</category>
    <category>vfx</category>
    <category>production-tracking</category>
    <category>agentic-ai</category>
    <description><![CDATA[<p>Production trackers don&#x27;t talk to each other. ShotGrid, ftrack, Kitsu, AYON and NIM each hold the same kind of data — projects, shots, assets, tasks, statuses, casting — behind five incompatible APIs, and moving a show from one to another is a manual, lossy slog. I built an MCP for each, and a hub on top. <a href="https://github.com/huikku/tracker-mcp-hub">tracker-mcp-hub</a>.</p>
<p>The trick is one shared shape. Every tracker MCP emits the same normalized snapshot — <code>project_summary</code> — so an agent reads a project out of ShotGrid and recreates it in Kitsu without knowing either SDK. Five standalone servers, published and credited separately, all speaking one contract. A sixth tracker is just one more MCP that emits the same shape; everything downstream then works on it for free.</p>
<p><img src="https://alienrobot.com/blog/tracker-mcp-hub-hero.webp" alt="One contract across every production tracker — each tracker emits project_summary, the hub does verify / migrate / audit / snapshot / rollup"></p>
<p>The hub is where that uniform contract pays off. It does five things no single tracker can: verify (diff two snapshots), audit (one source of truth against many mirrors), rollup (totals across every production), snapshot (a portable versioned archive), and migrate (an orchestrated read → write → verify that ends with proof). Most of it is pure — verify, audit, rollup and snapshot never touch a tracker SDK, they just operate on the normalized JSON. Only migrate does any writing.</p>
<p>The hub found real drift on its own the first time I aimed it at one project copied into all three original trackers. The ftrack copy came back short 8 tasks, carrying 615 status mismatches and 357 casting mismatches, plus name-collision assets ftrack had silently created. Every one of those is a documented cross-tracker incompatibility, surfaced by diffing snapshots instead of by hand. And an orchestrated migrate of a slice ended with VERIFY: PASS — every count matched.</p>
<p>Write safety was non-negotiable, since these point at real production databases. Every create, update, delete and status change takes a two-level dry run — a client-side plan, or a preflight that resolves references against live data, validates statuses against the schema, and returns a before→after diff while writing nothing. The whole thing is v0.1 and honest about its edges: the migrate reference copies structure, statuses and casting, and reports any media gap rather than pretending to move the heavy publish bytes.</p>]]></description>
  </item>
</channel>
</rss>
