threejs加载FBX模型uniapp版,带加载进度条,开箱即用

230 阅读1分钟

1、uniapp创建使用vue3

2、安装three运行 npm i three

3、替换模型加载器和链接加载不同的模型

4、效果图

<template>
	<view class="three" ref="webgl"></view>
	<view class="progress" v-if="percent < 100">
		<progress class="pr" :percent="percent" />
	</view>
</template>

<script setup>
	// 引入three.js
	import * as THREE from 'three';
	// 引入扩展库OrbitControls.js
	import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
	// 引入扩展库FBXLoader.js
	import { FBXLoader } from 'three/addons/loaders/FBXLoader.js';
	import { ref } from 'vue';
	import { onLoad,onReady, onUnload } from '@dcloudio/uni-app'
	const webgl  = ref(null)
	// 创建GLTF加载器对象
	const loader = new FBXLoader();
	//场景
	const scene  = new THREE.Scene();
	const mid    = ref('08')
	const percent= ref(0)
	onLoad(options => {
		if (options.id) {
			mid.value = options.id
		}
	})
	function init(object) {
		const el     = webgl.value.$el
		const width  = el.clientWidth
		const height = el.clientHeight
		//相机视角
		const camera = new THREE.PerspectiveCamera(
		    50, 
		    width / height, 
		    0.1, 
		    2000
		);    
		camera.position.z = 1;
		// camera.position.set(200, 200, 200);
		// camera.lookAt(0, 0, 0);
		//光源
		const ambientLight     = new THREE.AmbientLight(0xffffff,30.5);
		scene.add(ambientLight);
		// 平行光
		const directionalLight = new THREE.DirectionalLight(0xffffff, 10);
		directionalLight.position.set(80, 100, 50);
		scene.add(directionalLight);
		//加载模型
		scene.add(object);     
		//渲染器
		const renderer = new THREE.WebGLRenderer( { antialias: true, alpha: true } );
		//解决加载gltf格式模型纹理贴图和原图不一样问题
		renderer.setPixelRatio(devicePixelRatio);
		renderer.setSize(width, height);
		//设置背景为透明,这样就可以自己加背景图片了
		renderer.setClearAlpha(0);
                //渲染加载到dom
		el.appendChild(renderer.domElement)
		
		const controls = new OrbitControls(camera, renderer.domElement);
		//手势控制器
		controls.autoRotate = true;
		controls.enablePan = false;
		controls.maxDistance = 2;
		controls.minDistance = 0.5;
		controls.update();
		
		//60帧动画,360°自动旋转模型
		(function animate() {  
		    requestAnimationFrame(animate);  
		    controls.update();  
		    renderer.render(scene, camera);
		})()
	}
	
	function load() {
		loader.load(
		    //模型的链接地址,这里的地址必须使用线上地址或者使用本地服务器
		    'https://xxxx.fbx',
		    object => {
				init(object)
		    },
		    //加载进度
		    xhr => {
				console.log(xhr); 
		        percent.value = parseInt(( xhr.loaded / xhr.total * 100 ));    
		    },    
		    error => {      
		        console.error(error);    
		    }
		);
	}
	
	onReady(() => {
		load()
	})

	//页面卸载的时候清掉缓存和模型数据
	onUnload(() => {
		THREE.Cache.clear();
		renderer.dispose();  
		renderer.forceContextLoss();  
		renderer.domElement = null;  
		renderer = null;
	})

</script>

<style>
	.three {
		width: 100vw;
		height: 100vh;
		background-color: #efefef;
	}
	.progress {
		position: fixed;
		top: 0;
		bottom: 0;
		left: 20rpx;
		right: 20rpx;
		z-index: 999;
		display: flex;
		align-items: center;
		justify-content: center;
	}
	.pr {
		width: 100%;
	}
</style>