本文介绍如何在Vue组件中使用Three.js,包括npm安装Three.js库、Three.js加载gltf模型、添加光源、添加拖拽缩放控制器、添加地平线网格、模型居中等步骤,最后提供完整的Vue组件示例,让你可以实现一个真实交互的3D场景。 SEO关键字: Vue、Three.js、GLTF、模型加载、控制器、光源、地平线网格、模型居中
在本文中,我们介绍了如何在Vue组件中使用Three.js,通过GLTFLoader模块加载glTF格式的3D模型,并添加控制器、光源、地平线网格等功能,使得3D场景更加真实、交互性更强。在Vue组件中创建一个点光源、使用OrbitControls模块实现拖拽缩放控制器、使用GridHelper模块创建地平线网格,以及将模型居中。通过本文的教程,你可以轻松地创建一个真实交互的3D场景。
Three简介
Three.js是一款基于WebGL的JavaScript 3D库,提供了一系列易于使用的API,使开发者可以快速构建高性能、交互性强的3D场景。它是目前最受欢迎的WebGL框架之一。
npm安装Three
在Vue项目中使用Three.js,需要先安装Three.js库。可以通过npm进行安装:
npm install three
Three加载gltf模型
glTF(GL Transmission Format)是一种与Three.js兼容的3D文件格式。Three.js提供了GLTFLoader模块,用于加载glTF格式的3D模型。
在Vue组件中引入GLTFLoader模块,并使用它加载glTF模型:
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
const loader = new GLTFLoader();
loader.load('model.gltf', (gltf) => {
scene.add(gltf.scene);
});
没有材质的模型乌漆嘛黑!
添加光源
为了让模型看起来更加真实,我们需要添加光源。Three.js提供了多种类型的光源,包括环境光、点光源、聚光灯等。
在Vue组件中创建一个点光源并添加到场景中:
import { PointLight } from 'three';
const light = new PointLight(0xffffbb, 1);
light.position.set(10, 10, 10);
scene.add(light);
添加拖拽缩放控制器
为了方便用户操作模型,我们可以添加拖拽缩放控制器。Three.js提供了OrbitControls模块,用于实现这个功能。
在Vue组件中引入OrbitControls模块,并创建一个OrbitControls实例:
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
const controls = new OrbitControls(camera, renderer.domElement);
添加地平线网格
为了更好地展示模型的位置和方向,我们可以添加地平线网格。Three.js提供了GridHelper模块,用于创建网格辅助线。
在Vue组件中创建一个地平线网格并添加到场景中:
import { GridHelper } from 'three';
const gridHelper = new GridHelper(10, 10);
scene.add(gridHelper);
模型居中
有些情况下,加载的模型可能不是居中的。我们可以通过计算模型的边界框来将其居中。
在Vue组件中加载模型后,计算模型的边界框并将其居中:
loader.load('model.gltf', (gltf) => {
const bbox = new THREE.Box3().setFromObject(gltf.scene);
const center = bbox.getCenter(new THREE.Vector3());
gltf.scene.position.sub(center); // 将模型的中心点移动到场景的中心点
scene.add(gltf.scene);
});
完整例子
## 完整例子
下面是一个完整的Vue组件示例,展示了如何使用Three.js加载glTF模型并添加控制器、光源、地平线网格等功能。
```javascript
<template>
<div ref="container"></div>
</template>
<script>
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
export default {
mounted() {
const container = this.$refs.container;
// 创建Three.js场景、相机、渲染器
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(600, 600);
container.appendChild(renderer.domElement);
renderer.setClearColor(0x444444, 1.0);
// 加载GLTF模型
const loader = new GLTFLoader();
loader.load(
'model.gltf',
gltf => {
// 将模型放到中间
const box = new THREE.Box3().setFromObject(gltf.scene);
const size = box.getSize(new THREE.Vector3()).length();
const center = box.getCenter(new THREE.Vector3());
gltf.scene.position.x -= center.x;
gltf.scene.position.y -= center.y;
gltf.scene.position.z -= center.z;
camera.near = size / 100;
camera.far = size * 100;
camera.updateProjectionMatrix();
camera.position.copy(center);
camera.position.x += size / 2;
camera.position.y += size / 2;
camera.position.z += size / 2;
camera.lookAt(center);
scene.add(gltf.scene);
//添加在模型的右上角高三倍设置一个光源 太阳
const light = new THREE.DirectionalLight(0xffffbb, 1);
// 模型宽度
const width = box.max.x - box.min.x;
// 模型高度
const height = box.max.y - box.min.y;
// 模型深度
const depth = box.max.z - box.min.z;
light.position.set(width * 3, height * 3, depth * 3);
scene.add(light);
//多设置几个光源
const light3 = new THREE.DirectionalLight(0xffffbb, 1);
light3.position.set(-width * 3, -height * 3, depth * 3);
scene.add(light3);
const light4 = new THREE.DirectionalLight(0xffffbb, 1);
light4.position.set(width * 3, height * 3, -depth * 3);
scene.add(light4);
},
undefined,
error => {
console.error(error);
},
);
// 设置相机位置
camera.position.z = 5;
// 添加OrbitControls控制器
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;
controls.screenSpacePanning = false;
controls.minDistance = 1;
controls.maxDistance = 1000;
//设置一个地平线网格
const gridHelper = new THREE.GridHelper(100, 100);
scene.add(gridHelper);
// 动画循环
const animate = function () {
requestAnimationFrame(animate);
// 更新OrbitControls控制器状态
controls.update();
renderer.render(scene, camera);
};
animate();
}
};
</script>
暂无评论内容