目錄
Three 介紹
創建基礎3D場景
創建不同類型的3D模型
1. 球體
2. 圓柱體???????
3. 平面???????
加載外部3D模型
添加交互控制
創建可交互的3D場景
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
Ubuntu | ?安裝 Zabbix 一篇就夠了
Swagger | 手把手帶你寫自動生成接口文檔的爽感(零基礎親測實用)
SpringBoot整合Openfeign接入Kimi Ai!!超簡單,居然沒多少行代碼??(附加兜底教程)
SpringBoot接入Kimi實踐記錄輕松上手
Linux | 零基礎Ubuntu搭建JDK
Maven | 站在初學者的角度配置與項目創建(新手必學會)
Spring Ai | 極簡代碼從零帶你一起走進AI項目(中英)
Open Ai | 從零搭建屬于你的Ai項目(中英結合)
MongoDB | 零基礎學習與Springboot整合ODM實現增刪改查(附源碼)
Openfeign | 只傳遞城市代碼,即可獲取該地域實時的天氣數據(免費的天氣API)
Redis | 緩存技術對后端的重要性,你知道多少?
Mongodb | 基于Springboot開發綜合社交網絡應用的項目案例(中英)
感謝閱讀?|?更多內容盡在公棕號?WMCode?| CSDN@小Mie不吃飯