Articulate.
Articulate Lab · Roadmap

From Blender to a configurator anyone can drive

The trailer exists as a parametric Blender model with 310 named, exportable parts. This is the route from that file to a browser configurator a customer can turn, recolour, open and specify — and, if the visuals justify it, on into Unreal. Written 2026-08-15, at the end of Day 2.

How others do it

There are only three families of vehicle configurator in the market. Knowing which one you are looking at tells you the entire build cost.

FamilyHow it worksTell-taleCost
Real-time WebGL
three.js · babylon.js · React Three Fiber
One glTF file. Meshes toggled and materials swapped live in the browser. Free orbit, instant option changes, 5–40 MB download. Low — static hosting
Pre-rendered turntable Thousands of baked stills swapped like a flipbook. Fixed camera steps, no free orbit, options snap with a lag. Medium — render farm time
Pixel streaming
Unreal on a cloud GPU
A video stream of a remote render. Photoreal, but video-compression artefacts and drag latency. High — GPU per concurrent user

Every van and 4×4 builder at our scale — including the Off Highway Van configurator — is family one. That is what we should build. Open reference implementations worth reading: 4x4builder and automotive-configurator, both three.js + glTF.

Export: what leaves Blender

glTF 2.0 binary (.glb) is the only sane web format. It carries meshes, PBR materials, the node hierarchy and animation clips in one file. Non-negotiables before any export ships:

RuleWhy
Exclude Reference_CC-NC/The tow car is non-commercial licensed. One checkbox — that is precisely why the collection exists. This lab site is a personal project, so the CC-NC-derived wheels are kept; the car itself is not exported.
Bake the procedural chequer plateglTF has no procedural nodes. Unbaked, the floor and roof export flat.
Draco or Meshopt compression60–80% off the wire size. Measured: the whole trailer is 2.91 MB Draco-compressed, textures included.
Attribution block for CC-BY partsLeaf spring, couplers, towball, jockeys, awning. Required on any commercial surface.
Replace the jerrycan before launchSketchfab “Free Standard” permits commercial use but not redistribution as a standalone asset. A .glb served to a browser is redistribution.

glTF: what it cannot carry

The rule underneath every limitation below: glTF is a delivery format, not an authoring format. It describes what to draw, not how it was built. Anything procedural, parametric or dependency-based is flattened on the way out. This is not a defect — it is the reason the whole trailer loads in under three megabytes on a phone.

Does not surviveWhyWhat you do instead
Procedural materialsNo node graph in the format — only PBR values and image textures.Bake to images. The chequer plate exported as flat grey until it was baked to colour + roughness + normal maps.
ModifiersSubdivision, array, boolean, solidify are Blender constructs.Applied at export (export_apply). Irreversible in the file — another reason the .blend is master.
Parametric historyNo concept of “this was generated from a PARAMS dict”.The .blend and build-trailer.py remain the source of truth. The .glb is a build artefact.
Constraints & driversThe Limit Rotation constraints on the doors do not export.Re-implement in application code. The door sliders on /viewer are exactly that.
Multiple UV / vertex-colour layersSupport is limited and renderer-dependent.Consolidate to one UV set before export.
Blender’s exact shadingEEVEE and Cycles are not web renderers.Accept the difference, or bake lighting. Matching the HDRI between Blender and the browser gets you most of the way.

What glTF does carry, and carries well: meshes, PBR materials, image textures, the complete node hierarchy with names, transforms and pivots, skinning, morph targets, animation clips, and Draco or Meshopt compression. That covers everything a configurator actually needs.

Two consequences, fixed rules from here

1. The .blend is the master, always. The .glb is a build artefact — regenerate it, never edit it. The same relationship as source code to a compiled binary.
2. Anything procedural must be baked before it ships. A step in the export recipe, not a thing to remember.

The alternatives, honestly

