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

9,406次阅读
没有评论

共计 4068 个字符,预计需要花费 11 分钟才能阅读完成。

  • 安装 three 包,我选择的 0.149.0 版本 
     
    npm install --save three@0.149.0
  • 页面引入 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';
  • 创建 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);
    			},
  • 渲染

    // 渲染函数
    			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;
    			},
  • 设置光源(我这边设置的是四束光源)

    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);
  • 创建控件对象,这步主要是为了可以手动控制 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
    			},
  • 创建轨道控件(这一步是为了 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())}
    			},
  • 根据不同的文件类型使用不同的方法导入

    // 导入 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')
    				});
    			},
  • 注意事项:该效果在 uniapp 只能在 H5 运行,在 APP 运行需要使用 renderjs 这个我后续应该会有文章出来说明

  • 原文地址: Uniapp 中 three.js 初使用(加载 fbx 或者 glb)

      正文完
       0
      Yojack
      版权声明:本篇文章由 Yojack 于2024-10-07发表,共计4068字。
      转载说明:
      1 本网站名称:优杰开发笔记
      2 本站永久网址:https://yojack.cn
      3 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行删除处理。
      4 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
      5 本站所有内容均可转载及分享, 但请注明出处
      6 我们始终尊重原创作者的版权,所有文章在发布时,均尽可能注明出处与作者。
      7 站长邮箱:laylwenl@gmail.com
      评论(没有评论)