@comfyorg/fbx-exporter- three (中文(简体) )
FBX 二进制导出 3.js 场景 — Unity / 不真实 / Maya / Blender / 3.js 自己的场景 FBXLoader 都干净地消耗了产出.
- 自成一体: 类型脚本来源,船舶无害环境管理
.js+ 键.d.ts。只有运行时间解调器fflate(zlib) (英语). - 一发或同步数字 :
parseSync当纹理是DataTexture或缺席;parseAsync当纹理需要基于画布的编码时( nameHTMLImageElement编号 :ImageBitmap/成为目标). - 工具预设数字 :
threejs, (中文(简体) ),unity, (中文(简体) ),unreal, (中文(简体) ),blender, (中文(简体) ),maya——为目标选择右轴会战+单位规模. - 封面: meshes,多紫外线层,材料,纹理(PNG-嵌入),剥皮,动画(TRS +形态),形态目标,灯光,相机.
安装
npm install @comfyorg/fbx-exporter-three
端点 : three >= 0.160 (必须), @types/three >= 0.160 (可选的,只有使用 TypeScript ).
类型脚本
来源以 TypeScript; 已发布 dist/ 船舶无害环境管理 .js + 键 .d.ts公共类型包括: FBXExporter, (中文(简体) ), FBXExportOptions, (中文(简体) ), FBXPreset, (中文(简体) ), FBXAxis, (中文(简体) ), FBXExporterPlugin。 。 。 .
快速启动
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);
结果是二进制 FBX (Kaydara FBX Binary 魔法)可以直接掉入Unity,unreal,Blender,Maya,或者装入回放 FBXLoader。 。 。 .
API 密码
class FBXExporter
const exporter = new FBXExporter();
parseSync(input, options?) → Uint8Array
在一个呼叫中构建一个FBX. 用于静态场景,只有 DataTextures,或者当你已经 编码了所有的纹理.
| 选项 | 类型 | 默认 | 页:1 |
|---|---|---|---|
preset | 'threejs' | 'unity' | 'unreal' | 'blender' | 'maya' | 'threejs' | 选择轴+单位默认值. |
axisUp | 'X' | 'Y' | 'Z' | '-X' | '-Y' | '-Z' | 预设 | 覆盖预设 . |
axisForward | 不变 | 预设 | 覆盖预设 . |
unitScale | number | 预设 | 写入 GlobalSettings.UnitScaleFactor。 。 。 . |
bakeSpaceTransform | boolean | false | 前相乘轴矩阵为几何. 见下文限制说明. |
version | number | 7400 | FBX版本(支持7400/7500). |
fps | number | 24 | 动画帧率. |
embedTextures | boolean | true | 何时 false,纹理通过文件路径而不是嵌入来引用. |
animations | AnimationClip[] | 自动 | 如果省略,我们从 input.animations (《公约》 GLTFLoader 编号 : FBXLoader) (中文(简体) ). |
includeAnimations | boolean | true | 设定 false 只导出一个静态 T-pose (skips AnimStack/ Curve 节点). |
onlyVisible | boolean | false | 跳过对象3D .visible 实值 false。 。 。 . |
objectFilter | (o: Object3D) => boolean | —— 说 | 通用上游-返回 false 以跳过对象。 编为 onlyVisible。 。 。 . |
customProperties | boolean | false | 发送每个对象3D userData 作为用户定义的属性70条目。 地图布林斯- p_bool整数 + p_integer,浮点 − p_double,字符串 —— p_string,长度 - 数字数组 p_vector_3d其他联署材料的价值观使JSON弦化为 p_string。 。 。 . |
creator | string | @comfyorg/fbx-exporter-three - <ver> | 自定义字符串写入 FBX Creator 元数据. |
parseAsync(input, options?) → Promise<Uint8Array>
与 parseSync 但等待着同步纹理编码路径—— HTMLImageElement, (中文(简体) ), ImageBitmap,画布/投放目标纹理均需 canvas.toBlob() 这是同步。 当您的材料引用纹理时使用此功能 TextureLoader (任何带有帆布 API 的环境).
const bytes = await new FBXExporter().parseAsync(scene);
register(callback) 编号 : unregister(callback)
3的样式插件钩子 。 Js's (英语) GLTFExporter复选 sceneData (所收集的场景计划)在采集和纹理编码之后,在序列化之前:
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;
}
});
方便出口
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';
特征覆盖
| 三.js 输入 | FBX 输出 |
|---|---|
Mesh + 键 BufferGeometry (位置/ 常态/ 顶点颜色) | Geometry + 键 LayerElementNormal 编号 : LayerElementColor 编号 : LayerElementMaterial |
多个紫外线装置—— attributes.uv 编号 : uv1 编号 : uv2 编号 : uv3 (用于光映射/AO) | 多个 LayerElementUV 不同节点 TypedIndex + 每组 Layer 条目 |
MeshStandardMaterial 编号 : MeshPhongMaterial 编号 : MeshBasicMaterial | Material 与 FbxSurfacePhong 阴影模型 |
Texture (数据图、HTML图像、画布) | Texture + 键 Video 有嵌入式 PNG 字节 |
Group, (中文(简体) ), Object3D | Model (诺尔) |
SkinnedMesh + 键 Skeleton + 键 Bone | Deformer (皮肤)+ Deformer (组分)每根骨头+ Pose (BindPose) + (英语) Model 每根骨头 |
AnimationClip (位置/旋转/比例轨道) | AnimationStack + 键 AnimationLayer + 键 AnimationCurveNode + 键 AnimationCurve |
溶液目标(morphAttributes.position(中文(简体) ) | Geometry (形状)每平方圆+ Deformer (蓝发)+ Deformer (Blend ShapeChannel) (英语) |
墨迹动画( 组合) morphTargetInfluences 音轨) | 每道 AnimationCurveNode 驾驶 DeformPercent |
PointLight 编号 : DirectionalLight 编号 : SpotLight | NodeAttribute (灯光) - light.target.position 往返 LookAtProperty |
PerspectiveCamera 编号 : OrthographicCamera | NodeAttribute (卡梅拉语) |
| 轴/单位转换 | GlobalSettings.UpAxis 编号 : FrontAxis 编号 : UnitScaleFactor |
工具预设
| 预设 | 上轴 | 前轴 | 单位比例 | 贝克 | 当.. |
|---|---|---|---|---|---|
threejs (默认) | Y | 页:1 | 1个 | 关 | 绕行 FBXLoader。 。 。 . |
unity | Y | 页:1 | 1个 | 关 | 导入到 Unity( 它尊重文件轴) . |
unreal | 页:1 | 页:1 | 1个 | 关 | 导入到不真实编辑器 。 Unreal 的导入者在 GlobalSettings 宣布时处理轴转换 . |
blender | Y | 页:1 | 100个 | 关 | Blender 的文件 。 单位比例=100,因为 Blender 存储仪表,但 FBX 犬形单元为公分. |
maya | Y | 页:1 | 100个 | 关 | 和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 });
实例
皮肤+动画字符
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);
磁盘的纹理( 节点)
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
保存到文件
import { writeFileSync } from 'node:fs';
writeFileSync('out.fbx', bytes);
在浏览器中保存
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);
已知的限制
bakeSpaceTransform: true只预乘轴矩阵 顶点位置+常态对象Lcl变相,集群矩阵,动画曲线,和光相/相机变相都不被烘焙. 国旗只适合单一的原生场景; 离开它false- 现代进口商(团结、不真实、Blender、玛雅)荣誉GlobalSettings.UpAxis因此,在导入时会发生轴转换.light.target.position页:1DirectionalLight编号 :SpotLight通过合成的回转LookAtProperty型号+OP连接.- 输出总是二进制 FBX (单位:千美元)
Kaydara FBX Binary魔术). ASCII FBX没有执行.
如何运作(简要)
┌───────────────────┐ ┌──────────────┐ ┌──────────────┐
│ 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, …)
测试
npm test
446个单元测试覆盖了二进制地层,场景采集,每一种对象类型(Mesh / Material / Texture / Skin / Animation / Morph / Light /相机),轴/单元转换,公选表.
活性资产E2E测试(test/e2e-*.test.mjs没有参与 npm test - 他们读取了来自 test/_assets/ 它被赋予了尊严。 将您自己的资产丢入该文件夹并单独运行 :
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 编号 npm test 但优雅地跳过当 test/_assets/Xbot.glb - 掉入任何被剥光的GLTF来启用它.
许可证
麻省理工学院. 见 自由主义。 。 。 .
原载 @comfyorg (英语)。 。 。 .