FormatKeepsLosesUse for
glTF / GLBMeshes, PBR, hierarchy, pivots, animation, compressionEverything procedural or parametricThe web. No real competitor.
USDFar more structure, material graphs, layering, referencesNo native browser supportThe bridge to Unreal and Omniverse
FBXRigs and animationMaterials, badly. Proprietary.Legacy pipelines only

What control we can give

The honest constraint first: every item below depends on naming and separation, not on modelling skill. A fused mesh cannot be toggled, recoloured or animated independently. That is the entire argument for Phase 0.

FeatureDifficultyWhat the model must have
Orbit / zoom / panFreeNothing — the camera controller does it
Change colours & finishesEasyNamed material slots, parts separated by material. We have this.
Swap variants — 3 showers, 3 cookers, upgrade hitchesEasyEach variant a named object, hidden by default. This is the linked-asset library.
Open / close doorsEasyOrigin on the hinge line + rotation limit. Already built; pivots survive glTF as node transforms.
Deploy / retract the awningMediumLegs and guys must move together — a baked animation clip, or parent the legs to the shade and drive one value.
Add / remove waterMediumA tank with a separate water object scaled on Z, or a shader with a fill-level uniform. The second looks better.
Interior walk-throughMediumThe superstructure and insulation are already modelled. Most configurators fake this. Ours could be real.
Camp Score, unlock×level logicEasyNothing from Blender — pure application code.

Unreal vs WebGL — the honest comparison

The question is not “which is better”. Unreal wins on pixels and loses on reach; WebGL wins on reach and loses on pixels. What matters is which constraint binds this product. Below, three.js is what is running today on /viewer.

 three.js / WebGLUnreal — Pixel StreamingUnreal — native build
Visual ceilingGood. PBR, IBL, real-time shadows, screen-space effects.Excellent. Lumen GI, Nanite, ray-traced reflections, volumetrics.Excellent, plus path-traced stills.
ReachAny browser, any device, a URL. Nothing to install.Any browser — but a GPU must be running for each viewer.A download and an install. Desktop or headset only.
Time to first pixel~3 MB, 1–3 s.5–20 s while a GPU session spins up — longer under load.Minutes, once.
Interaction feelLocal. Zero latency on drag.Video round-trip. Noticeable on a slow connection; artefacts on fast motion.Native.
Running costStatic hosting. Effectively free at our volume.A cloud GPU per concurrent viewer. Indicative: roughly £0.40–1.20 per streaming hour, plus idle capacity to avoid queueing.Free to run, expensive to distribute and update.
Build effortModerate — it is code.Unreal project + streaming infrastructure, autoscaling, session management.Unreal project + packaging per platform.
Analytics & e-commerceIt is a web page. Everything integrates.Needs a bridge layer between the stream and the page.Effectively isolated.
SEO / sharingIndexable, linkable, embeddable.Partially.No.
Failure modeSlower frame rate on an old phone.Queue, or no session at all, at peak.Will not run.

The fact that decides it

Unreal has no web export. HTML5 packaging was removed years ago. “Unreal in the browser” always means streaming video from a remote GPU — which is why the cost scales with viewers, not with content. A configurator whose whole job is to be opened casually by anyone who clicks a link is precisely the wrong shape for that cost curve.

Where Unreal genuinely wins for us

JobRouteEffortVerdict
Marketing stills and hero videoImport the .glb or USD, drop into a Fab environment, Lumen or the path tracerHalf a dayDo this. Cheapest path to the biggest visual jump, and it costs nothing per viewer — the output is a file.
Show stand / VR walkthroughNative packaged buildA separate projectOnly if a show is booked
Browser configuratorPixel StreamingInfrastructure + ongoing GPU spendNo — not before there is traffic that justifies it

Getting the trailer into Unreal

RouteKeepsLoses
USD — preferred from Blender 5.xHierarchy, names, material assignments, layeringSome node-graph detail
glTFGeometry, PBR, names, pivotsMaterial graph flattens further on the Unreal side
DatasmithBest fidelity from CAD/DCC sourcesNo first-class Blender exporter

