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>

### 回答1: 小程序 threejs-miniprogram 可以通过改变物体的位置实现平移操作。 在 threejs-miniprogram 中,可以使用 Vector3 对象来表示物体的位置,Vector3 是三维空间中的一个点,可以包含 x、y、z 三个坐标。通过改变 Vector3 对象的坐标值,即可实现物体的平移。 具体实现步骤如下: 1. 首先,通过创建一个 Vector3 对象表示需要平移的物体的当前位置。例如,可以使用如下代码创建一个初始位置为 (0, 0, 0) 的 Vector3 对象: ```javascript var position = new THREE.Vector3(0, 0, 0); ``` 2. 接下来,根据需求确定平移的距离和方向,并将其添加到 Vector3 对象的坐标值上。例如,如果需要在 x 方向上平移 10 个单位,可以使用如下代码: ```javascript position.x += 10; ``` 可以根据需要在其他坐标轴上进行相应的平移操作。 3. 最后,将改变后的 Vector3 对象赋值给物体的位置属性,即可实现物体的平移。例如,可以使用如下代码将改变后的位置赋值给物体的 position 属性: ```javascript object.position.copy(position); ``` 其中,object 为需要平移的物体对象。 通过以上步骤可以实现小程序 threejs-miniprogram 中物体的平移操作。可以根据具体需求修改平移的距离和方向,从而实现不同的平移效果。 ### 回答2: threejs-miniprogram 是一款基于小程序的三维渲染库,能够在小程序中实现三维模型的展示和交互。要实现平移功能,可以按照以下步骤进行操作。 首先,在合适的位置引入 threejs-miniprogram 库,并创建一个 canvas 组件,作为渲染的画布。 然后,在小程序中定义一个相机、一个场景和一个渲染器。相机用于控制视角,场景用于存放物体,渲染器用于将场景中的物体渲染到画布上。 接下来,创建一个物体,可以是一个几何体或者一个模型。将该物体添加到场景中。 在实现平移功能时,可以通过监听鼠标或触摸事件,获取用户的输入信息。根据用户的操作,改变物体在场景中的位置。 例如,可以通过监测鼠标移动事件,获取鼠标的位置差异,并将物体的位置与鼠标位置差异相加,从而实现物体的平移效果。需要注意的是,物体的位置变化需要实时更新,并且平移的距离应与屏幕上的实际距离有一个合适的映射关系,以确保平移的实际效果符合用户的期望。 最后,更新场景中的物体位置,并将场景渲染到画布上,以展示平移后的效果。 通过以上步骤,就可以在小程序使用 threejs-miniprogram 实现平移功能。需要根据实际需求,调整代码中的参数和细节,以适应具体的项目。 ### 回答3: 在使用threejs-miniprogram进行小程序开发时,我们可以通过平移操作来改变物体的位置。平移操作可以让物体在三维空间中沿着指定的方向移动一定的距离。 在threejs-miniprogram中,我们可以通过调整物体的位置属性来实现平移。首先,我们需要创建一个平移向量,它包含了物体在各个轴上的平移距离。然后,我们可以通过将这个平移向量与物体的位置属性相加,来实现平移操作。 举个例子,假设我们有一个立方体,它的初始位置是(0, 0, 0)。如果我们想将立方体沿着x轴方向平移3个单位,我们可以创建一个平移向量(3, 0, 0),然后将这个平移向量与立方体的位置属性相加,即可实现平移操作。 具体的代码如下所示: ```javascript var cube = new THREE.Mesh(geometry, material); // 创建立方体 var translateVector = new THREE.Vector3(3, 0, 0); // 创建平移向量 cube.position.add(translateVector); // 平移操作,将平移向量与立方体的位置属性相加 ``` 这样,立方体就会沿着x轴方向平移3个单位。 需要注意的是,在进行平移操作时,我们需要将平移向量与物体的位置属性相加,而不是简单地将平移向量赋值给物体的位置属性。这样才能在每次平移操作后保留之前的平移信息。 所以,在使用threejs-miniprogram平移物体时,我们只需要创建平移向量,并将其与物体的位置属性相加即可。这样就能实现物体的平移操作。
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值