5.1模型格式


文档摘要

5.1模型格式 Three.js 模型格式详解与加载实践 5.1 模型格式概览 Three.js 支持多种模型格式,每种格式都有其优缺点。选择合适的格式取决于项目的具体需求。以下是一些常见的模型格式: glTF (GL Transmission Format): 现代、开放、可扩展的格式,旨在成为 3D 内容的 JPEG。它支持动画、材质、PBR 渲染,并且可以高效传输。强烈推荐使用。 OBJ (Wavefront Object): 一种简单的文本格式,广泛支持,但文件通常较大,且材质和动画支持有限。 FBX (Filmbox): Autodesk 开发的专有格式,广泛用于游戏和动画行业。支持复杂的动画和材质,但文件通常较大,且需要 FBX Loader。

5.1模型格式

Three.js 模型格式详解与加载实践

5.1 模型格式概览

Three.js 支持多种模型格式,每种格式都有其优缺点。选择合适的格式取决于项目的具体需求。以下是一些常见的模型格式:

  • glTF (GL Transmission Format): 现代、开放、可扩展的格式,旨在成为 3D 内容的 JPEG。它支持动画、材质、PBR 渲染,并且可以高效传输。强烈推荐使用。

  • OBJ (Wavefront Object): 一种简单的文本格式,广泛支持,但文件通常较大,且材质和动画支持有限。

  • FBX (Filmbox): Autodesk 开发的专有格式,广泛用于游戏和动画行业。支持复杂的动画和材质,但文件通常较大,且需要 FBX Loader。

  • STL (Stereolithography): 用于 3D 打印的格式,仅包含几何信息,不支持材质或动画。

  • PLY (Polygon File Format): 存储多边形网格数据的格式,可以包含颜色、法线等信息。

  • Collada (DAE): 一种开放的交换格式,支持动画和材质,但逐渐被 glTF 取代。

  • Three.js JSON Format: Three.js 自有的 JSON 格式,已经过时,不推荐使用。

5.1.1 glTF (GL Transmission Format)

glTF 是现代 Web 3D 的首选格式。它旨在高效地传输和加载 3D 模型,并支持 PBR 材质、动画、蒙皮等高级特性。glTF 有两种变体:

  • glTF (.gltf): 基于 JSON 的格式,包含对外部资源(如纹理和二进制数据)的引用。

  • glTF Binary (.glb): 将所有数据(包括几何、纹理和动画)嵌入到单个二进制文件中,更易于传输和加载。

代码实践:

import * as THREE from 'three'; import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'; const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 添加环境光 const ambientLight = new THREE.AmbientLight(0x404040); // soft white light scene.add(ambientLight); // 添加平行光 const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5); directionalLight.position.set(1, 1, 1); scene.add(directionalLight); camera.position.z = 5; const loader = new GLTFLoader(); loader.load( 'models/scene.gltf', // 模型路径 function (gltf) { scene.add(gltf.scene); // 可选:访问模型的组件 gltf.animations; // Array<THREE.AnimationClip> gltf.scene; // THREE.Group gltf.scenes; // Array<THREE.Group> gltf.cameras; // Array<THREE.Camera> gltf.asset; // Object // 可选:调整模型位置和缩放 gltf.scene.scale.set(0.1, 0.1, 0.1); gltf.scene.position.set(0, -1, 0); renderer.render(scene, camera); }, function (xhr) { console.log((xhr.loaded / xhr.total * 100) + '% loaded'); }, function (error) { console.error('An error happened', error); } ); function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); } animate();

详解:

  1. 引入 GLTFLoader: import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'; 导入 glTF 加载器。

  2. 创建加载器实例: const loader = new GLTFLoader(); 创建 GLTFLoader 的实例。

  3. 加载模型: loader.load('models/scene.gltf', ...) 使用 load 方法加载 glTF 模型。load 方法接受四个参数:

    • 模型路径: glTF 文件的路径。

    • 加载成功回调: 在模型加载成功后执行的函数。该函数接收一个 gltf 对象,其中包含模型的场景、动画、相机等信息。

    • 加载进度回调 (可选): 在模型加载过程中定期执行的函数,用于显示加载进度。

    • 加载失败回调 (可选): 在模型加载失败时执行的函数。

  4. 添加到场景: scene.add(gltf.scene); 将加载的模型的场景添加到 Three.js 场景中。 gltf.scene 是一个 THREE.Group 对象,包含模型的所有网格、材质和子对象。

  5. 访问模型组件 (可选): gltf 对象包含模型的动画、场景、相机和资产信息。可以通过 gltf.animationsgltf.scenegltf.camerasgltf.asset 属性访问这些组件。

  6. 调整模型 (可选): 可以调整模型的位置、缩放和旋转,以适应场景的需求。