Whichever route, the trailer arrives as static meshes: the door pivots must be rebuilt as Blueprint components, and materials reauthored as Unreal material instances. Budget for that — it is not a one-click import.

Recommendation

Both, for different jobs. WebGL is the product — the thing customers touch, the thing that scales to a thousand visitors for the price of one. Unreal is the camera — stills and film that make the product look like it costs what it costs. Revisit Pixel Streaming only when the configurator has traffic and the visual gap is demonstrably losing sales, not before.

The phases

Phase 0 — Hygienethe gate

Naming convention applied across all 766 objects. Collections finalised. Every configurable item promoted to a linked asset in assets/library/. Versioning discipline on every file.

Nothing downstream works without it. A model that renders beautifully but cannot be taken apart is worth nothing to a configurator.

Phase 1 — Export proofdone 2026-08-15

One .glb out of Blender — Draco-compressed, +Y up, modifiers applied, CC-NC excluded — loaded in a three.js page and published. Purpose: prove the pipeline end to end, measure the real numbers, and find what breaks before anything is built on top.

MeasuredValueReading
File size0.79 MBDraco on a 258-part model. Loads instantly even on mobile data. Headroom to spare.
Draw calls285One per part. Fine on desktop, heavy for low-end mobile — the fix is merging parts that share a material and never need to move independently. A Phase 2 job, not a problem today.
Mesh objects310Every one arrived separate and named. Zero unnamed nodes. Draw calls come in below node count because glTF instances the shared left/right wheel meshes.
Textures9Chequer plate (colour + roughness + normal), solar cells (colour + roughness + metallic), awning canvas. All baked — see below.
Materials21All named slots — alu_brushed, stainless_trim, chassis_black_gloss, rubber… each one is a configurator control.
Animations0Doors have correct pivots but no baked clips yet. Rotation is driven from application code in Phase 2.

Live and inspectable at /viewer — the part list on the right is read straight from the file.

Four bugs the export proof caught — which is the point of doing it

1. The glTF exporter writes every scene unless use_active_scene is set — a working copy of the jockey from a separate part scene silently rode along. 2. Debug collections (_inspect, 10_Cutters) export unless explicitly excluded. Both invisible in Blender; both obvious the moment you count nodes in the file. 3. Every procedural material exported flat — chequer plate, solar cells and awning canvas all arrived as plain grey slabs, because glTF carries no node graphs. All three are now baked to image textures. 4. The trailer arrived with no wheels: wheel_assy_L/R were empties filed in 03_RunningGear while all 52 of their mesh children still sat in Reference_CC-NC from the day they were copied off the tow car. The licence filter took them. Parents and children must live in the same collection.

Phase 2 — The configurator shellstarted

Already standing on /viewer: three.js, orbit, live colour swap on alu_brushed, per-door rotation sliders, part isolation, and a seaside world (PolyHaven CC0 HDRI for light, 2K backdrop, sand ground plane, real shadows). Still to come: React, one variant family (hitches) to prove the swap mechanism, and the awning as a baked clip.

This is the piece that becomes the BYOT platform.

Phase 3 — Content depthlater

The remaining variant families, awning animation, water level, Camp Score.

Volume work, not new technique. Cost scales with catalogue size, not with difficulty.

Phase 4 — Unreal, if justifieddecide later

Marketing stills and video first — half a day, no per-viewer cost. Pixel Streaming only if Phase 2 traffic proves the visual gap is costing sales.

Deciding earlier means deciding without evidence.

The real risk

It is not render quality

The risk in this project is that a beautiful model cannot be taken apart. Every hour spent on lighting before Phase 0 is complete is an hour spent on the wrong problem. Sequence: 0 → 1 → 2, and do not touch Unreal until Phase 2 is on a URL.