vue+three.js 加载fbx动画模型

        嗨,我是小路。今天主要和大家分享的主题是“vue+three.js 加载fbx动画模型”。        

在现代网页开发中,3D 图形和动画的应用越来越广泛,从产品展示、虚拟展厅到游戏、教育等领域,三维技术正在不断刷新用户体验。而作为前端开发者,如何将高性能的 3D 动画无缝集成到 Vue 项目中?今天从网上找了一个fbx动画模型,然后将其加载出来,并让模型动起来。

项目示意图

1.FBXLoader加载器

定义:主要用来加载fbx格式的动画模型。

二、实例代码

<!--
**加载fbx文件
-->
<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';
// 引入gltf模型加载库GLTFLoader.js
import { FBXLoader } from 'three/addons/loaders/FBXLoader';const bgColor = ref("")const leftRef = ref();
const rightRef = ref()
// 定义相机输出画布的尺寸(单位:像素px)
let width = 800; //宽度
let height = window.innerHeight; //高度const clock = new THREE.Clock();
// 创建FBX加载器对象
const loader = new FBXLoader();// 创建3D场景对象Scene
let scene,camera,spotLight,renderer,ambient,controls ;
const initThree = () => {scene = new THREE.Scene();//设置背景色scene.background = new THREE.Color("#dfe9f3");camera = new THREE.PerspectiveCamera(50, width / height, 2, 6000);// 根据需要设置相机位置具体值camera.position.set(200, 200, 200);spotLight = new THREE.SpotLight(0xffffff, 1.0);scene.add(spotLight);//光源添加到场景中renderer = new THREE.WebGLRenderer();//环境光:没有特定方向,整体改变场景的光照明暗ambient = new THREE.AmbientLight(0xffffff, 0.4);scene.add(ambient);renderer.setSize(width, height); //设置three.js渲染区域的尺寸(像素px)leftRef.value.append(renderer.domElement);//添加相机空间controls = new OrbitControls(camera, renderer.domElement);// 如果OrbitControls改变了相机参数,重新调用渲染器渲染三维场景controls.addEventListener('change', function () {renderer.render(scene, camera); //执行渲染操作});//监听鼠标、键盘事件
}const modelObj = reactive({ index: 1, url: './models/animate.fbx' });onMounted(() => {initThree();loadGltfData();render();// 处理窗口大小变化 只需要设置相机 和重新渲染window.addEventListener("resize", () => {camera.aspect = width / window.innerHeight;camera.updateProjectionMatrix();renderer.setSize(width, window.innerHeight);});
})let mixer = "";
let action = "";//加载gltf模型
const loadGltfData = () => {modelObj.url && loader.load(modelObj.url, function (fbx) {fbx.scale.setScalar(1); // 调整模型大小fbx.position.set(0, -100, 0); // 调整模型位置// 创建动画混合器mixer = new THREE.AnimationMixer(fbx);// 播放所有动画const animations = fbx.animations;if (animations && animations.length > 0) {action = mixer.clipAction(animations[0]);action.play();}//获取模型的长、宽、高let scale = getScale(fbx)//同比例放大,模型不变形fbx.scale.setScalar(scale)scene.add(fbx);}, 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);//以屏幕的一般高度为放缩比例let scale = (height/8)/size.z;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: #dfe9f3;}
}
</style>

三、复盘总结

       1、fbx动画模型加载和glft模型加载思路是一样的,需要注意的是在加载模型的处理。gltf有是加载gltf.scene;而fbx是将本身添加到scene。

        2、注意代码的封装。当使用代码越多,越要将其中的部分代码进行封装,用作为了开发的储备,这样遇到问题,可以直接从自己的练习库中寻找。编程做到最后,自然就是越做越轻松。也许后期,真的可以cltr+c + cltr+v。

都看到这里了,记得【点赞】+【关注】哟。

参考文档:

threeJs+vue 加载gltf模型、获取模型尺寸、播放模型动画-CSDN博客