如何在 TypeScript 中优化 3D 模型
Aspose.3D FOSS for TypeScript 提供了多种降低输出文件大小和提升处理吞吐量的策略。本指南涵盖了格式选择、二进制嵌入、内存管道以及 Node.js 级别的优化。.
分步指南
步骤 1:选择合适的输出格式
GLB(二进制 glTF)生成最紧凑的输出,并且拥有良好的工具支持。OBJ 是基于文本的,体积更大。STL 在仅几何工作流中更为紧凑。.
| 格式 | 大小 | 包含材质 | 包含动画 | 最佳用途 |
|---|---|---|---|---|
| GLB | 小 | 是(嵌入) | 是 | 网络、游戏、通用交换 |
| glTF | 中等 | 是(分离) | 是 | 开发、检查 |
| STL | 小 | 否 | 否 | 3D printing, geometry-only |
| OBJ | 大 | 分离 .mtl | 否 | 传统工具,兼容性广 |
| FBX | 中等 | 否* | 否* | 导入/导出器已存在,但未接入自动检测 |
| 3MF | 小 | 是 | 否 | 现代 3D 打印 |
步骤 2:导出为二进制 GLB
保存为 GLB 时,设置 GltfSaveOptions.binaryMode = true 以生成单个自包含的二进制文件。这可以避免单独的 .bin 伴随文件,并且许多 3D 查看器都需要它::
import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';
import { GltfSaveOptions } from '@aspose/3d/formats/gltf';
const scene = new Scene();
scene.open('complex-model.obj', new ObjLoadOptions());
const opts = new GltfSaveOptions();
opts.binaryMode = true;
scene.save('optimized.glb', opts);
console.log('Saved compact binary GLB');步骤 3:在内存管道中使用 Buffer I/O
在 Web 服务中处理文件时,使用 openFromBuffer 和 saveToBuffer 以避免写入文件系统::
import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';
function convertInMemory(inputBuffer: Buffer): Buffer {
const scene = new Scene();
scene.openFromBuffer(inputBuffer, new ObjLoadOptions());
return scene.saveToBuffer('glb');
}步骤 4:使用 Worker 线程批量处理文件
对于大型转换任务,将工作分配到 Node.js worker 线程,以利用多个 CPU 核心::
// worker.ts
import { workerData, parentPort } from 'worker_threads';
import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';
const { inputPath, outputPath } = workerData;
const scene = new Scene();
scene.open(inputPath, new ObjLoadOptions());
scene.save(outputPath);
parentPort?.postMessage({ done: true, output: outputPath });// main.ts: dispatch files to workers
import { Worker } from 'worker_threads';
import * as fs from 'fs';
import * as path from 'path';
const files = fs.readdirSync('./input').filter(f => f.endsWith('.obj'));
for (const file of files) {
const inputPath = path.join('./input', file);
const outputPath = path.join('./output', file.replace('.obj', '.glb'));
const worker = new Worker('./dist/worker.js', {
workerData: { inputPath, outputPath }
});
worker.on('message', msg => console.log(`Converted: ${msg.output}`));
worker.on('error', err => console.error(`Error: ${err}`));
}步骤 5:监控大模型的内存使用
对于超过 50 MB 的文件,监控堆内存使用情况;如果内存受限,请顺序处理文件::
function logMemory(label: string) {
const used = process.memoryUsage();
console.log(`[${label}] heapUsed: ${Math.round(used.heapUsed / 1024 / 1024)} MB`);
}
logMemory('before load');
const scene = new Scene();
scene.open('large-model.obj');
logMemory('after load');
scene.save('output.glb');
logMemory('after save');为超大模型增加 Node.js 堆内存::
node --max-old-space-size=8192 convert.js常见问答
哪种输出格式最紧凑??
GLB(二进制 glTF)嵌入资源后,可为包含材质和纹理的场景生成最紧凑的单文件输出。对于仅几何内容,STL 更为紧凑。.
@aspose/3d 是否会进行网格简化或 LOD??
不会。该库读取并写入源几何体,不会修改网格拓扑结构。不支持网格简化(顶点减少、LOD 生成)。.
我可以去除材质以减小文件大小吗??
设置 ObjSaveOptions.enableMaterials = false 保存为 OBJ 时。对于 glTF,始终会包含所有材质数据;使用 STL 进行仅几何体输出。.