记录–uniapp微信小程序引入threeJs并导入模型

  • 记录–uniapp微信小程序引入threeJs并导入模型已关闭评论
  • 215 次浏览
  • A+
所属分类:Web前端
摘要

我的建议是使用这个库
https://github.com/deepkolos/three-platformize
为什么?我试了uniapp推荐的和threejs-miniprogram这个小程序官方库,都加载不出来我的obj模型。所有我推荐不要用obj模型最好,挺多都支持GLTF模型的,但是我不能改。


这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

记录--uniapp微信小程序引入threeJs并导入模型

前言

我的需求是使用uniapp写微信小程序,在小程序中使用threeJs就行了,目前暂不考虑兼容app什么的。 1.引入小程序版的threejs库实现 2.使用webview实现(推荐)

重点

我的建议是使用这个库
https://github.com/deepkolos/three-platformize
为什么?我试了uniapp推荐的和threejs-miniprogram这个小程序官方库,都加载不出来我的obj模型。所有我推荐不要用obj模型最好,挺多都支持GLTF模型的,但是我不能改。

使用three-platformize加载obj模型的案例:

记录--uniapp微信小程序引入threeJs并导入模型

 核心代码:

html: <canvas type="webgl" id="webgl" style="width: 100vw; height: 100vh;"  	@touchstart="touchStart"  	@touchmove="touchMove"  	@touchend="touchEnd" /> script: <script> 	import * as THREE from 'three-platformize'; 	import { WechatPlatform } from 'three-platformize/src/WechatPlatform'; 	import { OBJLoader } from 'three-platformize/examples/jsm/loaders/OBJLoader'; 	import { GLTFLoader } from 'three-platformize/examples/jsm/loaders/GLTFLoader'; 	import {OrbitControls} from 'three-platformize/examples/jsm/controls/OrbitControls'; 	export default { 		data() { 			return { 				canvas:null, 				camera:null, 				scene:null, 				renderer:null, 				model:null, 				controls:null, 				loopIndex:null 			} 		}, 		onLoad() {  		}, 		methods: { 			async init() {  				const { canvas }= await this.getCanvas(); 				this.canvas = canvas; 				const platform = new WechatPlatform(canvas); // webgl canvas 				platform.enableDeviceOrientation('game'); // 开启DeviceOrientation 				THREE.PLATFORM.set(platform); 				this.platform = platform; 				this.renderModel(); 		    }, 			//获取画布 			async getCanvas(delay = 200) { 			  return new Promise((resolve, reject) => { 				const t = setTimeout(() => { 				  clearTimeout(t); 				  uni.createSelectorQuery().in(this) 					.select('#webgl') 					.fields({ node: true }) 					.exec((res) => { 						console.log('res',res) 					  if (res && res[0] && res[0].node) { 						const canvas = res[0].node; 						resolve({ canvas }); 					  } else { 						reject("获取canvas失败"); 					  } 					}); 				}, delay); 			  }); 			}, 			renderModel () { 				this.camera = new THREE.PerspectiveCamera(45, this.canvas.width / this.canvas.height, 0.25, 100); 				this.camera.position.set(- 5, 3, 10); 				this.camera.lookAt(new THREE.Vector3(0, 2, 0)); 				this.scene = new THREE.Scene(); 				this.scene.background = new THREE.Color(0xe0e0e0); 				this.scene.fog = new THREE.Fog(0xe0e0e0, 20, 100); 				this.clock = new THREE.Clock(); 				// lights 				var light = new THREE.HemisphereLight(0xffffff, 0x444444); 				light.position.set(0, 20, 0); 				this.scene.add(light); 				// 改变外壳颜色 				var AmbientLight = new THREE.AmbientLight(0x815800); // 环境光 				this.scene.add(AmbientLight); 				// 平行光 				light = new THREE.DirectionalLight(0xffffff); 				light.position.set(0, 20, 10); 				this.scene.add(light); 				// // ground 				// var mesh = new THREE.Mesh(new THREE.PlaneBufferGeometry(2000, 2000), new THREE.MeshPhongMaterial({ color: 0x999999, depthWrite: false })); 				// mesh.rotation.x = - Math.PI / 2; 				// this.scene.add(mesh); 				// var grid = new THREE.GridHelper(200, 40, 0x000000, 0x000000); 				// grid.material.opacity = 0.6; 				// grid.material.transparent = true; 				// this.scene.add(grid); 				// model 				var loader = new OBJLoader(); 				loader.load('http://localhost:8888/obj3/file.obj', (obj) => { 					console.log("obj+=") 					console.log(obj) 					// console.log(this.model) 					obj.position.set(0, -2, 0);//模型摆放的位置 					obj.scale.set(0.2, 0.2, 0.2); 					// this.model = obj; 					this.scene.add(obj); 				}, undefined, function (e) { 					console.log("模型加载错误") 					console.error(e); 				}); 				// var loader = new GLTFLoader(); 				// 	loader.load('https://dtmall-tel.alicdn.com/edgeComputingConfig/upload_models/1591673169101/RobotExpressive.glb', (gltf) => { 				// 		this.model = gltf.scene; 				// 		this.scene.add(this.model); 				// 	}, undefined, function (e) { 				// 		console.error(e); 		  //       }); 				// var geometry = new THREE.BoxGeometry( 5, 5, 5 ); 				// var material = new THREE.MeshBasicMaterial( {color: 0x00ff00} ); 				// var mesh = new THREE.Mesh( geometry, material ); 				// this.scene.add(mesh); 		 				this.renderer = new THREE.WebGLRenderer({antialias: true }); 				this.renderer.setPixelRatio(wx.getSystemInfoSync().pixelRatio); 				this.renderer.setSize(this.canvas.width, this.canvas.height); 				//this.renderer.outputEncoding = true; 				this.renderer.gammaFactor = 2.2; 		 				this.controls = new OrbitControls(this.camera, this.renderer.domElement ); 				this.camera.position.set( 5, 5, 10 ); 				this.animate(); 			}, 		animate() { 		        this.loopIndex = this.canvas.requestAnimationFrame(this.animate); 		        this.renderer.render(this.scene, this.camera); 		        this.controls.update(); 		    }, 		 		    touchStart(e) { 		        this.platform.dispatchTouchEvent(e); 		    }, 		    touchMove(e) { 		        this.platform.dispatchTouchEvent(e); 		    }, 		    touchEnd(e) { 		        this.platform.dispatchTouchEvent(e); 		    } 		}, 		mounted() { 			this.$nextTick(()=>  { 			      this.init(); 			    }); 		} 	} </script>

上面的案例中使用了两个模型,一个obj模型,obj模型的地址是自己写的本地服务器地址,需要自己配置,GLTF模型地址是网络地址,可以把注释解开查看。

注意点

1.加载外部模型与threeJs官网api是一致的
2.使用此方法加载外部模型,可能在真机调试时遇到模型不展示,或者微信闪退的情况(原因未知)

webview实现引入threejs库

效果图

记录--uniapp微信小程序引入threeJs并导入模型

实现:
1.使用vue实现threejs导入obj模型(pc端可完美实现),
2.在webview中引入相应的模型展示地址,

完结,就这两步即可,但是我是动态加载,所以在加载模型的时候,你需要在小程序端传值给pc端,让pc端加载相应的模型,这里就只需要用get在地址栏中传参就行了。

以下两个方法可能会用到:
1.模型大小自适应

setScaleToFitSize (obj) {       const boxHelper = new THREE.BoxHelper(obj);       boxHelper.geometry.computeBoundingBox();       const box = boxHelper.geometry.boundingBox;       const maxDiameter = Math.max((box.max.x - box.min.x), (box.max.y - box.min.y), (box.max.z - box.min.z));       const scaleValue = camera.position.z / maxDiameter;       obj.position.set(0, -10, 0);//模型摆放的位置       obj.scale.set(scaleValue, scaleValue, scaleValue);       scene.add(obj);     },

2.禁止小程序展示webview时候向下拉动:
mounted中添加:

document.body.addEventListener('touchmove', function (e) {         e.preventDefault();       }, { passive: false });

本文转载于:

https://blog.csdn.net/hzqzzz/article/details/126428029

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

 记录--uniapp微信小程序引入threeJs并导入模型