.vfx is a simulation interchange format and playback toolchain: simulations authored in Houdini, Blender, Maya, 3ds Max or EmberGen, played back natively in Unreal Engine — geometry, particles, per-piece data and volumes, verified numerically exact against the source simulation.
60×
smaller than alembic, measured
2.6
ms to apply 54,770 pieces
20
bytes per piece per frame
00
position error — bit-exact
the problem
what the engine draws is what the sim computed
Vertices are the wrong currency.
Film and virtual production increasingly review DCC-simulated destruction inside a real-time engine. General-purpose interchange stores that animation as deformed vertices, every frame — on one production landslide element, 39.4 GB of Alembic per delivered version, too heavy to scrub and blind to piece identity.
But rigid pieces don't need their vertices shipped every frame — their motion is one transform per piece. .vfx stores the render geometry once and streams motion as twenty bytes per piece per frame. The same element became 0.66 GB, a measured 60× reduction, while the simulation itself grew from 18,000 to 54,770 pieces.
the field
delivery routes evaluated · jul–aug 2026
Nine routes, no fit.
Before committing to building we evaluated every current route for high-piece-count rigid playback in Unreal. Each fails on size, fidelity, piece identity or platform — the formats, not the renderer, are the binding constraint.
routewhat it isassessment for this workload
Alembic → GeometryCache
Per-vertex positions, every frame
Proven; carried the element until now. 39.4 GB per version at ~987k vertices × 500 frames, RAM-bound CPU decode at playback, no piece identity. Cost scales with vertices × frames.
USD
Scene interchange
Imports into the same GeometryCache runtime as Alembic in current Unreal, so it inherits the same cost profile. No volume support.
Vertex Animation Textures
Motion baked to textures
Correct tool for topology-changing surfaces; rigid mode is bounded by texture limits (~131k pieces at 500 frames), requires Nanite off, and Lumen ignores its world-position offset.
Bone-per-piece FBX
Pieces as skeleton joints
Exact and Sequencer-friendly at hundreds to low thousands of pieces; impractical at tens of thousands.
Chaos (in-engine)
Simulate and cache inside Unreal
Not an interchange path: it replays its own solver, not an externally simulated and approved result.
Houdini Niagara point caches
Point data into particle systems
Good for debris and spray layers; points rather than paired render geometry, with ~1M CPU / 2M GPU caps.
ZibraGDS
GPU-compressed geometry sequences
The closest current product: roughly 10× smaller than GeometryCache in independent tests, but Windows/D3D12 only, lossy quantised attributes, piece identity lost, and a confirmed format break at 1.0.
ZibraVDB
Neural-compressed volume playback
Volumes only; its advertised ~100× ratios are lossy approximations of smoke and fire, not comparable to geometry caching.
Houdini Engine
Live cook inside Unreal
A runtime dependency rather than a playback format; current versions cook static geometry only.
what we built
a format and its whole toolchain
Specification to playback.
A chunked container format with typed streams, exporters for plugin-capable DCCs, and a native Unreal Engine playback plugin. Readers are deliberately small, unknown streams skip safely, and files written today stay readable by future tools — it is an interchange format first, not a single engine integration.
The design principle is determinism: positions reproduce bit-exact from the DCC and rotations within 0.047 degrees, enforced by an automated four-layer test suite run on every change — round trips, golden exporter comparisons, a hostile-input corpus and engine-side numerical agreement.
In production, a frame of all 54,770 pieces applies in 2.6 ms and full shots scrub in real time on a standard Sequencer timeline. The companion volume path is validated at roughly 300 million voxels per frame.
inside the container
unknown streams skip safely
Typed streams, small readers.
An .vfx file is a chunked container: a fixed header, typed streams identified by four-character codes, and a footer. Readers validate every field, skip streams they don't recognise, and reject corrupt files rather than mis-render them.
Everything below is measured on the format's first production deployment — a 500-frame mountainside landslide element from a current feature production, delivered and played back in Unreal Engine 5.7.
fig 01 · delivered size per version of the 500-frame landslide element, log scale. dashed outline = vendor projection, could not be verified on the linux benchmark machine. the .vfx figures include transform cache and render mesh, and describe a larger simulation than the alembic figure.
measured on the production shot and automated test suite, aug 2026 · unreal engine 5.7.4 · houdini 21.0 · rtx 4090 · threadripper 2990wx · 24 fps fixed budget.
fig 02 · cost of applying one cached frame against the fixed 24 fps budget. playback consumes 6.2% of the frame — the cost is transform application, not geometry decode.
accuracy
the whole of the format's lossiness
0.047 degrees, worst case.
A four-layer automated test chain runs before any change ships: format round trips, golden exporter comparisons, a 38-file hostile-input corpus, and engine-side numerical agreement with the source simulation.
fig 03 · orientation error from the 16-bit quaternion stream over 4,000,000 pieces written and read back through the shipping writer and reader. worst case displaces a surface 0.8 mm at one metre from its pivot. positions are unaffected: bit-exact.
scale headroom
measured per-unit costs, projected linearly
Four million pieces of headroom.
Measured per-unit costs project far beyond today's published production ceilings. The bottleneck is renderer integration, not the data format.
fig 04 · per-frame stream size against piece count, log-log. filled markers are measured caches and the measured alembic delivery; open markers are linear projections. alembic cost rises with every mesh-detail increase; the .vfx stream depends only on piece count.
element sizecache, 500 frstream / framegpu (particles)basis
element size54,770 pieces (current)
cache, 500 fr0.55 GB
stream / frame1.1 MB
gpu (particles)0.3 ms
basismeasured (cache, stream); projected (GPU)
element size362,726 pieces
cache, 500 fr3.6 GB
stream / frame7.3 MB
gpu (particles)2.0 ms
basiscache measured from production sim; playback projected
element size1,000,000 pieces
cache, 500 fr10 GB
stream / frame20 MB
gpu (particles)5.5 ms
basisprojected; equivalent Alembic ~720 GB
element size4,200,000 pieces
cache, 500 fr42 GB
stream / frame84 MB
gpu (particles)23 ms
basisprojected; per-element ceiling of the current mesh path
the 4.2m figure is the per-element ceiling of the current real-geometry path; the particle path is not texture-bound, so shot-level totals of 5m+ pieces are within the format's addressing.
project · specification
project.vfxsectorvisual effects · virtual production · gamesscopeformat design · exporters · unreal runtime · test suiteauthoringhoudini · blender · maya · 3ds max · embergenplaybackunreal engine, windows + linux
carriesrigid pieces · per-piece data · particles · volumesmotion20 bytes per piece per framemeasured39.4 gb alembic → 0.66 gb, same shotaccuracypositions bit-exact · rotations ≤ 0.047°linkdotvfx.org
Deep in a pipeline problem?
hello@envlpr.com. We'll tell you honestly whether we're the right team for it.