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.
| Family | How it works | Tell-tale | Cost |
|---|---|---|---|
| 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:
| Rule | Why |
|---|---|
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 plate | glTF has no procedural nodes. Unbaked, the floor and roof export flat. |
| Draco or Meshopt compression | 60–80% off the wire size. Measured: the whole trailer is 2.91 MB Draco-compressed, textures included. |
| Attribution block for CC-BY parts | Leaf spring, couplers, towball, jockeys, awning. Required on any commercial surface. |
| Replace the jerrycan before launch | Sketchfab “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 survive | Why | What you do instead |
|---|---|---|
| Procedural materials | No 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. |
| Modifiers | Subdivision, array, boolean, solidify are Blender constructs. | Applied at export (export_apply). Irreversible in the file — another reason the .blend is master. |
| Parametric history | No 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 & drivers | The 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 layers | Support is limited and renderer-dependent. | Consolidate to one UV set before export. |
| Blender’s exact shading | EEVEE 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
| Format | Keeps | Loses | Use for |
|---|---|---|---|
| glTF / GLB | Meshes, PBR, hierarchy, pivots, animation, compression | Everything procedural or parametric | The web. No real competitor. |
| USD | Far more structure, material graphs, layering, references | No native browser support | The bridge to Unreal and Omniverse |
| FBX | Rigs and animation | Materials, 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.
| Feature | Difficulty | What the model must have |
|---|---|---|
| Orbit / zoom / pan | Free | Nothing — the camera controller does it |
| Change colours & finishes | Easy | Named material slots, parts separated by material. We have this. |
| Swap variants — 3 showers, 3 cookers, upgrade hitches | Easy | Each variant a named object, hidden by default. This is the linked-asset library. |
| Open / close doors | Easy | Origin on the hinge line + rotation limit. Already built; pivots survive glTF as node transforms. |
| Deploy / retract the awning | Medium | Legs and guys must move together — a baked animation clip, or parent the legs to the shade and drive one value. |
| Add / remove water | Medium | A tank with a separate water object scaled on Z, or a shader with a fill-level uniform. The second looks better. |
| Interior walk-through | Medium | The superstructure and insulation are already modelled. Most configurators fake this. Ours could be real. |
| Camp Score, unlock×level logic | Easy | Nothing 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 / WebGL | Unreal — Pixel Streaming | Unreal — native build | |
|---|---|---|---|
| Visual ceiling | Good. PBR, IBL, real-time shadows, screen-space effects. | Excellent. Lumen GI, Nanite, ray-traced reflections, volumetrics. | Excellent, plus path-traced stills. |
| Reach | Any 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 feel | Local. Zero latency on drag. | Video round-trip. Noticeable on a slow connection; artefacts on fast motion. | Native. |
| Running cost | Static 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 effort | Moderate — it is code. | Unreal project + streaming infrastructure, autoscaling, session management. | Unreal project + packaging per platform. |
| Analytics & e-commerce | It is a web page. Everything integrates. | Needs a bridge layer between the stream and the page. | Effectively isolated. |
| SEO / sharing | Indexable, linkable, embeddable. | Partially. | No. |
| Failure mode | Slower 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
| Job | Route | Effort | Verdict |
|---|---|---|---|
| Marketing stills and hero video | Import the .glb or USD, drop into a Fab environment, Lumen or the path tracer | Half a day | Do this. Cheapest path to the biggest visual jump, and it costs nothing per viewer — the output is a file. |
| Show stand / VR walkthrough | Native packaged build | A separate project | Only if a show is booked |
| Browser configurator | Pixel Streaming | Infrastructure + ongoing GPU spend | No — not before there is traffic that justifies it |
Getting the trailer into Unreal
| Route | Keeps | Loses |
|---|---|---|
| USD — preferred from Blender 5.x | Hierarchy, names, material assignments, layering | Some node-graph detail |
| glTF | Geometry, PBR, names, pivots | Material graph flattens further on the Unreal side |
| Datasmith | Best fidelity from CAD/DCC sources | No 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.
| Measured | Value | Reading |
|---|---|---|
| File size | 0.79 MB | Draco on a 258-part model. Loads instantly even on mobile data. Headroom to spare. |
| Draw calls | 285 | One 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 objects | 310 | Every one arrived separate and named. Zero unnamed nodes. Draw calls come in below node count because glTF instances the shared left/right wheel meshes. |
| Textures | 9 | Chequer plate (colour + roughness + normal), solar cells (colour + roughness + metallic), awning canvas. All baked — see below. |
| Materials | 21 | All named slots — alu_brushed, stainless_trim, chassis_black_gloss, rubber… each one is a configurator control. |
| Animations | 0 | Doors 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.