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。
都看到这里了,记得【点赞】+【关注】哟。
参考文档:
更多推荐
所有评论(0)