@comfyorg/fbx-exporter-three

中文文档
1.0.2发布于 2026/09/23MITTypeScriptES Module构建来源已验证近 30 天下载 28.2万

FBX exporter for three.js scenes — binary FBX writer with full skinning, animation, morph targets, lights, cameras and texture embedding.

原始使用文档
文档目录17 节
  1. Install
  2. TypeScript
  3. Quickstart
  4. API
  5. class FBXExporter
  6. Convenience exports
  7. Feature coverage
  8. Tool presets
  9. Examples
  10. Skinned + animated character
  11. Textures from disk (Node)
  12. Saving to file
  13. Saving in the browser
  14. Known limitations
  15. How it works (brief)
  16. Testing
  17. License

@comfyorg/fbx-exporter-three

FBX binary exporter for three.js scenes — Unity / Unreal / Maya / Blender / three.js's own FBXLoader all consume the output cleanly.

  • Self-contained: TypeScript source, ships ESM .js + .d.ts. Only runtime dep is fflate (zlib).
  • One-shot or async: parseSync when textures are DataTextures or absent; parseAsync when textures need canvas-based encoding (HTMLImageElement / ImageBitmap / render targets).
  • Tool presets: threejs, unity, unreal, blender, maya — picks the right axis convention + unit scale for the target.
  • Covers: meshes, multi-UV layers, materials, textures (PNG-embedded), skinning, animation (TRS + morph), morph targets, lights, cameras.

Install

npm install @comfyorg/fbx-exporter-three

