Cách xuất các cảnh 3D sang glTF/GLB trong TypeScript

Cách xuất các cảnh 3D sang glTF/GLB trong TypeScript

Aspose.3D FOSS hỗ trợ glTF 2.0 cả ở dạng nhập khẩu và xuất khẩu. Cùng một Scene đối tượng có thể được tạo từ một tệp OBJ, FBX, STL, hoặc tệp nguồn khác và sau đó được ghi vào .gltf (JSON + tệp nhị phân bên ngoài) hoặc .glb (container nhị phân duy nhất) bằng cách đặt một cờ trên GltfSaveOptions.

Hướng Dẫn Từng Bước

Bước 1: Cài đặt @aspose/3d

npm install @aspose/3d

Xác nhận Node.js 18 trở lên đang hoạt động:

node --version   # must be >= 16.0.0

Bước 2: Nhập Scene, GltfSaveOptions và GltfFormat

import { Scene } from '@aspose/3d';
import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf';

GltfFormat là bộ mô tả định dạng được truyền tới scene.save(). GltfSaveOptions chứa tất cả cấu hình xuất khẩu.

Nếu bạn cũng đang tải một file nguồn (ví dụ, OBJ), hãy nhập các tùy chọn tải tương ứng:

import { ObjLoadOptions } from '@aspose/3d/formats/obj';

Bước 3: Xây dựng hoặc tải một cảnh

Tùy chọn A: Tải từ một file hiện có (chuyển đổi 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());

Tùy chọn B: Xây dựng một cảnh tối thiểu bằng chương trình:

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

Bước 4: Cấu hình GltfSaveOptions

GltfSaveOptions kiểm soát định dạng đầu ra và các chi tiết mã hoá.

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;

Các tùy chọn bổ sung bạn có thể đặt:

Thuộc tínhKiểuMặc địnhHiệu ứng
binaryModebooleanfalsetrue → GLB, false → glTF JSON
flipTexCoordVbooleantrueLật trục dọc UV để tương thích với engine

Bước 5: Lưu bằng cách sử dụng scene.save()

Cung cấp đường dẫn đầu ra, the GltfFormat bộ mô tả, và các tùy chọn đã cấu hình:

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');

Để tạo ra một JSON .gltf tệp thay thế:

saveOpts.binaryMode = false;
scene.save('output.gltf', GltfFormat.getInstance(), saveOpts);
console.log('Exported to glTF JSON successfully');

Bước 6: Xác minh tệp đầu ra

Kiểm tra xem tệp đầu ra có tồn tại và có kích thước khác 0 không:

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');
}

Để xác minh vòng lặp, tải lại GLB và kiểm tra số lượng node:

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`);

Các vấn đề thường gặp và cách khắc phục

Không tìm thấy tệp vật liệu OBJ sau khi xuất Khi lưu sang OBJ qua scene.save('output.obj'), the .mtl tệp material được ghi cùng bên cạnh .obj tệp tự động. Đảm bảo thư mục đầu ra có quyền ghi và cả hai tệp được giữ cùng nhau.

Tệp .glb đầu ra nhỏ hơn mong đợi / các lưới bị thiếu Nếu cảnh đã tải có các nút không có thực thể (ví dụ, các nhóm trống từ OBJ), GLB sẽ không chứa hình học của các nút đó. Xác nhận tệp đầu vào của bạn có dữ liệu đa giác thực tế bằng cách sử dụng mesh.controlPoints.length > 0 trước khi lưu.

Không thể tìm thấy mô-đun ‘@aspose/3d/formats/gltf’ Đảm bảo bạn đang sử dụng Node.js 18+ và rằng @aspose/3d được cài đặt trong cùng node_modules với điểm vào của bạn. Chạy npm ls @aspose/3d để xác nhận phiên bản là 24.12.0 hoặc mới hơn.

GltfFormat.getInstance() trả về undefined Điều này cho thấy có sự không khớp phiên bản giữa phần chính @aspose/3d gói và một phiên bản cũ đã được lưu trong bộ nhớ đệm. Xóa node_modulespackage-lock.json, sau đó chạy npm install lại.

Các texture bị thiếu trong GLB đầu ra Đảm bảo binaryMode = true được đặt để tạo ra một GLB tự chứa. Đối với đầu ra glTF JSON, các tệp hình ảnh texture phải có mặt bên cạnh tệp đầu ra vì chúng được tham chiếu bằng đường dẫn tương đối.

Lỗi kiểu: Đối số có kiểu ‘GltfSaveOptions’ không thể gán Đảm bảo cả hai SceneGltfSaveOptions được nhập khẩu từ cùng một phiên bản gói đã cài đặt. Các cài đặt hỗn hợp (toàn cục + cục bộ) có thể gây ra sự không khớp giao diện.

Câu hỏi thường gặp (FAQ)

Sự khác nhau giữa glTF và GLB là gì? glTF 2.0 JSON (.gltf) lưu trữ đồ thị cảnh dưới dạng tệp JSON có thể đọc được bởi con người với các .bin bộ đệm và tệp hình ảnh. GLB (.glb) đóng gói mọi thứ vào một container nhị phân duy nhất. Đặt binaryMode = true cho GLB, false cho JSON glTF.

Tôi có thể xuất một cảnh được xây dựng hoàn toàn bằng mã (không có tệp nguồn) không? Có. Tạo một Scene, thêm Node đối tượng, gắn Mesh hoặc các thực thể khác, sau đó gọi scene.save(). Cảnh không cần phải xuất phát từ một tệp đã tải.

Xuất glTF có mất dữ liệu không? Đối với hình học và biến đổi, có. Vật liệu được ánh xạ sang các thuộc tính vật liệu PBR của glTF khi có thể. Các phần mở rộng vật liệu FBX độc quyền có thể không được chuyển đổi qua lại một cách hoàn hảo.

Tôi có thể xuất sang STL hoặc 3MF thay thế không? Có. Mẫu giống hệt; nhập định dạng tương ứng của *SaveOptions*Format.getInstance():

import { StlSaveOptions, StlFormat } from '@aspose/3d/formats/stl';
const opts = new StlSaveOptions();
scene.save('output.stl', StlFormat.getInstance(), opts);

scene.save() có chạy bất đồng bộ không? Không. scene.save() là đồng bộ. Đặt nó trong một worker thread nếu bạn cần tránh chặn event loop khi xuất khẩu lớn.

Phiên bản Node.js nào được hỗ trợ? Node.js 18, 20 và 22+. Node.js 16 và các phiên bản trước đó không được hỗ trợ.

Xem Thêm

 Tiếng Việt