glTF 优势:

  • 高效性: 压缩的二进制格式,减少文件大小和加载时间。

  • PBR 材质支持: 支持物理渲染材质,实现更逼真的视觉效果。

  • 动画支持: 支持骨骼动画、变形动画等。

  • 开放标准: 无需授权费用,易于集成到各种 3D 引擎和工具中。

5.1.2 OBJ (Wavefront Object)

OBJ 是一种简单的文本格式,广泛支持,但文件通常较大,且材质和动画支持有限。它主要包含几何信息(顶点、面)和材质引用。

代码实践:

import * as THREE from 'three'; import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader.js'; import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader.js'; const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 添加环境光 const ambientLight = new THREE.AmbientLight(0x404040); // soft white light scene.add(ambientLight); // 添加平行光 const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5); directionalLight.position.set(1, 1, 1); scene.add(directionalLight); camera.position.z = 5; // 加载 MTL 材质文件 const mtlLoader = new MTLLoader(); mtlLoader.load('models/model.mtl', (materials) => { materials.preload(); // 加载 OBJ 模型文件 const objLoader = new OBJLoader(); objLoader.setMaterials(materials); // 设置材质 objLoader.load('models/model.obj', (object) => { scene.add(object); // 可选:调整模型位置和缩放 object.scale.set(0.1, 0.1, 0.1); object.position.set(0, -1, 0); renderer.render(scene, camera); }, function (xhr) { console.log((xhr.loaded / xhr.total * 100) + '% loaded'); }, (error) => { console.error('An error happened', error); }); }); function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); } animate();

详解:

  1. 引入 OBJLoader 和 MTLLoader: import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader.js';import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader.js'; 导入 OBJ 和 MTL 加载器。OBJ 文件通常与 MTL (Material Template Library) 文件一起使用,MTL 文件定义了模型的材质。

  2. 创建加载器实例: const objLoader = new OBJLoader();const mtlLoader = new MTLLoader(); 创建 OBJLoaderMTLLoader 的实例。

  3. 加载 MTL 文件: mtlLoader.load('models/model.mtl', ...) 使用 load 方法加载 MTL 文件。

  4. 设置材质: objLoader.setMaterials(materials); 将加载的材质传递给 OBJLoader。

  5. 加载 OBJ 文件: objLoader.load('models/model.obj', ...) 使用 load 方法加载 OBJ 模型。

  6. 添加到场景: scene.add(object); 将加载的模型添加到 Three.js 场景中。

  7. 调整模型 (可选): 可以调整模型的位置、缩放和旋转,以适应场景的需求。

OBJ 优势:

  • 简单易懂: 文本格式,易于阅读和编辑。

  • 广泛支持: 几乎所有 3D 建模软件都支持导出 OBJ 格式。

OBJ 劣势:

  • 文件较大: 文本格式,没有压缩,文件大小通常较大。

  • 材质支持有限: MTL 文件仅支持简单的材质属性,不支持 PBR 渲染。

  • 动画支持差: 不支持动画。

5.1.3 FBX (Filmbox)

FBX 是 Autodesk 开发的专有格式,广泛用于游戏和动画行业。它支持复杂的动画和材质,但文件通常较大,且需要 FBX Loader。

代码实践:

import * as THREE from 'three'; import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js'; const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 添加环境光 const ambientLight = new THREE.AmbientLight(0x404040); // soft white light scene.add(ambientLight); // 添加平行光 const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5); directionalLight.position.set(1, 1, 1); scene.add(directionalLight); camera.position.z = 5; const loader = new FBXLoader(); loader.load( 'models/model.fbx', function (object) { scene.add(object); // 可选:调整模型位置和缩放 object.scale.set(0.1, 0.1, 0.1); object.position.set(0, -1, 0); // 可选:播放动画 if (object.animations && object.animations.length > 0) { const mixer = new THREE.AnimationMixer(object); const action = mixer.clipAction(object.animations[0]); action.play(); // 创建动画循环 function animate() { requestAnimationFrame(animate); mixer.update(0.01); // delta time renderer.render(scene, camera); } animate(); } else { renderer.render(scene, camera); // 没有动画则直接渲染 } }, function (xhr) { console.log((xhr.loaded / xhr.total * 100) + '% loaded'); }, function (error) { console.error('An error happened', error); } ); function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); } // 如果没有动画,则只执行一次渲染 // animate(); // 只有有动画的时候才执行

