Standalone FBX exporter repository and npm package for exporting Three.js scenes to FBX.
Package name: @needle-tools/fbx-exporter
This repository contains:
- the FBX exporter source and package entrypoints
- validation tooling based on
ufbxand Autodesk FBX SDK - Blender smoke-test helpers and FBX reference fixtures
- a publishable
package/folder with a typed ESM API
| Path | Purpose |
|---|---|
src/FBXExporter.ts |
Main exporter implementation |
src/index.ts |
Package entrypoint re-exporting the public API |
package/ |
Publishable npm package metadata and dist output |
tests/FBXExporter.spec.js |
Main exporter test suite |
tests/FBXLoaderAdversarial.spec.js |
three.js FBXLoader round-trip stress tests |
tests/FBXBlenderAdversarial.spec.js |
Blender import and FBX-to-glTF probe tests |
tests/fbx-validator/ |
ufbx-based validation tooling |
tests/fbx-sdk-validator/ |
FBX SDK-based validation and conversion tooling |
tests/reference/ |
Reference parser/export scripts for FBX structure debugging |
tests/scripts/ |
CLI/debug helpers for exporter development |
The package exposes a single high-level API:
new FBXExporter()exporter.export(scene, options)
npm install @needle-tools/fbx-exporterimport { FBXExporter } from '@needle-tools/fbx-exporter';
const exporter = new FBXExporter();
const result = await exporter.export(scene, {
binary: true,
embedTextures: true,
});
console.log(result.fbxFileName);
console.log(result.format);
console.log(Object.keys(result.files));interface FBXExportResult {
target: 'Default' | 'Horizon Worlds';
format: 'ascii' | 'binary';
fbxFileName: string;
fbxData: string | ArrayBuffer;
files: Record<string, Uint8Array>;
textures: Texture[];
zipData: Uint8Array;
}npm install
npm run build:packageOutputs:
package/dist/index.jspackage/dist/index.d.tspackage/dist/FBXExporter.jspackage/dist/FBXExporter.d.ts
npm testTo run only the exporter suite:
npm run test:fbxSupported means the package exports that data today and we have at least basic
validation coverage. Partial means the package exports only part of the FBX
payload, exports a compatibility approximation, or importer behavior is
inconsistent. Not supported means there is no dedicated export path yet.
| Area | Status | Notes |
|---|---|---|
| Scene root and hierarchy | Supported | Parent-child relationships are preserved and top-level objects are connected to FBX root. |
| Generic nodes / groups / empties | Supported | Exported as FBX Model nodes with Null type. |
| Mesh nodes | Supported | Mesh models are exported with geometry/material connections. |
| Local transforms | Supported | Writes Lcl Translation, Lcl Rotation, Lcl Scaling, RotationOrder, and InheritType. |
| Nested transform round-trips | Supported | Covered by adversarial FBXLoader tests. |
| Cameras | Supported | Exports NodeAttribute/Camera payloads for perspective and orthographic cameras, including projection mode, clipping planes, focal length/FOV, aspect hints, and ortho size. Current importer coverage differs: Blender imports both, while three.js FBXLoader only instantiates perspective cameras. |
| Lights | Supported | Exports NodeAttribute/Light payloads for point, directional, and spot lights, including color, intensity, shadow flags, attenuation distance, and spot cone data. Unsupported light classes fall back to point lights with a warning. |
| Markers / locators | Partial | Use generic Null nodes for locator-style transforms. Dedicated FBX Marker attributes are not written. |
| Visibility | Supported | Static node visibility is exported through FBX visibility properties. Blender honors it on import; three.js FBXLoader currently does not apply node visibility. |
| Area | Status | Notes |
|---|---|---|
| Triangle meshes | Supported | Indexed and non-indexed triangle meshes are exported and round-trip through FBXLoader. |
| Positions and polygon indices | Supported | Standard mesh vertices and polygon indices are written for ASCII and binary export. |
| Multi-material groups | Supported | Per-polygon material indices are exported and covered by adversarial tests. |
| Normals | Supported | Emits LayerElementNormal; validated with ufbx and Autodesk FBX SDK tooling. |
| Tangents | Supported | Emits LayerElementTangent; current coverage is writer-focused rather than a dedicated tangent stress test. |
| Vertex colors | Supported | Emits LayerElementColor; current coverage is structural rather than a dedicated adversarial color round-trip. |
| UV0 | Supported | three.js uv is exported as FBX UVMap. |
| Secondary and additional UV layers | Supported | uv1, uv2, and higher are exported as separate LayerElementUV entries and validated through FBXLoader and Blender/glTF round-trips. |
| Texture UV channel routing | Supported | texture.channel is exported through FBX UVSet. |
| Material classes | Partial | MeshBasicMaterial, MeshLambertMaterial, MeshPhongMaterial, and MeshStandardMaterial export to Lambert/Phong-style FBX materials. This is an approximation, not full glTF-style PBR fidelity. |
| Base color, emissive, and opacity | Supported | Standard material properties are written and covered by exporter tests. |
| Normal and alpha maps | Supported | Exported as separate texture slots and covered by round-trip tests. |
| AO, roughness, and metalness maps | Partial | Exported through FBX-compatible property mappings and texture slots, not native PBR semantics. |
| Double-sided materials | Partial | Writes a compatibility DoubleSided dynamic property. FBXLoader and Blender currently flatten front-sided and double-sided imports the same way. |
| Texture offset and repeat | Supported | Exported via FBX texture translation/scaling and covered by round-trip tests. |
| Texture wrap: repeat / clamp | Supported | Maps cleanly to the standard FBX wrap enum. |
| Texture wrap: mirrored repeat | Not supported | Standard FBX wrap mode only has repeat and clamp, so mirrored repeat is downgraded to repeat with a warning. |
| Texture rotation and center | Not supported | The exporter does not currently write texture rotation or center/pivot transforms. |
| Embedded textures | Supported | ASCII and binary embedded-texture paths are covered in tests. |
| Binormals, smoothing groups, edge visibility | Not supported | The exporter does not emit those FBX layer elements today. |
| Area | Status | Notes |
|---|---|---|
| Animation stacks, layers, curves, keyframes | Not supported | The exporter only writes a placeholder Takes block. |
| Node transform animation | Not supported | Only static local transforms are exported. |
| Material / texture animation | Not supported | No animated material or texture property export exists today. |
| Skinning / bones / bind poses | Not supported | No LimbNode, Pose, Deformer/Skin, or Cluster export exists. |
| Morph targets / blend shapes | Not supported | No Shape, BlendShape, or BlendShapeChannel export exists. |
| Other deformers / vertex caches | Not supported | No deformer export path exists beyond static mesh data. |
- Geometry UV layers are exported as separate FBX
LayerElementUVentries. Texturechannelis exported through the standard FBXUVSetproperty:0 -> UVMap,1 -> uv1,2 -> uv2, and so on. - The Autodesk FBX SDK documents
FbxTexture::EWrapModeas having onlyeRepeatandeClamp. Because there is no standard mirrored-repeat wrap mode in that enum,three.jsMirroredRepeatWrappingis exported as repeat with a warning. DoubleSidedis not documented as a built-in standard property onFbxSurfaceLambert/FbxSurfacePhong. This package still writes a compatibilityDoubleSidedboolean dynamic property because some tools recognize it, but importer behavior is tool-specific.- Static node
Visibilityis exported, but currentthree.jsFBXLoaderdoes not apply it to imported objects. Blender does. - Orthographic camera attributes are exported, but current
three.jsFBXLoaderstill instantiates orthographic cameras as genericObject3Dplaceholders. - Current adversarial tests show that both
three.jsFBXLoaderand Blender's FBX import path flatten front-sided and double-sided materials the same way, soDoubleSideshould be treated as best-effort compatibility metadata, not guaranteed roundtrip state.
References:
FbxTexture: https://help.autodesk.com/cloudhelp/2020/ENU/FBX-API-Reference/cpp_ref/class_fbx_texture.htmlFbxSurfaceLambert: https://help.autodesk.com/cloudhelp/2020/ENU/FBX-Developer-Help/files/cpp_ref/FBX_Developer_Help_cpp_ref_class_fbx_surface_lambert_html.htmlFbxSurfacePhong: https://help.autodesk.com/cloudhelp/2018/ENU/FBX-Developer-Help/cpp_ref/class_fbx_surface_phong.html- FBX properties: https://help.autodesk.com/cloudhelp/2018/ENU/FBX-Developer-Help/fbx_sdk_object_model/fbx_properties.html