这一节我们来通过Threejs加载一个glft格式的三维模型文件,首先我们先简单了解下gltf文件
gltf文件全称Graphics Language Transmission Forma(图形语言传输格式),是一种三维模型格式,用于传输和加载3D场景和模型;其号称是图形界的JPEG,能够实现快速的模型数据交换。
gltf文件核心是JSON文件,一个gltf文件可传输一个或多个场景, 包括网格、材质、贴图、蒙皮、骨架、变形目标、动画、灯光以及摄像机等信息。
下面通过代码实现加载一个gltf格式的文件到场景中,首先还是需要创建场景、相机、渲染器等初始化代码,具体步骤查看前面章节,代码如下
import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
// 定义变量
let scene,camera,renderer
let axesHelper
let hesLight,dirLight,sportLight
let controls
// 初始化场景
initScene()
// 初始化辅助轴
initAxesHelper()
// 初始化灯光
initLight()
// 初始化mesh
initMesh()
// 初始化相机
initCamera()
// 初始化渲染器
initRenderer()
// 循环动画
animate()
// 初始化轨道控制器
initControls()
window.addEventListener('resize',function() {
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
renderer.setSize(window.innerWidth,window.innerHeight)
})
function initScene() {
scene = new THREE.Scene()
scene.background = new THREE.Color(0xa0a0a0)
}
function initAxesHelper() {
axesHelper = new THREE.AxesHelper(5)
scene.add(axesHelper)
}
function initLight() {
hesLight = new THREE.HemisphereLight(0xffffff,0x444444)
hesLight.intensity = 0.6
scene.add(hesLight)
dirLight = new THREE.DirectionalLight()
dirLight.position.set(5,5,5)
scene.add(dirLight)
sportLight = new THREE.SpotLight(0xffffff)
sportLight.position.set(0,10,10)
scene.add(sportLight)
}
function initMesh() {
}
function initCamera() {
camera = new THREE.PerspectiveCamera(75,window.innerWidth / window.innerHeight,0.1,100)
camera.position.set(1.5,1.5,1.5)
}
function initRenderer() {
renderer = new THREE.WebGLRenderer({antialias:true})
renderer.setPixelRatio(window.devicePixelRatio)
renderer.setSize(window.innerWidth,window.innerHeight)
document.body.appendChild(renderer.domElement)
}
function initControls() {
controls = new OrbitControls(camera, renderer.domElement)
}
function animate() {
requestAnimationFrame(animate)
renderer.render(scene,camera)
}在index.js中顶部引入GLTFLoader 加载器
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'在initMesh() 函数中定义一个变量loader,该变量用于接收GLTFLoader实例
const loader = new GLTFLoader()通过loader的load方法来加载gltf文件,load方法的详细参数如下 .load ( url : String, onLoad : Function, onProgress : Function, onError : Function ) url — 包含有.gltf/.glb文件路径/URL的字符串。 onLoad — 加载成功完成后将会被调用的函数。该函数接收parse所返回的已加载的JSON响应。 onProgress — (可选)加载正在进行过程中会被调用的函数。其参数将会是XMLHttpRequest实例,包含有总字节数.total与已加载的字节数.loaded。 onError — (可选)若在加载过程发生错误,将被调用的函数。该函数接收error来作为参数。
这里我们在加载gltf文件成功后,打印该gltf,看下里面的数据结构,并在加载成功后,将其加入到scene中
loader.load('../models/motor03.gltf',function(gltf) {
console.log(gltf);
scene.add(gltf.scene)
})刷新浏览器,查看效果,同时打开调试工具,查看gltf打印的数据结构

鼠标旋转发现,图像颜色与原本的gltf文件颜色有偏差,这里只需要修改WebGL渲染器默认的编码方式.outputEncoding就可以了 在initRenderer()函数中加入如下代码
//解决加载gltf格式模型纹理贴图和原图不一样问题
renderer.outputEncoding = THREE.sRGBEncoding;再次刷新浏览器,看效果

通过在控制台打印gltf我们可以看到,该gltf文件里面包含一个scene,scene文件目录如下

我们可以在material中看到color字段,通过该字段我们可以修改各个材质的颜色,在上面loader.load的回调函数中,添加如下代码
const motorMesh = gltf.scene.children[0].children
motorMesh[0].material.color = new THREE.Color(0x000000)刷新浏览器,可以看到motorMesh[0]材质的颜色已经改变为黑色

ok,搞定收工,喜欢的朋友,动动你发财的小手点赞关注收藏哦