目录
Three 介绍
Three.js是一个强大的JavaScript 3D库,可以轻松地在网页中创建3D图形。下面我将介绍如何在Vue项目中使用Three.js创建简单的3D模型。
官网
https://threejs.org/
创建 vue 项目
npm create vue@latest
安装 three
npm install three
项目拖入IDE
创建基础3D场景
<template>
<div ref="container" class="three-container"></div>
</template>
<script>
import * as THREE from 'three';
export default {
name: 'Simple3DModel',
mounted() {
this.initThreeJS();
},
methods: {
initThreeJS() {
// 1. 创建场景
const scene = new THREE.Scene();
scene.background = new THREE.Color(0xf0f0f0);
// 2. 创建相机
const camera = new THREE.PerspectiveCamera(
75, // 视野角度
this.$refs.container.clientWidth / this.$refs.container.clientHeight, // 宽高比
0.1, // 近截面
1000 // 远截面
);
camera.position.z = 5;
// 3. 创建渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(
this.$refs.container.clientWidth,
this.$refs.container.clientHeight
);
this.$refs.container.appendChild(renderer.domElement);
// 4. 添加光源
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
directionalLight.position.set(1, 1, 1);
scene.add(directionalLight);
// 5. 创建简单几何体
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshStandardMaterial({
color: 0x00ff00,
metalness: 0.1,
roughness: 0.5
});
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
// 6. 动画循环
const animate = () => {
requestAnimationFrame(animate);
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
};
animate();
// 7. 处理窗口大小变化
window.addEventListener('resize', () => {
camera.aspect = this.$refs.container.clientWidth / this.$refs.container.clientHeight;
camera.updateProjectionMatrix();
renderer.setSize(
this.$refs.container.clientWidth,
this.$refs.container.clientHeight
);
});
// 保存实例以便销毁时清理
this.scene = scene;
this.camera = camera;
this.renderer = renderer;
this.cube = cube;
}
},
beforeDestroy() {
// 清理资源
if (this.renderer) {
this.renderer.dispose();
this.$refs.container.removeChild(this.renderer.domElement);
}
window.removeEventListener('resize', this.handleResize);
}
};
</script>
<style>
.three-container {
width: 100%;
height: 500px;
}
</style>
创建不同类型的3D模型
1. 球体
const geometry = new THREE.SphereGeometry(1, 32, 32);
const material = new THREE.MeshStandardMaterial({
color: 0x4169e1,
wireframe: false
});
const sphere = new THREE.Mesh(geometry, material);
scene.add(sphere);
2. 圆柱体
const geometry = new THREE.CylinderGeometry(0.5, 0.5, 2, 32);
const material = new THREE.MeshStandardMaterial({ color: 0xff6347 });
const cylinder = new THREE.Mesh(geometry, material);
scene.add(cylinder);
3. 平面
const geometry = new THREE.PlaneGeometry(5, 5);
const material = new THREE.MeshStandardMaterial({
color: 0xcccccc,
side: THREE.DoubleSide
});
const plane = new THREE.Mesh(geometry, material);
plane.rotation.x = Math.PI / 2; // 旋转使其水平
scene.add(plane);
加载外部3D模型
Three.js支持加载多种格式的3D模型,如GLTF、OBJ、FBX等。以下是加载GLTF模型的示例:
首先安装GLTF加载器:
npm install three @types/three --save
npm install three-gltf-loader
在组件中使用:
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
// 在methods中添加
loadModel() {
const loader = new GLTFLoader();
loader.load(
'/path/to/model.gltf',
(gltf) => {
this.scene.add(gltf.scene);
},
undefined,
(error) => {
console.error('An error happened:', error);
}
);
}
添加交互控制
可以使用OrbitControls来添加鼠标交互控制:
安装:
npm install three-orbitcontrols
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
// 在initThreeJS方法中添加
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true; // 启用阻尼效果
controls.dampingFactor = 0.05;
// 在animate函数中更新controls
controls.update();
完整的案例
创建可交互的3D场景
<template>
<div ref="container" class="three-container"></div>
</template>
<script>
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
export default {
name: 'Interactive3DScene',
mounted() {
this.initThreeJS();
},
methods: {
initThreeJS() {
// 场景
const scene = new THREE.Scene();
scene.background = new THREE.Color(0xf0f0f0);
// 相机
const camera = new THREE.PerspectiveCamera(
75,
this.$refs.container.clientWidth / this.$refs.container.clientHeight,
0.1,
1000
);
camera.position.set(0, 2, 5);
// 渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(
this.$refs.container.clientWidth,
this.$refs.container.clientHeight
);
renderer.shadowMap.enabled = true;
this.$refs.container.appendChild(renderer.domElement);
// 控制器
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;
// 光源
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
directionalLight.position.set(5, 10, 7);
directionalLight.castShadow = true;
directionalLight.shadow.mapSize.width = 1024;
directionalLight.shadow.mapSize.height = 1024;
scene.add(directionalLight);
// 地面
const groundGeometry = new THREE.PlaneGeometry(10, 10);
const groundMaterial = new THREE.MeshStandardMaterial({
color: 0xcccccc,
side: THREE.DoubleSide
});
const ground = new THREE.Mesh(groundGeometry, groundMaterial);
ground.rotation.x = -Math.PI / 2;
ground.receiveShadow = true;
scene.add(ground);
// 添加一些3D物体
this.addObjects(scene);
// 动画循环
const animate = () => {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
};
animate();
// 窗口大小调整
window.addEventListener('resize', this.handleResize);
// 保存实例
this.scene = scene;
this.camera = camera;
this.renderer = renderer;
this.controls = controls;
},
addObjects(scene) {
// 立方体
const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);
const cubeMaterial = new THREE.MeshStandardMaterial({
color: 0x00ff00,
metalness: 0.3,
roughness: 0.4
});
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.position.set(-2, 0.5, 0);
cube.castShadow = true;
scene.add(cube);
// 球体
const sphereGeometry = new THREE.SphereGeometry(0.7, 32, 32);
const sphereMaterial = new THREE.MeshStandardMaterial({
color: 0x4169e1,
metalness: 0.5,
roughness: 0.1
});
const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
sphere.position.set(0, 0.7, 0);
sphere.castShadow = true;
scene.add(sphere);
// 圆柱体
const cylinderGeometry = new THREE.CylinderGeometry(0.5, 0.5, 1.5, 32);
const cylinderMaterial = new THREE.MeshStandardMaterial({
color: 0xff6347,
metalness: 0.1,
roughness: 0.8
});
const cylinder = new THREE.Mesh(cylinderGeometry, cylinderMaterial);
cylinder.position.set(2, 0.75, 0);
cylinder.castShadow = true;
scene.add(cylinder);
},
handleResize() {
this.camera.aspect = this.$refs.container.clientWidth / this.$refs.container.clientHeight;
this.camera.updateProjectionMatrix();
this.renderer.setSize(
this.$refs.container.clientWidth,
this.$refs.container.clientHeight
);
}
},
beforeDestroy() {
if (this.renderer) {
this.renderer.dispose();
this.$refs.container.removeChild(this.renderer.domElement);
}
window.removeEventListener('resize', this.handleResize);
}
};
</script>
<style>
.three-container {
width: 100%;
height: 500px;
}
</style>
* Thanks you *
如果觉得文章内容不错,随手帮忙点个赞、在看、转发一下,如果想第一时间收到推送,也可以给我个星标⭐~谢谢你看我的文章。
*往期推荐 *
实现如何利用 Kafka 延时删除 用户邮箱的验证码(如何发送邮箱+源码) - 第一期
Docker小白入门教程一篇领你入门(CRUD全命令+无废话版+问题集)-第三期
Docker小白入门教程一篇领你入门(CRUD全命令+无废话版+问题集)
想要高效处理,那不妨看看 Python的 异步 Asyncio 保证效率翻多倍
银河麒麟 | ubuntu 安装国产达梦DM8数据库(安装+外网通+IDEA连接)
网络设备日志存储到指定的Kiwi-log服务器(图解+软件)
银河麒麟 | ubuntu 安装运用 docker 容器,实现容器化部署项目
银河麒麟 | ubuntu 安装zabbix监控设备信息(亲测包对)
国产操作系统-银河麒麟本地化部署Ollama国产开源的AI大模型Qwen3
Swagger | 手把手带你写自动生成接口文档的爽感(零基础亲测实用)
SpringBoot整合Openfeign接入Kimi Ai!!超简单,居然没多少行代码??(附加兜底教程)
Maven | 站在初学者的角度配置与项目创建(新手必学会)
Spring Ai | 极简代码从零带你一起走进AI项目(中英)
MongoDB | 零基础学习与Springboot整合ODM实现增删改查(附源码)
Openfeign | 只传递城市代码,即可获取该地域实时的天气数据(免费的天气API)
Mongodb | 基于Springboot开发综合社交网络应用的项目案例(中英)
感谢阅读 | 更多内容尽在公棕号 WMCode | CSDN@小Mie不吃饭