基于three-platformize完成一个3D加载demo

1,762 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第11天,点击查看活动详情

前言

前面推荐了一个适配多平台小程序的3D加载库,这一次我用uni-app 来引入 完成一个3D效果的加载。

3D库引入

根据github.com/deepkolos/t… 我们先把这个3D库引入到我们的项目,如下使用npm 命令

npm install three-platformize

依赖成功后可以看到项目中有依赖,如下

image.png

查看package.json可以看到我们的包依赖

{
  "dependencies": {
    "three-platformize": "^1.133.3"
  }
}

页面引入

	import { $cancelAnimationFrame, $requestAnimationFrame, $window, AmbientLight, DirectionalLight, PerspectiveCamera, PLATFORM, Scene, sRGBEncoding, WebGL1Renderer } from 'three-platformize'
	import { WechatPlatform } from 'three-platformize/src/WechatPlatform'
	import {GLTFLoader,GLTF } from 'three-platformize/examples/jsm/loaders/GLTFLoader'
	import { OrbitControls } from 'three-platformize/examples/jsm/controls/OrbitControls'

3D效果需要在页面用一个canvas标签来加载,我们在页面定义如下

			<canvas class="webgl" type="webgl" id="gl" @touchstart="onTX" @touchmove="onTX" @touchend="onTX"></canvas>

在生命周期的onReady里,开始进行加载

onReady() {
			 uni.createSelectorQuery().select('#gl').node().exec((res) => {
			      const canvas = res[0].node
			
			      this.platform = new WechatPlatform(canvas)
			      PLATFORM.set(this.platform);
			
			      const renderer = new WebGL1Renderer({ canvas, antialias: true, alpha: true })
			      const camera = new PerspectiveCamera(75, canvas.width / canvas.height, 0.1, 100);
			      const scene = new Scene()
			       this.gltfLoader = new GLTFLoader()
			      const controls = new OrbitControls(camera, canvas);
			      controls.enableDamping = true
					controls.autoRotate = true //设置自动旋转
					controls.dampingFactor = 0.25;// 动态阻尼系数 就是鼠标拖∂拽旋转灵敏度
					 
					controls.enableZoom = true  // 是否可以缩放
			      // this.gltfLoader.loadAsync('https://dtmall-tel.alicdn.com/edgeComputingConfig/upload_models/1591673169101/RobotExpressive.glb').then((gltf) => {
			      // this.gltfLoader.loadAsync('http://grass.grgchain.cn/fileServer/view/files/junci/B.glb').then((gltf) => {
			      // this.gltfLoader.loadAsync('http://grass.grgchain.cn/fileServer/view/files/junci/chip.glb').then((gltf) => {
			      this.gltfLoader.loadAsync(
				  'https://tumi-1306178125.cos.ap-shanghai.myqcloud.com/tumi/untitled.gltf',
					res=>{
					  	console.log('---进度--',res)
					}
				  )
				  .then((gltf) => {
			        // @ts-ignore
			        gltf.parser = null;
					gltf.scene.scale.set(10,10,10); 
			        gltf.scene.position.y = -2;
			        scene.add(gltf.scene);
					console.log('---在线渲染--',gltf)
			      })
					
			      camera.position.z = 10
			      renderer.outputEncoding = sRGBEncoding
			      scene.add(new AmbientLight(0xffffff, 1.0))
			      scene.add(new DirectionalLight(0xffffff, 1.0))
			      renderer.setSize(canvas.width, canvas.height)
			      renderer.setPixelRatio($window.devicePixelRatio)
			
			      const render = () => {
			        if (!this.disposing) this.frameId = $requestAnimationFrame(render)
			        controls.update()
			        renderer.render(scene, camera);
			      }
			      render()
			    })
		}

加载核心代码就是这些,其实大部分API是和Three.js一样的方式,所以我们如果要深入学习,想要完成更好的效果还是得去看Three.js文档。通过以上加载,可以把我们的3D文件加载出来,如下所示,图里能自动旋转是因为代码里加上了自动旋转。

QQ20220602-094222-HD.gif

并且还增加了我们的手势拖动,也是可以的,这样一个基础的3D效果加载就出来了。

在页面销毁的时候记得清理内存

,onUnload() {
			this.disposing = true
			    $cancelAnimationFrame(this.frameId)
			    PLATFORM.dispose()
		}

总结

如果只是简单的进行一个3D文件加载,其实难度不大。难的是和3D效果做交互,这涉及到更多的API来触发。并且3D文件一般都很大,要做好加载过程和进度的展示。最后放一下Three.js的官方文档

www.webgl3d.cn/Three.js/