一、gltf文件格式
glTF(GL transmission format)是由Khronos Group发布的一种用于在3D应用程序中传输和渲染3D模型和场景的标准。它的目标是成为一种快速、轻量且易于扩展的中间格式,支持从现代3D工具中导出的大部分内容,包括动画、材料和几何体等。
通常情况下,我们使用3D建模软件(例如Blender、Maya等)创建3D模型后,需要将模型导出为各种格式(例如OBJ、FBX、DAE等)才能进行使用。但是传统的3D文件格式通常很重,导致加载时间长,而且不灵活。相比之下,glTF格外小巧,并且完美地与WebGL和Three.js兼容,使它成为轻量级Web 3D模型的首选格式。
二、Three.js的GLTFLoader加载器
Three.js是一款流行的JavaScript库,用于在Web上呈现3D图形。它提供了一些基本几何体、贴图、灯光等组件,同时也有一些实用的工具和监控器。Three.js的GLTFLoader是一种用于加载和解析glTF文件的JavaScript库。
使用GLTFLoader,我们可以轻松地加载glTF文件,将其加入到Three.js场景中,添加不同的光照和材质,实现复杂的场景渲染。
下面的代码片段演示了如何使用GLTFLoader加载gltf模型:
// 首先需要在HTML页面中引入three.js和GLTFLoader <script src="https://cdn.bootcdn.net/ajax/libs/three.js/110/three.min.js"></script> <script src="https://cdn.bootcdn.net/ajax/libs/three.js/110/loaders/GLTFLoader.min.js"></script> // 创建Three.js场景、相机和渲染器 var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamera(...); var renderer = new THREE.WebGLRenderer(...); // 创建GLTFLoader实例,并设置加载完成后的回调函数 var loader = new THREE.GLTFLoader(); loader.load( 'models/mymodel.gltf', function ( gltf ) { // 当模型加载完成后,可以在回调函数中对模型进行处理 scene.add( gltf.scene ); }, function ( xhr ) { // 当模型加载过程中,可以在回调函数中对加载的进度进行处理 console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' ); }, function ( error ) { // 当模型加载失败时,可以在回调函数中进行处理 console.error( error ); } );
在上面的代码中,我们先引入了three.js和GLTFLoader的库文件,然后创建了Three.js场景、相机和渲染器。接着创建了GLTFLoader实例,使用它的load方法异步加载gltf模型。load方法有四个参数:第一个参数是要加载的gltf文件的路径,第二个参数是加载完成后的回调函数,第三个参数是加载进度回调函数,第四个参数是加载失败回调函数。
当模型加载完成后,我们可以在回调函数中对模型进行处理,例如将它添加到场景中:
loader.load( 'models/mymodel.gltf', function ( gltf ) { // 将模型添加到场景中 scene.add( gltf.scene ); }, ... );
三、GLTF模型的组成部分
GLTF是一种面向Web的格式,它将3D模型分解成了几个部分,每个部分都是以JSON格式存储的。下面是GLTF模型的主要部分:
3D场景
整个3D场景是GLTF模型的根元素,存储了场景中所有的节点、光照、相机等信息。JSON格式的场景数据可以通过三个文件来存储:.gltf、.glb 和.bin文件。 .gltf是一个纯文本格式,包含了场景的所有信息,.glb文件则是二进制格式的,包含了所有的节点信息、二进制数据、材质文件等内容。
网格
网格是GLTF模型的物理实体,包括几何体数据和材质数据等信息。一个网格可以包含多个几何体,也可以使用同一个材质。
材质
材质控制了网格的外观,包括基础颜色、透明度、金属度、粗糙度、环境光遮蔽等属性。
纹理
纹理是一幅2D图片,用于给3D物体提供颜色、纹理、法线等信息。GLTF模型中的纹理可以被用于材质的漫反射、环境遮蔽、法线贴图等属性。
四、GLTF模型的优化
虽然GLTF模型已经被优化过了,但是在项目中,我们仍需要进一步优化模型以提高渲染效率和减少内存占用。
压缩纹理
纹理是3D模型中占用大量内存的元素之一。使用压缩纹理会大大减少内存占用,提高渲染效率。在Three.js中,我们可以使用CompressedTextureLoader加载已经被压缩的图片。
var textureLoader = new THREE.CompressedTextureLoader(); textureLoader.load( 'textures/texture.dds', function ( texture ) { // 在材质中使用压缩纹理 var material = new THREE.MeshBasicMaterial( { map: texture } ); } );
删除不必要的节点
在导出3D模型的过程中,一些不必要的节点可能也被导出了。我们可以在加载GLTF模型后,使用Three.js的API删除这些节点。
loader.load( 'models/mymodel.gltf', function ( gltf ) { // 遍历所有节点 for ( var i = 0; i < gltf.scene.children.length; i ++ ) { var node = gltf.scene.children[ i ]; // 如果节点名字包含”不必要节点“,就删除该节点 if ( node.name.indexOf( '不必要节点' ) !== -1 ) { gltf.scene.remove( node ); } } // 将模型添加到场景中 scene.add( gltf.scene ); } );
使用LOD(层级渐进式显示)技术
在渲染静态大型场景时,使用LOD技术可以提高渲染效率。该技术根据物体与相机的距离,渐进式地显示更为详细或简化的3D模型。
在Three.js中,我们可以使用THREE.LOD创建一个LOD对象,它包含一个或多个具有不同细节层次的对象。然后,我们可以使用addLevel方法,定义不同细节层次对象的距离范围和对应的模型对象。
var lod = new THREE.LOD(); // 创建3个不同细节层次的对象,最后一个细节对象为模型对象 var modelHighDetail = new THREE.Mesh(...); var modelMedDetail = new THREE.Mesh(...); var modelLowDetail = new THREE.Mesh(...); var model = new THREE.Mesh(...); // 将不同细节层次的对象添加到LOD对象中 lod.addLevel( modelHighDetail, 0 ); lod.addLevel( modelMedDetail, 100 ); lod.addLevel( modelLowDetail, 500 ); lod.addLevel( model, 1000 ); // 将LOD对象添加到场景中 scene.add( lod );
五、总结
本文阐述了使用Three.js的GLTFLoader加载gltf模型的方法,详细介绍了GLTF模型的组成部分、GLTF模型的优化方法与技巧。对于需要在Web上呈现3D模型的开发者来说,GLTF模型是在3D建模软件中构建3D模型之后的最佳输出格式之一,同时使用Three.js的GLTFLoader还可以很方便地对模型进行加载、显示和处理。