วิธีส่งออกฉาก 3D ไปเป็น glTF/GLB ด้วย TypeScript
Aspose.3D FOSS รองรับ glTF 2.0 ทั้งในรูปแบบการนำเข้าและส่งออก. เดียวกัน Scene object สามารถถูกเติมข้อมูลจากไฟล์ OBJ, FBX, STL หรือไฟล์ต้นฉบับอื่นและจากนั้นเขียนไปยัง .gltf (JSON + external binary) หรือ .glb (single binary container) โดยตั้งค่าแฟล็กหนึ่งบน 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 คือ format descriptor ที่ส่งให้ 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;ตัวเลือกเพิ่มเติมที่คุณอาจตั้งค่า:
| Property | Type | Default | Effect |
|---|---|---|---|
binaryMode | boolean | false | true → GLB, false → glTF JSON |
flipTexCoordV | boolean | true | พลิกแกนแนวตั้งของ UV เพื่อความเข้ากันได้กับเอนจิน |
ขั้นตอนที่ 5: บันทึกโดยใช้ scene.save()
ส่งพาธผลลัพธ์, the GltfFormat descriptor, และตัวเลือกที่กำหนดค่า:
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 ที่ส่งออกมีขนาดเล็กกว่าที่คาดไว้ / meshes หายไป หากซีนที่โหลดมีโหนดที่ไม่มีเอนทิตี (เช่น กลุ่มว่างจาก 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 ถูกนำเข้าจากแพ็กเกจที่ติดตั้งเดียวกัน การติดตั้งแบบผสม (global + local) อาจทำให้เกิดความไม่ตรงกันของอินเทอร์เฟซ.
คำถามที่พบบ่อย (FAQ)
ความแตกต่างระหว่าง glTF กับ GLB คืออะไร? glTF 2.0 JSON (.gltf) จัดเก็บกราฟฉากเป็นไฟล์ JSON ที่อ่านได้โดยมนุษย์พร้อมไฟล์แยก .bin บัฟเฟอร์และไฟล์รูปภาพ. GLB (.glb) จัดบรรจุทุกอย่างเป็นคอนเทนเนอร์ไบนารีเดียว. ตั้งค่า binaryMode = true สำหรับ GLB, false สำหรับ JSON glTF.
ฉันสามารถส่งออกฉากที่สร้างทั้งหมดด้วยโค้ด (ไม่มีไฟล์ต้นฉบับ) ได้หรือไม่? ใช่. สร้าง Scene, เพิ่ม Node วัตถุ, แนบ Mesh หรือเอนทิตีอื่น, จากนั้นเรียก scene.save(). ฉากไม่จำเป็นต้องมาจากไฟล์ที่โหลด.
การส่งออก glTF เป็น lossless หรือไม่? สำหรับเรขาคณิตและการแปลง, ใช่. วัสดุจะถูกแมปไปยังคุณสมบัติวัสดุ glTF PBR เมื่อเป็นไปได้. ส่วนขยายวัสดุ FBX ที่เป็นกรรมสิทธิ์อาจไม่สามารถทำ round‑trip ได้อย่างสมบูรณ์แบบ.
ฉันสามารถส่งออกเป็น 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() ทำงานแบบซิงโครนัส หากคุณต้องการหลีกเลี่ยงการบล็อก event loop ระหว่างการส่งออกขนาดใหญ่ ให้ห่อหุ้มด้วย worker thread.
เวอร์ชันของ Node.js ที่รองรับคืออะไร? Node.js 18, 20, และ 22+. Node.js 16 และก่อนหน้านั้นไม่รองรับ.