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>

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