記錄--uniapp微信小程式引入threeJs並導入模型

来源:https://www.cnblogs.com/smileZAZ/archive/2022/11/28/16932638.html
-Advertisement-
Play Games

這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 前言 我的需求是使用uniapp寫微信小程式,在小程式中使用threeJs就行了,目前暫不考慮相容app什麼的。 1.引入小程式版的threejs庫實現 2.使用webview實現(推薦) 重點 我的建議是使用這個庫https://git ...


這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助

前言

我的需求是使用uniapp寫微信小程式,在小程式中使用threeJs就行了,目前暫不考慮相容app什麼的。
1.引入小程式版的threejs庫實現
2.使用webview實現(推薦)

重點

我的建議是使用這個庫
https://github.com/deepkolos/three-platformize
為什麼?我試了uniapp推薦的和threejs-miniprogram這個小程式官方庫,都載入不出來我的obj模型。所有我推薦不要用obj模型最好,挺多都支持GLTF模型的,但是我不能改。

使用three-platformize載入obj模型的案例:

 核心代碼:

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庫

效果圖

實現:
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

如果對您有所幫助,歡迎您點個關註,我會定時更新技術文檔,大家一起討論學習,一起進步。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 首發微信公眾號:SQL資料庫運維 原文鏈接:https://mp.weixin.qq.com/s?__biz=MzI1NTQyNzg3MQ==&mid=2247485212&idx=1&sn=450e9e94fa709b5eeff0de371c62072b&chksm=ea37536cdd40da7 ...
  • 導語 VPN是一種通過公網連接兩個或多個私網站點的專用網路,使得這些站點仿佛是通過專線連接在一起。IPSec是一套協議框架,用於保證數據傳輸的私密性,完整性,真實性。但是VPN網路經常會帶來一些連通性上的問題,通常與MTU設置的不合理有關。本文通過一個實際案例,來具體分析解決這個問題。 作者:陸信宇 ...
  • 作者:vivo 互聯網存儲技術團隊- Qiu Sidi 在企業大數據體系建設過程中,數據採集是其中的首要環節。然而,當前行業內的相關開源數據採集組件,並無法滿足企業大規模數據採集的需求與有效的數據採集治理,所以大部分企業都採用自研開發採集組件的方式。本文通過在vivo的日誌採集服務的設計實踐經驗,為 ...
  • 版權聲明:原創不易,本文禁止抄襲、轉載,侵權必究! 一、DBeaver簡介 DBeaver是一個通用的資料庫管理工具和 SQL 客戶端,社區版的DBeaver只能連接關係型資料庫,比如MySQL、Oracle等,只有企業版以上才能連接非關係型資料庫,比如MongoDB、Redis等;DBeaver ...
  • 原文:Jitpack發佈Android庫出現Direct local .aar file dependencies are not supported when building an AAR - Stars-One的雜貨小窩 問題描述 由於我項目中某個Module引用了本地的aar文件,導致出現了 ...
  • 文章主要闡述了優先順序反轉的一些概念和解決思路,並結合iOS平臺的幾種鎖進行了詳細的調研。通過深入的理解,可以去規避一些不必要的優先順序反轉,從而進一步避免卡死異常。 ...
  • ...
  • 前言 由於工作需要,要抓取tb上某個介面的文案資源,用來分析借鑒。 本來想著,無非就是驗證一下當前用戶信息之類的,但在研究過後,發現並沒那麼簡單。 1,查看請求相關參數 比如下圖,發現請求中攜帶的參數不少,然後其中隨時變化的就有t、sign、data, 很明顯,這就是tb判斷請求是否合法的參數,其中 ...
一周排行
    -Advertisement-
    Play Games
  • GoF之工廠模式 @目錄GoF之工廠模式每博一文案1. 簡單說明“23種設計模式”1.2 介紹工廠模式的三種形態1.3 簡單工廠模式(靜態工廠模式)1.3.1 簡單工廠模式的優缺點:1.4 工廠方法模式1.4.1 工廠方法模式的優缺點:1.5 抽象工廠模式1.6 抽象工廠模式的優缺點:2. 總結:3 ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 本章將和大家分享ES的數據同步方案和ES集群相關知識。廢話不多說,下麵我們直接進入主題。 一、ES數據同步 1、數據同步問題 Elasticsearch中的酒店數據來自於mysql資料庫,因此mysql數據發生改變時,Elasticsearch也必須跟著改變,這個就是Elasticsearch與my ...
  • 引言 在我們之前的文章中介紹過使用Bogus生成模擬測試數據,今天來講解一下功能更加強大自動生成測試數據的工具的庫"AutoFixture"。 什麼是AutoFixture? AutoFixture 是一個針對 .NET 的開源庫,旨在最大程度地減少單元測試中的“安排(Arrange)”階段,以提高 ...
  • 經過前面幾個部分學習,相信學過的同學已經能夠掌握 .NET Emit 這種中間語言,並能使得它來編寫一些應用,以提高程式的性能。隨著 IL 指令篇的結束,本系列也已經接近尾聲,在這接近結束的最後,會提供幾個可供直接使用的示例,以供大伙分析或使用在項目中。 ...
  • 當從不同來源導入Excel數據時,可能存在重覆的記錄。為了確保數據的準確性,通常需要刪除這些重覆的行。手動查找並刪除可能會非常耗費時間,而通過編程腳本則可以實現在短時間內處理大量數據。本文將提供一個使用C# 快速查找並刪除Excel重覆項的免費解決方案。 以下是實現步驟: 1. 首先安裝免費.NET ...
  • C++ 異常處理 C++ 異常處理機制允許程式在運行時處理錯誤或意外情況。它提供了捕獲和處理錯誤的一種結構化方式,使程式更加健壯和可靠。 異常處理的基本概念: 異常: 程式在運行時發生的錯誤或意外情況。 拋出異常: 使用 throw 關鍵字將異常傳遞給調用堆棧。 捕獲異常: 使用 try-catch ...
  • 優秀且經驗豐富的Java開發人員的特征之一是對API的廣泛瞭解,包括JDK和第三方庫。 我花了很多時間來學習API,尤其是在閱讀了Effective Java 3rd Edition之後 ,Joshua Bloch建議在Java 3rd Edition中使用現有的API進行開發,而不是為常見的東西編 ...
  • 框架 · 使用laravel框架,原因:tp的框架路由和orm沒有laravel好用 · 使用強制路由,方便介面多時,分多版本,分文件夾等操作 介面 · 介面開發註意欄位類型,欄位是int,查詢成功失敗都要返回int(對接java等強類型語言方便) · 查詢介面用GET、其他用POST 代碼 · 所 ...
  • 正文 下午找企業的人去鎮上做貸後。 車上聽同事跟那個司機對罵,火星子都快出來了。司機跟那同事更熟一些,連我在內一共就三個人,同事那一手指桑罵槐給我都聽愣了。司機也是老社會人了,馬上聽出來了,為那個無辜的企業經辦人辯護,實際上是為自己辯護。 “這個事情你不能怪企業。”“但他們總不能讓銀行的人全權負責, ...