详解:

  1. 引入 FBXLoader: import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js'; 导入 FBX 加载器。

  2. 创建加载器实例: const loader = new FBXLoader(); 创建 FBXLoader 的实例。

  3. 加载模型: loader.load('models/model.fbx', ...) 使用 load 方法加载 FBX 模型。

  4. 添加到场景: scene.add(object); 将加载的模型添加到 Three.js 场景中。

  5. 调整模型 (可选): 可以调整模型的位置、缩放和旋转,以适应场景的需求。

  6. 播放动画 (可选): 如果模型包含动画,可以使用 THREE.AnimationMixer 来播放动画。

FBX 优势:

  • 动画支持: 支持复杂的动画,包括骨骼动画和变形动画。

  • 材质支持: 支持复杂的材质属性。

FBX 劣势:

  • 文件较大: 文件大小通常较大。

  • 专有格式: 由 Autodesk 开发,需要 FBX Loader。

5.1.4 STL (Stereolithography)

STL 是一种用于 3D 打印的格式,仅包含几何信息(三角形网格),不支持材质或动画。

代码实践:

import * as THREE from 'three'; import { STLLoader } from 'three/examples/jsm/loaders/STLLoader.js'; const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 添加环境光 const ambientLight = new THREE.AmbientLight(0x404040); // soft white light scene.add(ambientLight); // 添加平行光 const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5); directionalLight.position.set(1, 1, 1); scene.add(directionalLight); camera.position.z = 5; const loader = new STLLoader(); loader.load( 'models/model.stl', function ( geometry ) { const material = new THREE.MeshPhongMaterial( { color: 0xffffff } ); const mesh = new THREE.Mesh( geometry, material ); scene.add( mesh ); // 可选:调整模型位置和缩放 mesh.scale.set(0.1, 0.1, 0.1); mesh.position.set(0, -1, 0); renderer.render(scene, camera); } ); function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); } animate();

详解:

  1. 引入 STLLoader: import { STLLoader } from 'three/examples/jsm/loaders/STLLoader.js'; 导入 STL 加载器。

  2. 创建加载器实例: const loader = new STLLoader(); 创建 STLLoader 的实例。

  3. 加载模型: loader.load('models/model.stl', ...) 使用 load 方法加载 STL 模型。

  4. 创建材质: 由于 STL 文件不包含材质信息,需要手动创建材质。 const material = new THREE.MeshPhongMaterial( { color: 0xffffff } );

  5. 创建网格: const mesh = new THREE.Mesh( geometry, material ); 使用加载的几何体和创建的材质创建网格。

  6. 添加到场景: scene.add(mesh); 将创建的网格添加到 Three.js 场景中。

  7. 调整模型 (可选): 可以调整模型的位置、缩放和旋转,以适应场景的需求。

STL 优势:

  • 简单: 仅包含几何信息,易于生成和处理。

  • 广泛支持: 几乎所有 3D 打印软件都支持导出 STL 格式。

STL 劣势:

  • 不支持材质: 不包含材质信息,需要手动创建材质。

  • 不支持动画: 不支持动画。

  • 文件较大: 没有压缩,文件大小通常较大。

5.1.5 模型格式选择建议

模型格式 优势 劣势 适用场景
glTF 高效、PBR 材质、动画支持、开放标准 复杂场景可能需要优化 现代 Web 3D 应用,需要高质量渲染和动画。
OBJ 简单易懂、广泛支持 文件较大、材质支持有限、动画支持差 简单的静态模型,不需要复杂的材质和动画。
FBX 动画支持、材质支持 文件较大、专有格式 游戏和动画行业,需要复杂的动画和材质。
STL 简单、广泛支持 不支持材质、不支持动画、文件较大 3D 打印,仅需要几何信息。

流程图:

总结

选择合适的模型格式是 Three.js 开发的关键一步。glTF 是现代 Web 3D 的首选格式,因为它提供了高效的传输、PBR 材质支持和动画支持。对于简单的静态模型,OBJ 格式可能更合适。对于需要复杂动画和材质的场景,FBX 格式是一个不错的选择。STL 格式则适用于 3D 打印。了解各种模型格式的优缺点,可以帮助你做出明智的选择,优化 Three.js 应用的性能和视觉效果。

希望这篇文章能够帮助你更好地理解 Three.js 中的模型格式及其加载实践。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U