| name | blender-web-3d |
| description | Work with Blender from Claude — headless CLI scripting or the Blender MCP — to build, modify, render, and publish any 3D model, including shipping it online as an interactive Three.js/Next.js web app (GLB export with Draco+WebP, orbit viewer, bloom, animated parts, Vercel deploy). Use this whenever the user wants to create, improve, fix, render, or iterate on any Blender model or scene — phrases like "improve the model", "fix this part", "render this", "make a 3D web demo", "export to glTF/GLB", "use blender", "the model looks wrong in the browser", "optimize the 3D scene", or any screenshot-driven feedback loop on a 3D asset. Also use it when debugging a Three.js viewer that renders black, glows wrong, or has detached/floating parts, and when deciding between Blender MCP and headless CLI. Proven on the Aurora colony-ship project. |
| license | MIT |
| compatibility | Requires Blender 4.x/5.x on PATH. Node.js for the web viewer. Optional BlenderMCP addon + uvx blender-mcp for live GUI sessions. |
| metadata | {"author":"czlonkowski","version":"1.0"} |
Blender → Web 3D publishing pipeline
Build detailed 3D models with scripted, reproducible Blender edits, export them
as compressed GLB, and serve them in a Next.js/Three.js viewer. The whole loop
runs headless — no Blender GUI needed — so every change is a reviewable script
and every state is a versioned file.
Every pattern here is project-agnostic — it applies to any model (product
viz, architecture, vehicles, characters, props). The patterns were extracted
from a real shipped project (the Aurora colony ship: a ~2 km vessel with two
counter-rotating habitat rings, ~30 versioned edit scripts, deployed on
Vercel). A typical project layout:
my-project/
├── app/ # Next.js + Three.js viewer (one client component)
├── public/models/ # versioned runtime GLBs (model-vNNN.glb)
├── public/draco/ # Draco decoder files
├── scripts/ # versioned Blender edit scripts + export pipeline
└── ../blend-output/ # versioned .blend chain + textures + beauty renders
Two ways to drive Blender: MCP vs headless CLI
Both exist on this machine; choose per task.
- Headless CLI (
blender --background file.blend --python script.py) —
the default for this skill. Reproducible, versionable, runs without a GUI,
works in CI. All the pipeline patterns below assume it.
- Blender MCP — the community BlenderMCP addon (
blender_mcp_addon.py,
installed in Blender's addons; stock v1.2 from the ahujasid/blender-mcp
project, not modified) plus its paired MCP server (uvx blender-mcp,
registered with claude mcp add blender -- uvx blender-mcp when wanted).
The addon runs a socket server only inside a live GUI session (the user
opens Blender, sidebar → "Connect to MCP server"); in --background mode it
prints a warning and stays inert. Use MCP when the user is watching the
viewport and wants live iteration, viewport screenshots, or quick
interactive queries.
- Write scripts that work in both modes: guard on
bpy.data.filepath
(not GUI state), avoid operators needing a 3D-view context (convert text
via bpy.data.meshes.new_from_object(obj.evaluated_get(depsgraph))), and
keep everything idempotent — then the same script runs via CLI or pasted
through MCP's execute-code tool. Docstrings saying "run in the GUI" usually
just mean the file-path guard must match; headless still works.
The iteration loop (one model change, end to end)
- Copy forward:
cp <previous>.blend <next-version>.blend — never edit a
previous version in place. One version per meaningful change.
- Write a versioned edit script (
scripts/blender_<change>_vNNN.py)
following the managed-script pattern → read
references/blender-scripting.md before writing it.
- Run headless:
blender --background <blend> --python <script>. The
script validates itself and saves.
- Verify with renders: headless EEVEE renders from 2-4 camera angles
(recipe in
references/blender-scripting.md). Look at them — geometry bugs
are obvious in pictures and invisible in logs.
- Export: bump the export-pipeline constants to the new version, run the
raw + runtime GLB exports →
references/export-pipeline.md.
- Wire the app: copy runtime GLB into
public/models/, bump the model
path in the viewer component, update README asset notes.
- Verify in the browser, then deploy (
npx vercel deploy --prod --yes
from the app directory — the user may need to run this themselves if the
permission classifier blocks it).
Keep every version of scripts and blends. The chain is the project's history
and lets any state be rebuilt or bisected.
Reference files — read before the relevant phase
references/blender-scripting.md — the managed-script pattern (guards,
markers, validation), bmesh geometry construction, headless verification
renders, BVH cleanup/reseating of orphaned parts, and draw-call
consolidation (with the animated-ancestor rule). Read before writing any
Blender script.
references/export-pipeline.md — glTF/GLB export settings (Draco, WebP,
transmission), what needs baking vs what exports natively, and the export
gotchas (drivers, collection instances, normal-map chains). Read before
exporting or when the GLB looks wrong.
references/threejs-viewer.md — the viewer app: loading, driving rotations
in JS, postprocessing with the mandatory NaN-scrub pass, light strobes,
performance knobs, the occluded-window RAF trap, and the debug-frame hook.
Read before touching the web app or debugging rendering.
Design lessons that shape good results
- Enclosed volumes beat skeletons. Thin rods, hoops, and trusses with
nothing behind them read as "cage" from any distance. Structures read as
solid when they enclose a lit volume: continuous hull bands, glazed surfaces
with visible chunky mullions (not hairline rods), and interior content
(terraces, plants, lights) visible through glass. Glass needs presence —
alpha ≈ 0.45 and a slight emissive tint, not alpha 0.2.
- Attach everything. Floating greebles (caps, markers, rings) read as
bugs. When a pass removes geometry, sweep for now-orphaned small parts that
used to sit on it (BVH proximity test — see blender-scripting reference).
- Scale detail to the camera. At kilometre scale, 2 m mullions every 20 m
read correctly; 0.3 m rods disappear or alias.
- Give each zone a light signature (e.g. warm amber residential vs green
agricultural glow) — it makes the model legible at a glance and gives bloom
something meaningful to do.
When the user reports a visual bug from a screenshot
Locate the object first, guess never. Headless probe scripts that dump object
names, world-space bounds, radii, and angular positions (grouped by name
pattern) identify what the user photographed in one run. Then fix by script,
re-render the same view, and compare. The screenshot's background often
identifies which assembly you're looking at (e.g. a ring interior visible
behind the hub pinpoints the camera position).