如何在 TypeScript 中导出 3D 场景为 glTF/GLB
Aspose.3D FOSS 支持 glTF 2.0 作为导入和导出格式。相同 Scene 对象可以从 OBJ、FBX、STL 或其他源文件中填充,然后写入 .gltf (JSON + 外部二进制)或 .glb (单一二进制容器)通过在…上设置一个标志 GltfSaveOptions.
分步指南
步骤 1:安装 @aspose/3d
npm install @aspose/3d确认已使用 Node.js 18 或更高版本::
node --version # must be >= 16.0.0步骤 2:导入 Scene、GltfSaveOptions 和 GltfFormat
import { Scene } from '@aspose/3d';
import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf';GltfFormat 是传递给的格式描述符 scene.save(). GltfSaveOptions 携带所有导出配置。.
如果您还要加载源文件(例如 OBJ),请导入相应的加载选项::
import { ObjLoadOptions } from '@aspose/3d/formats/obj';步骤 3:构建或加载场景
选项 A:从现有文件加载(OBJ → GLB 转换)::
import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';
import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf';
const scene = new Scene();
scene.open('model.obj', new ObjLoadOptions());选项 B:以编程方式构建最小场景::
import { Scene, Node, Mesh } from '@aspose/3d';
import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf';
const scene = new Scene();
const childNode = new Node('cube');
scene.rootNode.addChildNode(childNode);
// Attach geometry to childNode as needed
步骤 4:配置 GltfSaveOptions
GltfSaveOptions 控制输出格式和编码细节。.
const saveOpts = new GltfSaveOptions();
// Set to true for a single binary .glb file
// Set to false (default) for JSON .gltf + separate .bin
saveOpts.binaryMode = true;您可以设置的其他选项::
| 属性 | 类型 | 默认 | 效果 |
|---|---|---|---|
binaryMode | boolean | false | true → GLB, false → glTF JSON |
flipTexCoordV | boolean | true | 翻转 UV 垂直轴以兼容引擎 |
步骤 5:使用 scene.save() 保存
传递输出路径, GltfFormat 描述符,以及已配置的选项::
import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';
import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf';
const scene = new Scene();
scene.open('model.obj', new ObjLoadOptions());
const saveOpts = new GltfSaveOptions();
saveOpts.binaryMode = true; // produce .glb
scene.save('output.glb', GltfFormat.getInstance(), saveOpts);
console.log('Converted to GLB successfully');生成 JSON .gltf 文件,而不是::
saveOpts.binaryMode = false;
scene.save('output.gltf', GltfFormat.getInstance(), saveOpts);
console.log('Exported to glTF JSON successfully');步骤 6:验证输出文件
检查输出文件是否存在且大小非零::
import * as fs from 'fs';
const outputPath = 'output.glb';
const stats = fs.statSync(outputPath);
console.log(`Output file size: ${stats.size} bytes`);
if (stats.size === 0) {
throw new Error('Export produced an empty file: check scene content');
}为了往返验证,重新加载 GLB 并检查节点计数::
import { Scene } from '@aspose/3d';
import { GltfLoadOptions } from '@aspose/3d/formats/gltf';
const verify = new Scene();
verify.open('output.glb', new GltfLoadOptions());
let nodeCount = 0;
function countNodes(node: any): void {
nodeCount++;
for (const child of node.childNodes) countNodes(child);
}
countNodes(verify.rootNode);
console.log(`Round-trip verification: ${nodeCount} node(s) in output`);常见问题及解决方案
导出后未找到 OBJ 材质文件 通过保存为 OBJ 时 scene.save('output.obj'),, .mtl material 文件会与 … 一起写入 .obj 文件会自动生成。确保输出目录可写,并且两个文件保持在一起。.
输出的 .glb 小于预期 / 网格缺失 如果加载的场景中有没有实体的节点(例如来自 OBJ 的空组),GLB 将不包含这些节点的几何体。请使用以下方式确认你的输入文件具有实际的多边形数据: mesh.controlPoints.length > 0 在保存之前。.
找不到模块 ‘@aspose/3d/formats/gltf’ 确保你使用的是 Node.js 18+,并且 @aspose/3d 已安装在相同的 node_modules 作为你的入口点。运行 npm ls @aspose/3d 以确认版本为 24.12.0 或更高。.
GltfFormat.getInstance() 返回 undefined 这表明主程序之间的版本不匹配 @aspose/3d 包和缓存的旧版本之间存在差异。删除 node_modules 和 package-lock.json,,然后运行 npm install 再次。.
输出的 GLB 中缺少纹理 确保 binaryMode = true 已设置为生成自包含的 GLB。对于 glTF JSON 输出,纹理图像文件必须与输出文件放在同一目录下,因为它们是通过相对路径引用的。.
类型错误:类型为 ‘GltfSaveOptions’ 的参数不可分配 确保两者 Scene 和 GltfSaveOptions 从相同的已安装软件包实例中导入。混合安装(全局 + 本地)可能导致接口不匹配。.
常见问题 (FAQ)
glTF 与 GLB 有何区别?? glTF 2.0 JSON(.gltf)将场景图存储为可读的 JSON 文件,并使用分离的 .bin 缓冲区和图像文件。GLB(.glb)将所有内容打包成单个二进制容器。设置 binaryMode = true 用于 GLB,, false 用于 JSON glTF。.
我可以导出完全在代码中构建的场景吗(没有源文件)?? 是的。创建一个 Scene,,添加 Node 对象,附加 Mesh 或其他实体,然后调用 scene.save().。场景不需要来源于已加载的文件。.
glTF 导出是无损的吗?? 对于几何体和变换,是的。材质会在可能的情况下映射到 glTF PBR 材质属性。专有的 FBX 材质扩展可能无法完美往返。.
我可以改为导出为 STL 或 3MF 吗?? 是的。模式完全相同;导入相应格式的 *SaveOptions 和 *Format.getInstance():
import { StlSaveOptions, StlFormat } from '@aspose/3d/formats/stl';
const opts = new StlSaveOptions();
scene.save('output.stl', StlFormat.getInstance(), opts);scene.save() 会异步运行吗?? 不。. scene.save() 是同步的。如果在大规模导出时需要避免阻塞事件循环,请将其包装在工作线程中。.
支持哪些 Node.js 版本?? Node.js 18、20 和 22+。不支持 Node.js 16 及更早版本。.