Building a 3D Car Scene with a Multi-Agent Pipeline

One paragraph of prompt went in. A 3D parallax sunset car scene came out — built by a five-agent pipeline running on Qwen3.8 27B, entirely local, with two geometry bugs caught before a single line of code was written.

The Prompt

Create a 3D car driving through a sunset landscape. Parallax scrolling background with multiple depth layers. Cinematic lighting. The car should look like it's moving — wheels spinning, body bobbing, road markings scrolling. Single HTML file, Three.js from CDN, no build step.

That's it. No architecture doc, no layer speeds specified, no lighting rig described. One paragraph.


The Simulation

A car driving through a sunset landscape. Seven parallax layers scroll at different speeds to sell the depth, the wheels spin, the body bobs, and the road markings stream past.

🖱️ Drag to orbit around the car • Scroll to zoom in/out • Open in new tab →


The Scene

The implementation is a single HTML file with a carefully budgeted scene graph. Below: the original pipeline output (left, static camera) and the refined version after iterative visual feedback (right, drag to orbit, scroll to zoom).

Original (pipeline output)

Refined (iterative feedback)

Refinements applied:

The scene graph:


The Refinement Loop

The pipeline gave us a car. The refinement loop gave us a good car. Each iteration: screenshot → vision agent describes what's wrong → debugger agent fixes the code → verify. No human wrote code — just pointed at screenshots and said "that's too wide" or "the glass looks like a black hole."

The vision agent (a separate model with image input) was the key tool — it described what it saw in screenshots, measured pixel positions, and confirmed fixes. The debugger agent (medium thinking) handled the code changes.


The Pipeline

This wasn't a single model call. The PI Agent Harness ran a 5-agent pipeline — each agent handling one job, coordinating through structured prompts and a shared task board. All running locally on a single RTX 3090.

Architect Planner Debugger Tester Reviewer

What Each Agent Did

  1. Architect (~6 min) — 25KB design doc: scene graph, 9 parallax layers with speed ratios, 3-light sunset rig, car geometry plan, ~31 draw call budget, 8 design decisions with rejected alternatives
  2. Planner (~10 min) — 20-step implementation plan in 5 phases. Caught 2 design bugs before any code was written (detailed below)
  3. Debugger (~27 min) — 515-line Three.js implementation. 31 draw calls, 17.8k triangles, zero JS errors
  4. Tester — manual verification: scene renders, looks 3D, car moves correctly
  5. Reviewer (~10 min) — 12-item checklist audit. Verdict: complete

The Model

Qwen3.8 27B — released the same day this was built. Running locally on a single RTX 3090 (24GB VRAM) under the PI.dev agent harness. No cloud, no API keys, no per-token costs.

The implementation agent ran at xhigh — the maximum reasoning effort level. Before writing a single line of Three.js, it worked through the wrap geometry, wheel angular velocity, and parallax speed ratios in its extended thinking trace. The 16,384-token reasoning budget (--reasoning-budget 16384) is what gave it room to verify the math before committing to code.

The template injects "Reasoning effort is set to xhigh. Please think carefully and thoroughly" into the prompt. Combined with the server-side token cap, the model gets both the instruction to think deeply AND the budget to actually do it.


Bug 1: The Two-Copy Wrap Gap

The obvious approach to infinite scrolling is two copies of a tile: one at x=0, one at x=-W. When the group shifts past -W, snap back to 0. Simple. Wrong.

The problem: at the moment of the snap, the camera's viewport spans from roughly x=-4 to x=+4 (in world units). If the tile width W is, say, 20 units, then at the snap point the region from x=W to x=W+4 has no geometry. The right edge of the screen shows a gap for one frame.

The fix is three copies: x=-W, x=0, x=+W. Now at any point during the scroll cycle, at least two copies are partially visible. The gap is mathematically impossible.

// Three-copy wrap
const W = tileWidth; // e.g. 20
group.add(tile.clone().translateX(-W));
group.add(tile);           // at x=0
group.add(tile.clone().translateX(W));

// In animation loop:
group.position.x -= speed * dt;
if (group.position.x <= -W) {
    group.position.x += W; // snap back, no gap
}

Why the planner caught this: it's a geometric proof, not a runtime error. No exception is thrown. No console warning. A tester would need to watch 30+ seconds of scrolling to notice a one-frame gap at the snap point. The planner caught it by reasoning about the viewport bounds relative to the tile positions.


Bug 2: Invisible Wheel Spin

The wheels were spinning. The code was correct. wheel.rotation.z -= speed * dt / radius. Perfect. And you couldn't see it.

Why: a CylinderGeometry is rotationally symmetric. It looks identical at 0°, 90°, 180°, 270°. Rotating it produces zero visual change. The spin was happening — invisible.

The fix: make the hub non-symmetric. A square (BoxGeometry) or cross shape breaks the rotational symmetry. Now every degree of rotation is visible.

// Bad: cylindrical hub — spin invisible
const hub = new THREE.Mesh(
    new THREE.CylinderGeometry(0.12, 0.12, 0.08, 16),
    hubMaterial
);

// Good: square hub — spin visible
const hub = new THREE.Mesh(
    new THREE.BoxGeometry(0.2, 0.2, 0.08),
    hubMaterial
);

Why the planner caught this: it's a perceptual bug, not a code error. The rotation IS happening. The math IS correct. But the human eye can't perceive it. Only by reasoning about what the viewer will actually see (not what the code does) did the planner flag it.


The Skill

After the pipeline completed, the lessons were extracted into a reusable skill reference (9.5KB): six pitfalls, a verification checklist, a color palette, and the three-copy wrap pattern. Next time a 3D scene is requested, the agent reads this skill and skips the mistakes we hit.

The pipeline's output isn't just the car. It's the knowledge.


The Numbers

515 → 771
Lines (original → refined)
31 → 52
Draw calls (original → refined)
5
Agents
53
Minutes (initial pipeline)
2
Bugs caught pre-code
0
API costs

Built with Three.js r185 from CDN. Single HTML file. No build step. Runs in any modern browser. Qwen3.8 27B on a single RTX 3090.


Why It Matters

The planner's value isn't in writing code. It's in catching the bugs that no runtime test would find — the geometric gap that only appears for one frame, the rotation that's happening but invisible. These are reasoning bugs, not execution bugs. They require understanding the viewer's perspective, not just the code's logic.

Qwen3.8 27B, released today, running locally on a 3090, building a 3D scene in 53 minutes with zero cloud costs. The iterative refinement that followed (screenshot → measure → fix → verify) brought it from "recognisable car" to "looks like a car". The harness that made this possible is the PI Agent Harness.

The harness is documented in the PI Agent Harness bundle.