Peer deps: three >= 0.160 (required), @types/three >= 0.160 (optional, only if you're using TypeScript).

TypeScript

Source is written in TypeScript; published dist/ ships ESM .js + .d.ts. Public types include FBXExporter, FBXExportOptions, FBXPreset, FBXAxis, FBXExporterPlugin.

Quickstart

import * as THREE from 'three';
import { FBXExporter } from '@comfyorg/fbx-exporter-three';
import { writeFileSync } from 'node:fs';

const scene = new THREE.Scene();
scene.add(new THREE.Mesh(
  new THREE.BoxGeometry(1, 1, 1),
  new THREE.MeshStandardMaterial({ color: 0x6688ff }),
));

const exporter = new FBXExporter();
const bytes = exporter.parseSync(scene);

writeFileSync('cube.fbx', bytes);

The result is a binary FBX (Kaydara FBX Binary magic) you can drop straight into Unity, Unreal, Blender, Maya, or load back with FBXLoader.

API

class FBXExporter

const exporter = new FBXExporter();

parseSync(input, options?) → Uint8Array

Build an FBX in one call. Use this for static scenes, scenes that only have DataTextures, or when you've already encoded all your textures.

OptionTypeDefaultNotes
preset'threejs' | 'unity' | 'unreal' | 'blender' | 'maya''threejs'Picks axis + unit defaults.
axisUp'X' | 'Y' | 'Z' | '-X' | '-Y' | '-Z'presetOverrides preset.
axisForwardsamepresetOverrides preset.
unitScalenumberpresetWritten to GlobalSettings.UnitScaleFactor.
bakeSpaceTransformbooleanfalsePre-multiplies axis matrix into geometry. See limitation note below.
versionnumber7400FBX version (7400 / 7500 supported).
fpsnumber24Animation frame rate.
embedTexturesbooleantrueWhen false, textures are referenced by file path instead of embedded.
animationsAnimationClip[]autoIf omitted, we collect from input.animations (the convention used by GLTFLoader / FBXLoader).
includeAnimationsbooleantrueSet false to export a static T-pose only (skips AnimStack/Curve nodes entirely).
onlyVisiblebooleanfalseSkip Object3Ds whose .visible is false.
objectFilter(o: Object3D) => boolean—Generic predicate — return false to skip an object. Composes with onlyVisible.
customPropertiesbooleanfalseEmit each Object3D's userData as user-defined Properties70 entries. Maps booleans → p_bool, integers → p_integer, floats → p_double, strings → p_string, length-3 number arrays → p_vector_3d; other JS values get JSON-stringified into a p_string.
creatorstring@comfyorg/fbx-exporter-three - <ver>Custom string written to FBX Creator metadata.

parseAsync(input, options?) → Promise<Uint8Array>

Same as parseSync but awaits async texture encoding paths — HTMLImageElement, ImageBitmap, canvas/render-target textures all need canvas.toBlob() which is async. Use this whenever your materials reference textures loaded via TextureLoader (any environment with a canvas API).

const bytes = await new FBXExporter().parseAsync(scene);

register(callback) / unregister(callback)

Plugin hook in the style of three.js's GLTFExporter. The callback receives sceneData (the collected scene plan) after collection and texture encoding, before serialization:

exporter.register((sceneData) => {
  // e.g. swap pre-encoded PNG bytes into texture entries
  for (const [tex, entry] of sceneData.textures.textures) {
    if (tex.userData.preEncodedPng) entry.imageBytes = tex.userData.preEncodedPng;
  }
});

Convenience exports

import {
  FBXExporter,
  PRESETS,            // tool preset table
  resolvePreset,      // merge user options onto a preset
  encodeRGBA8PNG,     // pure-JS PNG encoder used internally
} from '@comfyorg/fbx-exporter-three';

Feature coverage

three.js inputFBX output
Mesh + BufferGeometry (positions / normals / vertex colors)Geometry + LayerElementNormal / LayerElementColor / LayerElementMaterial
Multiple UV sets — attributes.uv / uv1 / uv2 / uv3 (used for lightmap / AO)Multiple LayerElementUV nodes with distinct TypedIndex + per-set Layer entries
MeshStandardMaterial / MeshPhongMaterial / MeshBasicMaterialMaterial with FbxSurfacePhong shading model
Texture (DataTexture, HTMLImage, canvas)Texture + Video with embedded PNG bytes
Group, Object3DModel (Null)
SkinnedMesh + Skeleton + BoneDeformer (Skin) + Deformer (Cluster) per bone + Pose (BindPose) + Model (LimbNode) per bone
AnimationClip (position / rotation / scale tracks)AnimationStack + AnimationLayer + AnimationCurveNode + AnimationCurve
Morph targets (morphAttributes.position)Geometry (Shape) per morph + Deformer (BlendShape) + Deformer (BlendShapeChannel)
Morph animation (compound morphTargetInfluences track)Per-channel AnimationCurveNode driving DeformPercent
PointLight / DirectionalLight / SpotLightNodeAttribute (Light) — light.target.position round-trips via LookAtProperty
PerspectiveCamera / OrthographicCameraNodeAttribute (Camera)
Axis / unit conversionGlobalSettings.UpAxis / FrontAxis / UnitScaleFactor

Tool presets

PresetUpAxisFrontAxisUnitScaleBakeUse when…
threejs (default)YZ1offRound-tripping through FBXLoader.
unityYZ1offImporting into Unity (it respects file axes).
unrealZX1offImporting into Unreal Editor. Unreal's importer handles axis conversion when GlobalSettings declares it.
blenderYZ100offFiles for Blender. UnitScale=100 because Blender stores meters but FBX canonical unit is centimeters.
mayaYZ100offSame as Blender.
// Use a preset:
exporter.parseSync(scene, { preset: 'unreal' });

// Or set axes directly:
exporter.parseSync(scene, { axisUp: 'Z', axisForward: 'X' });

// Mix: preset defaults + selective override:
exporter.parseSync(scene, { preset: 'unity', unitScale: 100 });

Examples

Skinned + animated character

import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { FBXExporter } from '@comfyorg/fbx-exporter-three';

const gltf = await new GLTFLoader().loadAsync('character.glb');
const scene = gltf.scene;
scene.animations = gltf.animations;  // wire so the exporter finds them

const bytes = await new FBXExporter().parseAsync(scene);

Textures from disk (Node)

const tex = new THREE.DataTexture(rgbaPixels, w, h, THREE.RGBAFormat);
tex.needsUpdate = true;
material.map = tex;

const bytes = new FBXExporter().parseSync(scene);  // embeds PNG-encoded RGBA

Saving to file

import { writeFileSync } from 'node:fs';
writeFileSync('out.fbx', bytes);

Saving in the browser

const blob = new Blob([bytes], { type: 'application/octet-stream' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'out.fbx';
a.click();
URL.revokeObjectURL(url);

Known limitations

  • bakeSpaceTransform: true only pre-multiplies the axis matrix into vertex positions + normals. Object Lcl transforms, cluster matrices, animation curves, and light/camera transforms are NOT baked. The flag is only safe for single-mesh-at-origin scenes; leave it false otherwise — modern importers (Unity, Unreal, Blender, Maya) honour GlobalSettings.UpAxis so axis conversion happens on import.
  • light.target.position for DirectionalLight / SpotLight round-trips via a synthetic LookAtProperty Model + OP connection.
  • Output is always binary FBX (Kaydara FBX Binary magic). ASCII FBX is not implemented.

How it works (brief)

┌───────────────────┐   ┌──────────────┐   ┌──────────────┐
│ three.js Scene    │ → │ SceneCollect │ → │ FBXElem tree │ → encodeBinaryFBX → Uint8Array
└───────────────────┘   └──────────────┘   └──────────────┘
                              │                    │
                  builds UIDs, dedupes      one writer per FBX
                  geometries / mats /       record kind (Geometry,
                  textures, plans OO/OP     Material, Skin Deformer,
                  connection graph         AnimStack, …)

Testing

npm test

446 unit tests covering the binary layer, scene collection, every Object kind (Mesh / Material / Texture / Skin / Animation / Morph / Light / Camera), axis/unit conversion, the public-options surface.

Real-asset E2E tests (test/e2e-*.test.mjs) aren't part of npm test — they read large binary inputs from test/_assets/ which is gitignored. Drop your own assets in that folder and run them individually:

node --import tsx test/e2e-1-obj.test.mjs           # raw .obj round-trip
node --import tsx test/e2e-2-xbot.test.mjs          # Mixamo skinned + animated character
node --import tsx test/e2e-3-testTexture.test.mjs   # OBJ + MTL + PNG textures
node --import tsx test/e2e-4-threejs-models.test.mjs  # 7 three.js example glTFs

test/m5-bindpose-recovery.test.mjs IS in npm test but skips gracefully when test/_assets/Xbot.glb isn't there — drop in any skinned glTF to enable it.

License

MIT. See LICENSE.

Published under @comfyorg.

版本与发布记录

@comfyorg/fbx-exporter-three 共发布 2 个版本,首次发布于 2026/05/19;过去 12 个月发布了 2 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
1.0.2latest2026/09/231 个月前
1.0.12026/05/195 个月前

关于 @comfyorg/fbx-exporter-three 的常见问题

@comfyorg/fbx-exporter-three 是什么?

FBX exporter for three.js scenes — binary FBX writer with full skinning, animation, morph targets, lights, cameras and texture embedding.

如何安装 @comfyorg/fbx-exporter-three?

在项目目录运行 npm install @comfyorg/fbx-exporter-three,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:three(>=0.160.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@comfyorg/fbx-exporter-three 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@comfyorg/fbx-exporter-three 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@comfyorg/fbx-exporter-three 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=18。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@comfyorg/fbx-exporter-three 可以商用吗?

@comfyorg/fbx-exporter-three 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@comfyorg/fbx-exporter-three 的下载量有多少?

根据 npm 官方下载统计,@comfyorg/fbx-exporter-three 在 2026/10/11 – 2026/11/09 这 30 天内被下载 281,719 次,日均约 9,391 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@comfyorg/fbx-exporter-three 还在维护吗?

最新版本 1.0.2 发布于 2026/09/23(1 个月前);至今共发布 2 个版本,其中过去 12 个月发布了 2 个;首次发布于 2026/05/19。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。