首页 前端知识 Uniapp中three.js初使用(加载fbx或者glb)

Uniapp中three.js初使用(加载fbx或者glb)

2024-09-28 23:09:54 前端知识 前端哥 107 670 我要收藏
  1. 安装three包,我选择的0.149.0版本 
     
    npm install --save three@0.149.0

  2. 页面引入three.js

    	import * as THREE from 'three'
    	import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js'
    	import {GLTFLoader} from 'three/examples/jsm/loaders/GLTFLoader.js';
    	import {FBXLoader} from 'three/examples/jsm/loaders/FBXLoader.js';

  3. 创建three.js场景

    init() {
    				// 创建一个场景
    				this.scene = new THREE.Scene()
    				//三位坐标线
    				// const axesHelper = new THREE.AxesHelper(5);
    				// this.scene.add(axesHelper);
    				//创建相机对象,45是相机的视角  , 宽高比是屏幕的宽高比 , 最近能看到0.1 , 最远能看到10000
    				// this.camera = new THREE.OrthographicCamera(-s * k, s * k, s , -s, 1, 1000);
    				// this.camera.position.set(0, 20, 300);
    				this.camera = new THREE.PerspectiveCamera()
    				//100,300 ,500
    				this.camera.position.set(500, 0, 700); //设置相机位置
    				// this.camera.position.set(100, -800, 500);
    				// this.scene.position.set(0,40,0)
    				console.log(this.scene.position)
    				this.camera.lookAt(this.scene.position); //设置相机方向(指向的场景对象)
    				// 执行一个渲染函数
    				this.rendererGLR()
    				/* 光源设置*/
    				this.pointLight()
    				this.clock = new THREE.Clock()
    				
    				//创建控件对象
    				this.change()
    				//更新轨道控件
    				this.animate()
    				let fileName = this.modelUrl.lastIndexOf(".")
    				let fileFormat = this.modelUrl.substring(fileName + 1, this.modelUrl.length).toLowerCase()
    				if (fileFormat == 'fbx') {
    					this.fbxLoader()
    				} else if(fileFormat == 'glb') {
    					this.gblLoader()
    				}
    				this.renderer.render(this.scene, this.camera);
    			},

  4. 渲染

    //渲染函数
    			rendererGLR(){ 
    				this.$nextTick(() => {
    					const element = document.getElementById('threeView')
    					this.renderer.setSize(element.clientWidth, element.clientHeight);
    					element.appendChild(this.renderer.domElement);
    				})
    				this.renderer = new THREE.WebGLRenderer({alpha:true, antialias: true});//alpha:true背景透明
    				this.renderer.setPixelRatio( window.devicePixelRatio * 2);
    				this.renderer.toneMapping = THREE.ACESFilmicToneMapping;
    				this.renderer.toneMappingExposure = 1.0;
    				this.renderer.shadowMap.enabled = true;
    				this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
    			},

  5. 设置光源 (我这边设置的是四束光源)

    let ambientLight = new THREE.AmbientLight(0xffffff,1);
    	this.scene.add(ambientLight);
    	const directional_light = new THREE.DirectionalLight( 0xffffff, 1 );
    	directional_light.position.set( 0, 1, 0 ); 
    	directional_light.castShadow = true; 
    	this.scene.add(directional_light);
    	let a=1,b=0.6,c=10;
    	let directionalLight1 = new THREE.DirectionalLight(0xffffff,b);
    	directionalLight1.position.set(-a,-a ,a*c).normalize();
    	let directionalLight2 = new THREE.DirectionalLight(0xffffff,b);
    	directionalLight2.position.set(a,-a,-a*c).normalize();
    	let directionalLight3 = new THREE.DirectionalLight(0xffffff,b);
    	directionalLight3.position.set(-a,a,-a*c).normalize();
    	let directionalLight4 = new THREE.DirectionalLight(0xffffff,b);
    	directionalLight4.position.set(a,a,a*c).normalize();
    	this.scene.add(directionalLight1);
    	this.scene.add(directionalLight2);
    	this.scene.add(directionalLight3);
    	this.scene.add(directionalLight4);

  6. 创建控件对象,这步主要是为了可以手动控制3D旋转,放大缩小等效果

    //创建控件对象
    			change(){
    				this.controls = new OrbitControls(this.camera, this.renderer.domElement);
    				this.controls.minDistance = 300
    				this.controls.maxDistance  = 1000
    				this.controls.addEventListener('change', () => {
    					this.renderer.render(this.scene, this.camera);
    				}); //监听鼠标、键盘事件
    				//禁止缩放
    				this.controls.enableZoom = this.changeFlag
    				//禁止旋转
    				this.controls.enableRotate = this.changeFlag
    				//禁止右键拖拽
    				this.controls.enablePan  = this.changeFlag
    			},

  7. 创建轨道控件(这一步是为了3D效果自旋转)

    //更新轨道控件
    			animate() {
    				if (this.renderer) {
    					// console.log(this.stats)
    					// this.stats.update()
    					let T = this.clock.getDelta()
    					let renderT = 1 / 30
    					this.timeS = this.timeS + T
    					if(this.timeS > renderT) {
    						this.controls.update();
    						this.renderer.render(this.scene, this.camera);
    						this.timeS = 0
    					}
    					requestAnimationFrame(this.animate);
    					if (!this.changeFlag) {
    						this.controls.autoRotateSpeed = 15
    					}
    					this.controls.autoRotate = true // 是否自动旋转
    				}
    				//创建一个时钟对象
    				// this.clock = new THREE.Clock()
    				// this.scene.rotateY(0.01)
    				//获得两帧的时间间隔  更新混合器相关的时间
    				// if (this.mixer) {this.mixer.update(this.clock.getDelta())}
    			},

  8. 根据不同的文件类型使用不同的方法导入

    //导入FBX模型文件
    			fbxLoader(){
    				let that=this
    				const loader = new FBXLoader();
    				loader.load(this.modelUrl,function(mesh){
    					that.scene.add(mesh);
    					that.ownerInstance.callMethod('onload')
    				})
    			},
    			//导入GLB模型文件
    			gblLoader(){
    				let that=this
    				const loader = new GLTFLoader();
    				loader.load(this.modelUrl, function(gltf) {
    					console.log(gltf)
    					that.mesh = gltf.scene
    					let model = gltf.scene
    					that.scene.add(model);
    					that.ownerInstance.callMethod('onload')
    				});
    			},

  9. 注意事项:该效果在uniapp只能在H5运行,在APP运行需要使用renderjs 这个我后续应该会有文章出来说明

转载请注明出处或者链接地址:https://www.qianduange.cn//article/18680.html
标签
评论
发布的文章
大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!