Images,
and the systems
that make them.
Creative technologist, bridging creative and engineering. I design, build and consult on AI workflows and systems for studios, agencies, production companies and image‑led brands.











Portrait Performance System
A portrait system built as ten custom ComfyUI nodes. A person is held as a written identity specification, read from a reference photograph by a language model or authored by selection with no photograph. The photograph never reaches the image model. Identity, expression and pose are then addressed separately.
Expression is authored in FACS, the coding system that numbers each movement a face can make, through a vocabulary that turns a word into those numbers. To turn the head, a 3D head is fitted to the portrait and the description is derived from the geometry actually rendered, so the words and the map cannot disagree.

The canvas, stage by stage
A language model reads the reference photograph and writes an identity specification. It records identity only: expression and head pose are assessed, because they decide which asymmetries may be recorded, but never written down. The same document can be authored by selection in the Identity Builder, with no photograph.
The person as a document
The photograph never reaches the image model. It is read, and what was read is what gets rendered.
The specification is what gets edited. Blocking a tattoo deletes the tattoo from the document; changing the backdrop changes a value in a field. A second model resolves what is left, and only a render document projected from that result reaches the image model.
The reference and the result below are shown as they came out: no field of the specification was edited by hand. Where the result drifts, in the skin or the hair for example, the field can be edited and the portrait rendered again.


One identity, four expressions
EMFACS gives anger one row: 4 + 5 + 7 + 23. The vocabulary holds 31 words for it, skeptical among them. A word picks a starting point; which muscles fire, how hard, on which side, and where the eyes and head go are separate dials. With no units set, the compiler returns its fixed neutral clause byte for byte, and a test enforces it.





a at rest no units b curious 1B + 2B + 5A c amused 6C + 12C + 7B d skeptical 4C + 14C on one side e ashamed 1B + 15B A trace · B slightly · C markedly
One expression, two identities
An expression block names muscles and how hard they work, never a face, so the same block applies to any identity. Both portraits were re-expressed from the same five blocks.


The head solved at three angles
As the head turns away from the camera, the system shortens the description. The image model follows the text over the geometry map, so describing the eyes of a head that faces away turns it back to the camera. To set how much to cut, 24 action units are measured against neutral at every ten degrees of the turn.

0° 40° 90° 140° inner brow raise 1 ● ● ○ ○ jaw drop 26 ● ● ● ● at strength C, markedly
Ten identities at neutral
Every cell is the same rig at rest — neutral, frontal, evenly lit, the same distance. Nothing varies across a row, because the anchor is the document before any world field has been filled in. What differs between them was written, not directed.
Ten nodes, three groups
| no. | node | what it does | stage |
|---|---|---|---|
| 01 | Identity builder | Authors an identity specification by selection, or loads one and changes a field. | 01 · 04 |
| 02 | Compose input | Joins specification, render choices and expression into the document the composer reads. | 02 |
| 03 | Extract sentence | Passes on only what the renderer may see: the composed sentence, or a render document. | 02 · 04 |
| 04 | Sheet views | Splits a multi-view character sheet into its named views for the stages that follow. | optional |
| 05 | Expression studio | One authoring surface: 146 emotion words, 57 presets, eight action-unit slots, head, gaze, containment. | 03 · 05 |
| 06 | Apply expression | Re-expresses a resolved specification without another language-model round trip. | optional |
| 07 | Expression compile | One expression block in, anatomical prose out. Deterministic, and adapted to what is visible. | 05 |
| 08 | Ear points | Marks the top and bottom of one ear on the image, giving the fit a measured ear extent. | 05 |
| 09 | Identity fit | Fits a 3D head to the portrait, posed with the block’s expression. Emits the map and what it measured. | 05 |
| 10 | Prompt assemble | Builds the prompt from that measurement: map contract, view lock, expression, final instruction. | 05 |
Limits and provenance
The likeness is similar rather than exact, and the description is allowed to say that an expression cannot be read from an angle. Both are deliberate: the description states what the view supports and no more.
The head is Google Research’s GNM and the landmarks come from MediaPipe. GNM was trained on binary gender categories and four broad demographic groups, and the identity builder inherits that limit.
The nodes were briefed rather than written. Comfy Bridge, an MCP for local ComfyUI, built, tested and deployed them.
