Most of what I make is pictures. Some of what I make is the systems and machinery that make the pictures. Lately I have been finding myself digging into these systems, to support and enable teams of artists in elevating their work.
This page describes three problems and what I built to solve them.
01
Two ways to protect a product from a generative model
Problem
Generative models will happily redraw your product. With on-brand work, the product is the one thing that cannot change. The geometry is approved, the finish is specified, and a hallucinated handle or logo becomes a retouching job or a reshoot. The question is how you let a model rebuild an environment without letting it modify the thing sitting in the middle of it.
First pass
The render already knows which pixels are the product. An object ID pass is a perfect mask: free, and exact to the pixel. I built ComfyUI graphs that take the render passes alongside the beauty, derive the mask from object IDs, and let diffusion regenerate everything outside the locked geometry. The product isn’t protected by a prompt or by the model’s good behavior. It is never touched.


the object ID pass And the source render

Everything outside the mask regenerates. The raking warm light never reaches the panel or the bezel. small items generated in the front are clipped.
Where it broke
Masked inpainting fills a hole and matches the edges. It cannot modify anything outside the mask. So when the model invents an environment with new light, it has to reconcile that light against a product it is forbidden to change. The product keeps the lighting from the original render, the environment gets lighting from the model, and the seam is wherever the two disagree. It reads as a composite. That isn’t a weak model. The task as posed makes correct integration impossible the moment the new environment implies a different key.
Second pass
I built a Nuke node that sends the whole frame out for regeneration with nothing masked, and gets back a fully relit scene, product included. It then blurs what was sent and what came back, and divides one by the other. The blur discards high frequency, which is typically where any geometric drift in the returned image lives. What survives the division is the low-frequency lighting and color change.
That ratio multiplies onto the original full-resolution scene-linear plate. The product keeps its approved geometry, because that geometry never left the plate. It receives the new lighting, as the ratio carries it. For multi-pass renders there’s a version that applies a ratio per lighting pass, and rebuilds the beauty from them.


Only the model’s reading of the light comes back, not its pixels
Why
The protection moved from a hard defined space to frequency. Masking defends a region, and the ratio defends detail.
Both are still in use. If a brand or a legal position requires that the delivered product is literally the approved render with nothing done to it, masking wins by definition and appearance doesn’t enter into it. If the job is an environment the product has to genuinely sit in, the ratio wins.
02
3dsMAX Assistant using MCP (a simple example)

A proposed change, previewed, then applied
Problem
An artist opening a shot needs answers that live in three separate places: what is actually in the scene, which SKU that geometry is and whether it is the current version, and what the job ticket asked for. Reconciling those by hand is slow, and the failures are quiet ones. Nothing throws an error when a camera is framed on superseded geometry. It surfaces at review.
Approach
An MCP server exposes Max’s scene operations as tools, a bridge runs them on Max’s main thread, and a docked panel puts it in front of the artist. The same panel reaches the n8n toolset the studio already runs, so the assistant can query the asset system and the job ticket as readily as it reads the viewport. The scene, the SKU database and the ticket become one place to ask.
in practice
Add a three-quarter-left camera for the speaker. The assistant doesn’t interpret the word speaker. It asks the asset system which SKU that geometry is bound to, resolves the full assembly (a hundred and seventy-nine objects) measures its bounding radius, and solves for where a 50mm lens has to sit to frame that at ten degrees of elevation. Then it proposes the result and waits.
Why
A model guessing at a three-quarter camera gives you plausible coordinates. A model holding a tool that measures gives you correct ones. Every number in that proposal came from the scene or from the database. None of it came from the model’s sense of where a camera usually goes. Of course, speed is the obvious benefit but predictability is the real payoff.
03
Scene assembly from a ticket

Thirty seconds, unattended, with a report
Problem
Starting a new project or scene can be repetitive. Folders, units, color management, product merges from the asset library, texture paths, color charts, ground planes, lighting rigs, a camera per shot, render settings. None of it is creative. All of it is easy to get wrong, and a wrong SKU or color setting surfaces at review.
Approach
A runner that reads a structured plan derived from the project ticket and builds the entire scene unattended. Roughly thirty seconds, start to finish. Studio standards live in a config file or a sheet rather than in code, so changing a default is a simple edit or update.
Why
Automation pointed at the part of the job that nobody is excited about. The artist receives a notification on slack, opens a correct scene and starts working.