threeJs+vue加载gltf模型、获取模型尺寸、播放模型动画
- IT业界
- 2025-09-19 10:03:01

嗨,我是小路。今天主要和大家分享的主题是“threeJs+vue 加载gltf模型”。
加载GLTF模型到基于Three.js和Vue的项目中是一个常见的需求,特别是在开发需要展示高质量3D内容的应用时。下面,我将提供一个详细的指南,帮助你了解如何在Vue项目中使用Three.js加载GLTF模型。
示例效果图
一、主要属性 1.gltf格式定义:gltf格式就相当于图片的jpg格式一样。并且gltf格式文件中有三种文件.txt、.bin、.gltf。
txt:主要是对文件的一些说明。
.bin:是二进制文件,主要存放着模型的一些顶点书
.gltf:主要是存放的json格式数据,里面有各种模型信息。如控制器、动画、资产,缓冲数据,使用的扩展、贴图图片、模型材料信息、网格、取样器、场景、纹理等。
2.gltf模型加载器注意:加载模型之后,一些纹理会有偏差,这个时候在渲染时,加入一下代码,解决这个问题。还有模型在加载时,会有三种不同的状态:加载成功、加载中、加载失败。
加载中:用来记录模型加载的进度。当加载大型的模型的时候,可以根据加载的进度,显示在显示条上。
加载完成:是加载成功后对模型进行处理。如模型的位置、模型的大小等等
加载失败:记录失败的原因,便于开发调试。
//解决加载gltf格式模型纹理贴图和原图不一样问题 renderer.outputEncoding = THREE.sRGBEncoding; // 创建GLTF加载器对象 const loader = new GLTFLoader(); //加载gltf模型 const loadGltfData = () => { //加载模型 modelObj.url && loader.load(modelObj.url, function (gltf) { console.log(gltf) //加载完成 //设置模型的位置 gltf.scene.position.set(10, 0, 0); // 播放模型动画 if (gltf.animations && gltf.animations.length) { mixer = new THREE.AnimationMixer(gltf.scene); action = mixer.clipAction(gltf.animations[0]); // 获取第一个动画剪辑 action.play(); // 播放动画 } //获取模型的长、宽、高 let scale = getScale(gltf.scene) //同比例放大,模型不变形 gltf.scene.scale.set(scale,scale,scale) scene.add(gltf.scene); }, function (xhr) { //加载时 console.log((xhr.loaded / xhr.total * 100) + '% loaded'); }, function (error) { console.log('加载失败', error); }) } 3.播放动画定义:three.js默认加载模型是不播放的,只有自己去设置才能播放。以下是播放的模型动画代码:
// 播放模型动画 if (gltf.animations && gltf.animations.length) { mixer = new THREE.AnimationMixer(gltf.scene); action = mixer.clipAction(gltf.animations[0]); // 获取第一个动画剪辑 action.play(); // 播放动画 } 二、实例代码 1、获取模型长宽高 //获取模型长宽高 const getScale = (model)=>{ // 计算模型的边界框 const box = new THREE.Box3().setFromObject(model); // 获取边界框的尺寸 const size = new THREE.Vector3(); box.getSize(size); console.log('height',height) console.log('width',width) console.log('x',size.x) console.log('y',size.y) console.log('z',size.z) //以屏幕的一般高度为放缩比例 let scale = (height/2)/size.z; console.log('scale',scale) return scale; } 2、示例代码 <template> <div class="pageBox"> <div class="leftBox" ref="leftRef"></div> <div class="rightBox" ref="rightRef" :style="{ background: bgColor }"></div> </div> </template> <script setup> import { onMounted, reactive, ref } from 'vue'; import * as THREE from 'three'; // 引入轨道控制器扩展库OrbitControls.js import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; // 设置相机控件轨道控制器OrbitControls // 引入gltf模型加载库GLTFLoader.js import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; const bgColor = ref("") //实例化一个gui对象 // const gui = new GUI(); const leftRef = ref(); const rightRef = ref() // 定义相机输出画布的尺寸(单位:像素px) let width = 800; //宽度 let height = window.innerHeight; //高度 // 创建3D场景对象Scene const scene = new THREE.Scene(); //设置背景色 scene.background = new THREE.Color("#ffffff"); // 实例化一个透视投影相机对象 const camera = new THREE.PerspectiveCamera(50, width / height, 2, 6000); //======================================================= const spotLight = new THREE.SpotLight(0xffffff, 1.0); const clock = new THREE.Clock(); //=============================================== // 创建GLTF加载器对象 const loader = new GLTFLoader(); // 创建渲染器对象 const renderer = new THREE.WebGLRenderer(); const modelObj = reactive({ index:1,url: './models/gir2/scene.gltf' }); onMounted(() => { initData() render(); //添加相机空间 const controls = new OrbitControls(camera, renderer.domElement); // 如果OrbitControls改变了相机参数,重新调用渲染器渲染三维场景 controls.addEventListener('change', function () { renderer.render(scene, camera); //执行渲染操作 });//监听鼠标、键盘事件 }) const initData = () => { //环境光:没有特定方向,整体改变场景的光照明暗 const ambient = new THREE.AmbientLight(0xffffff, 0.4); scene.add(ambient); scene.add(spotLight);//光源添加到场景中 // 根据需要设置相机位置具体值 camera.position.set(200, 200, 200); loadGltfData(); renderer.setSize(width, height); //设置three.js渲染区域的尺寸(像素px) //将innerHTML置空,避免append重复添加渲染 leftRef.value.innerHTML = '' leftRef.value.append(renderer.domElement); } let mixer = ""; let action = ""; //加载gltf模型 const loadGltfData = () => { modelObj.url && loader.load(modelObj.url, function (gltf) { console.log(gltf) //加载完成 //设置模型的位置 gltf.scene.position.set(10, 0, 0); // 播放模型动画 if (gltf.animations && gltf.animations.length) { mixer = new THREE.AnimationMixer(gltf.scene); action = mixer.clipAction(gltf.animations[0]); // 获取第一个动画剪辑 action.play(); // 播放动画 } //获取模型的长、宽、高 let scale = getScale(gltf.scene) //同比例放大,模型不变形 gltf.scene.scale.set(scale,scale,scale) scene.add(gltf.scene); }, function (xhr) { //加载时 console.log((xhr.loaded / xhr.total * 100) + '% loaded'); }, function (error) { console.log('加载失败', error); }) } //获取模型长宽高 const getScale = (model)=>{ // 计算模型的边界框 const box = new THREE.Box3().setFromObject(model); // 获取边界框的尺寸 const size = new THREE.Vector3(); box.getSize(size); console.log('height',height) console.log('width',width) console.log('x',size.x) console.log('y',size.y) console.log('z',size.z) //以屏幕的一般高度为放缩比例 let scale = (height/2)/size.z; console.log('scale',scale) return scale; } //渲染 const render = () => { //解决加载gltf格式模型纹理贴图和原图不一样问题 renderer.outputEncoding = THREE.sRGBEncoding; mixer ? mixer.update(clock.getDelta()) : null; renderer.render(scene, camera); //执行渲染操作 //重复渲染 requestAnimationFrame(render);//请求再次执行渲染函数render,渲染下一帧 } </script> <style scoped lang="less"> .pageBox { width: 100%; height: 100vh; padding: 0; margin: 0; display: flex; justify-content: space-between; align-items: center; .rightBox { width: 100%; height: 100%; background: yellow; } } </style> 三、注意事项 1.光源一定要添加注意:大部分的材料都是和光相关的材料,所以在添加模型时,需要添加光源,这样模型才会显示正常的颜色,不然模型会呈现黑色。
2.设置模型的大小注意:屏幕的宽度会随着屏幕的宽度进行变动,一般设置都是按照屏幕的高度,等比例缩放(x、y、z都要同比例缩放)。如果不清楚设置多少的比例,可以参考获取模型长宽高的代码。
都看到这里了,记得【点赞】+【关注】哟。
threeJs+vue加载gltf模型、获取模型尺寸、播放模型动画由讯客互联IT业界栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“threeJs+vue加载gltf模型、获取模型尺寸、播放模型动画”
上一篇
样式和ui(待更新)