Building a Four-Agent 3D Production Pipeline in Blender
Rendering a single product shot in Blender is a craft problem. Rendering hundreds of them. Across multiple models, in dozens of upholstery colorways, with consistent scale, lighting, and framing — is a systems problem. The failure modes are different, and the tools have to be different too.
This case study walks through a four-agent production pipeline I built on top of BlenderMCP to solve the systems version of that problem. The architecture separates one-time setup from repeatable production, bakes quality control into the loop, and enforces the one non-negotiable constraint of shared-instance Blender: sequential execution.
The Problem
Product 3D renders have two kinds of work hiding inside them. The first kind is configuration — mapping every mesh in an OBJ file to the right material, figuring out which faces are upholstery versus metal versus mattress versus legs. You do this once per model, and then you never want to think about it again. The second kind is production — loading the model, scaling it, unwrapping it, lighting it, and rendering the shots. You do this over and over, and every step has to be identical or the output drifts.
When those two kinds of work live in the same script, every render becomes a re-configuration exercise. Mesh assignments get re-derived, scale decisions get re-argued, and small inconsistencies compound across a catalog. The fix is to separate them architecturally, not just procedurally.
The Architecture
The pipeline is four agents operating in sequence, each with a narrow job and a clean handoff.
1. 3d-model-config — One-Time Setup
Before any model can be rendered, it needs a config file: a mapping of every mesh in the OBJ to the right material category. The 3d-model-config agent handles this interactively. You trigger it with start 3d-model-config session, and it either picks up a pre-loaded brief from its inbox or runs a short wizard asking four questions — flag type (NEST, LEVEL, HYBRID), which OBJ file, width in inches, and task ID.
From there, it loads the model in Blender and walks through each mesh zone with you, confirming assignments as it goes. The output is a <model>-config.md written to its outbox. That file is permanent. Every future render of that model reuses it, and the model never gets re-configured.
2. blender-3d-specialist — The Production Workhorse
This is where the actual rendering happens. The agent reads YAML render briefs from teams/blender-team/inbox/ and processes them one at a time.
The first thing it does on every brief is check for a config file. If there isn’t one, it writes a config request to the 3d-model-config inbox, drops a BLOCKED notice in its own outbox, and stops. It refuses to guess. This is the single most important behavior in the whole pipeline — it’s what makes the two-agent separation work in practice instead of just on paper.
If the config exists, the agent runs a strict sequence:
- Opens a fresh Blender scene
- Imports the OBJ and scales it to real-world dimensions using the width from the brief
- Re-unwraps all upholstery meshes with Cube Projection so fabric scale is physically accurate
- Applies a PBR fabric material from the Seamless Upholstery library — the full 5-map treatment (color, roughness, normal, height, AO) — or falls back to a single-image swatch when a full set isn’t available
- Applies config-driven material overrides for legs, metal parts, and mattresses
- Builds a 4-point studio lighting rig and backdrop
- Renders each shot individually at 2560×1440 in Cycles with 512 samples
- Saves the
.blendfile, writes a manifest, and sends a QA notification
Every shot is one tool call. Nothing is batched. The reason for that shows up in the hard rule at the bottom of this post.
There’s a second mode: if the brief includes upholstery_sweep: true, the agent iterates through the entire Seamless library, producing one hero shot per colorway per model configuration. Before a sweep starts, four guardrails run — a scale assertion, an isolation check, a camera height check, and a test render gate — because a failed sweep wastes hours, not minutes.
3. render-qa — The Automated Gatekeeper
Once the blender agent writes its QA notification, render-qa picks it up and checks every output PNG against four criteria: framing, fill percentage, file size, and transparency. On PASS, it moves the renders to the final output directory and the blender agent marks the brief DONE_. On FAIL, it writes a failure report back to the blender inbox with specific fix instructions, and the blender agent retries — up to three attempts before escalation.
The important thing here is that QA is not a human checkpoint. Human review is the last mile, not the first. By the time anything hits my eyes, it’s already passed the mechanical checks, which means review attention gets spent on the judgment calls rather than on catching cropped feet and blown-out backdrops.
4. The PostToolUse Hook — No Manual Trigger
When a new render brief lands in teams/blender-team/inbox/, a PostToolUse Write hook fires automatically and re-wakes the session, surfacing the brief for immediate processing. I don’t have to start the agent, poll the inbox, or remember anything. Writing a brief is the trigger.
This is the small piece that makes the whole thing feel like a system instead of a toolbox.
The One Hard Rule
One render at a time, always sequential.
BlenderMCP uses a single shared Blender instance. Parallel agents corrupt renders without exception — meshes from one job bleeding into another, materials getting reassigned mid-bake, output files colliding. Every architectural choice above is downstream of this constraint: the single-shot tool calls, the agent-per-job separation, the inbox-driven handoffs. The system is sequential by design because the substrate demands it, and pretending otherwise produces garbage outputs very quickly.
What This Unlocks
Separating configuration from production means a new model costs one config session and then becomes infinitely reusable. Upholstery sweeps across the full Seamless library run unattended. QA failures produce specific, actionable fix instructions instead of vague “something’s off” pings. And the whole thing runs from a brief file — the interface is a YAML document, not a GUI.
The architecture generalizes. Any production pipeline with a one-time configuration step, a repeatable execution step, an automated quality gate, and a shared-instance constraint can be modeled this way. The specifics change; the shape holds.