uniapp使用threejs-miniprogram在微信小程序加载模型

1.通过 npm 安装

npm install --save threejs-miniprogram

2.导入小程序版本的 Three.js并创建一个与 canvas 绑定的 three.js

<template>
	<canvas type="webgl" id="webgl" style="width: 100vw; height: 100vh"></canvas>
</template>
<script setup>
import { createScopedThreejs } from 'threejs-miniprogram';
import { onReady } from '@dcloudio/uni-app';

let THREE = null;
let canvas = null;

onReady(() => {
	init();
});

async function init() {
	await createThree();
}

function createThree() {
	return new Promise((resolve) => {
		uni.createSelectorQuery()
			.select('#webgl')
			.node()
			.exec((res) => {
				//canvas做动画时要用
				canvas = res[0].node;
				// 创建一个与 canvas 绑定的 three.js
				THREE = createScopedThreejs(canvas);
				resolve();
			});
	});
}
</script>

 3.创建渲染器

let renderer = null

async function init() {
	await createThree();
	createRenderer()
}

function createRenderer() {
	renderer = new THREE.WebGLRenderer();
	renderer.setSize(canvas.width, canvas.height);
}

4.创建场景,创建相机,渲染

let scene = null;
let camera = null;

async function init() {
	await createThree();
	createRenderer();
	createScene();
	createCamera();
	renderer.render(scene, camera);
}

function createScene() {
	scene = new THREE.Scene();
}

function createCamera() {
	camera = new THREE.PerspectiveCamera(75, canvas.width / canvas.height, 0.1, 1000);
	camera.position.set(400, 400, 800);
	camera.lookAt(0, 0, 0);
}

5.注册GLTF加载器,加载模型添加到场景

threejs-miniprogram/example/loaders/gltf-loader.js at master · wechat-miniprogram/threejs-miniprogram · GitHub

下载 gltf-loader.js

注册gltf-loader

import { registerGLTFLoader } from '@/utils/gltfloader.js';

async function init() {
	await createThree();
	createRenderer();
	createScene();
	createCamera();
	registerGLTFLoader(THREE)
	renderer.render(scene, camera);
}

加载模型和光源

async function init() {
	await createThree();
	createRenderer();
	createScene();
	createCamera();
	createLight();
	registerGLTFLoader(THREE);
	//glb纹理需要blob,小程序没有
	const res = await loadGLTF('http://127.0.0.1:3000/abc.gltf');
	scene.add(res);
	renderer.render(scene, camera);
}

function loadGLTF(url) {
	return new Promise((resolve, reject) => {
		new THREE.GLTFLoader().load(url, (gltf) => {
			// gltf.scene.scale.set(1, 1, 1);
			resolve(gltf.scene);
		});
	});
}

function createLight() {
	const light = new THREE.AmbientLight(0xffffff);
	scene.add(light);
}

 6.添加控制器

threejs-miniprogram/example/test-cases/orbit.js at master · wechat-miniprogram/threejs-miniprogram · GitHub

下载 orbit.js,创建控制器

import registerOrbit from '@/utils/controls.js';

let controls = null

async function init() {
	await createThree();
	createRenderer();
	createScene();
	createCamera();
	createLight();
	registerGLTFLoader(THREE);
	//glb纹理需要blob,小程序没有
	const res = await loadGLTF('http://127.0.0.1:3000/abc.gltf');
	scene.add(res);
	renderer.render(scene, camera);
	createControls()
}

function createControls() {
	const orbits = registerOrbit(THREE);
	controls = new orbits.OrbitControls(camera, renderer.domElement);
	controls.enableDamping = true;
}

动起来

<template>
	<canvas type="webgl" id="webgl" style="width: 100vw; height: 100vh" @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd"></canvas>
</template>
async function init() {
	await createThree();
	createRenderer();
	createScene();
	createCamera();
	createLight();
	registerGLTFLoader(THREE);
	//glb纹理需要blob,小程序没有
	const res = await loadGLTF('http://127.0.0.1:3000/abc.gltf');
	scene.add(res);
	renderer.render(scene, camera);
	createControls();
	animate();
}

function animate() {
	//小程序没有window.requestAnimationFrame
	canvas.requestAnimationFrame(animate);
	renderer.render(scene, camera);
	controls.update();
}

function touchMove(e) {
	controls.onTouchMove(e);
}

function touchEnd(e) {
	controls.onTouchEnd(e);
}

function touchStart(e) {
	controls.onTouchStart(e);
}

报错了

原因是微信小程序没有addEventListener

把orbit.js的addEventListener删掉,我们手动触发

  

 完整代码

<template>
	<canvas type="webgl" id="webgl" style="width: 100vw; height: 100vh" @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd"></canvas>
</template>

<script setup>
import { createScopedThreejs } from 'threejs-miniprogram';
import { onReady } from '@dcloudio/uni-app';
import { registerGLTFLoader } from '@/utils/gltfloader.js';
import registerOrbit from '@/utils/controls.js';

let THREE = null;
let canvas = null;
let renderer = null;
let scene = null;
let camera = null;
let controls = null;

onReady(() => {
	init();
});

async function init() {
	await createThree();
	createRenderer();
	createScene();
	createCamera();
	createLight();
	registerGLTFLoader(THREE);
	//glb纹理需要blob,小程序没有
	const res = await loadGLTF('http://127.0.0.1:3000/abc.gltf');
	scene.add(res);
	renderer.render(scene, camera);
	createControls();
	console.log(controls);
	animate();
}

function createThree() {
	return new Promise((resolve) => {
		uni.createSelectorQuery()
			.select('#webgl')
			.node()
			.exec((res) => {
				//canvas做动画时要用
				canvas = res[0].node;
				// 创建一个与 canvas 绑定的 three.js
				THREE = createScopedThreejs(canvas);
				resolve();
			});
	});
}

function createRenderer() {
	renderer = new THREE.WebGLRenderer();
	renderer.setSize(canvas.width, canvas.height);
}

function createScene() {
	scene = new THREE.Scene();
}

function createCamera() {
	camera = new THREE.PerspectiveCamera(75, canvas.width / canvas.height, 0.1, 1000);
	camera.position.set(400, 400, 800);
	camera.lookAt(0, 0, 0);
}

function loadGLTF(url) {
	return new Promise((resolve) => {
		new THREE.GLTFLoader().load(url, (gltf) => {
			resolve(gltf.scene);
		});
	});
}

function createLight() {
	const light = new THREE.AmbientLight(0xffffff);
	scene.add(light);
}

function createControls() {
	const orbits = registerOrbit(THREE);
	controls = new orbits.OrbitControls(camera, renderer.domElement);
	controls.enableDamping = true;
}

function animate() {
	//小程序没有window.requestAnimationFrame
	canvas.requestAnimationFrame(animate);
	renderer.render(scene, camera);
	controls.update();
}

function touchMove(e) {
	controls.onTouchMove(e);
}

function touchEnd(e) {
	controls.onTouchEnd(e);
}

function touchStart(e) {
	controls.onTouchStart(e);
}
</script>

<style></style>

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值