一、后期调研
因小程序环境下,没有浏览器相干的运行环境如 window, document 等,所以在小程序中应用 three.js 须要应用相应的移植版本。
调研了以下三种:
①微信官网给出的版本:
https://github.com/wechat-min…
加载不带贴图的 glb 文件没问题。但加载带贴图的 glb 文件报错,对 loader 文件没有做移植,并且看官网不怎么保护了。
②three 平台化产品,然而感觉上手不是特地敌对,并且比拟大。
https://github.com/deepkolos/…
③yannliao 微信官网社区里比拟热门的版本
https://github.com/yannliao/t…
最终应用了第三种,对 glb 带材质的文件也能失常加载。
二、应用教程
1、在示例仓库(https://github.com/yannliao/t…)中,下载 libs 及 jsm 文件夹,放入本人我的项目根目录下
2、在 index.js 页面的 js 文件下引入 three
import * as THREE from '../../libs/three.weapp.min.js'
import {OrbitControls} from '../../jsm/loaders/OrbitControls'
Page({data: {},
onLoad: function () {wx.createSelectorQuery()
.select('#c')
.node()
.exec((res) => {const canvas = THREE.global.registerCanvas(res[0].node)
this.setData({canvasId: canvas._canvasId})
const camera = new THREE.PerspectiveCamera(70, canvas.width / canvas.height, 1, 1000);
camera.position.z = 500;
const scene = new THREE.Scene();
scene.background = new THREE.Color(0xAAAAAA);
const renderer = new THREE.WebGLRenderer({antialias: true});
const controls = new OrbitControls(camera, renderer.domElement);
// controls.enableDamping = true;
// controls.dampingFactor = 0.25;
// controls.enableZoom = false;
camera.position.set(200, 200, 500);
controls.update();
const geometry = new THREE.BoxBufferGeometry(200, 200, 200);
const texture = new THREE.TextureLoader().load('./pikachu.png');
const material = new THREE.MeshBasicMaterial({map: texture});
// const material = new THREE.MeshBasicMaterial({color: 0x44aa88});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
// renderer.setPixelRatio(wx.getSystemInfoSync().pixelRatio);
// renderer.setSize(canvas.width, canvas.height);
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(canvas.width, canvas.height);
}
function render() {canvas.requestAnimationFrame(render);
// mesh.rotation.x += 0.005;
// mesh.rotation.y += 0.01;
controls.update();
renderer.render(scene, camera);
}
render()})
},
onUnload: function () {THREE.global.unregisterCanvas(this.data.canvasId)
},
touchStart(e) {console.log('canvas', e)
THREE.global.touchEventHandlerFactory('canvas', 'touchstart')(e)
},
touchMove(e) {console.log('canvas', e)
THREE.global.touchEventHandlerFactory('canvas', 'touchmove')(e)
},
touchEnd(e) {console.log('canvas', e)
THREE.global.touchEventHandlerFactory('canvas', 'touchend')(e)
},
touchCancel(e) {// console.log('canvas', e)
},
longTap(e) {// console.log('canvas', e)
},
tap(e) {// console.log('canvas', e)
},
documentTouchStart(e) {// console.log('document',e)
},
documentTouchMove(e) {// console.log('document',e)
},
documentTouchEnd(e) {// console.log('document',e)
},
})
3、在 index.wxml 中退出 canvas 组件, 其中须要手动绑定相应的事件,用于手势管制。
<view style="height: 100%; width: 100%;" bindtouchstart="documentTouchStart" bindtouchmove="documentTouchMove" bindtouchend="documentTouchEnd" >
<canvas type="webgl" id="c" style="width: 100%; height:100%;" bindtouchstart="touchStart" bindtouchmove="touchMove" bindtouchend="touchEnd" bindtouchcancel="touchCancel" bindlongtap="longTap" bindtap="tap"></canvas>
</view>
三、踩坑记录
Q1:为何示例外面的模型,在真机预览上都看不到?
答:起因在于模型下载地址,不在小程序 request 非法域名中。如果只是想真机浏览下成果,不思考日后上线问题,能够在真机预览轻快下,打击页面左边下面的 3 个点,抉择关上调试即可,这相当于开发工具勾选不效验非法域名。或是日后要上线,那就把模型放到你本人的服务器上,要有域名的,icp 备过案的,https 的服务器。这是微信的要求,不是 threejs 的要求。
Q2:模型能看到了,然而贴图看不到?
答:如果援用都正确的状况下看不到,那就是,贴图尺寸的问题,threejs 有限度图片尺寸,目前测试最大为 2048。并且图片的大小要为 2 的冥数倍。
Q3:我不想只在调试模式下能看到模型,然而域名服务器那些,我也搞不明确,有没有方法,让我在失常体验版下也能够给他人浏览我的模型?
答:之前我也被这个问题困扰过,微信小程序如果是云开发版时,会有一个收费的 5G 的云数据库和存储空间,咱们的冲破就是它。存进去后,咱们罕用的是 fileID, 然而这里,我要应用的是它的下载地址,https 结尾的哟,并且能够胜利增加进非法域名,问题解决。那非云开发版本怎么办呢,unicloud 也提供收费的云存储,你创立一个云空间后,云存储上传即可,点击详情能够看到 https 的门路。