通過vue如何利用 Three 繪制 簡單3D模型(源碼案例)

目錄

Three 介紹

創建基礎3D場景

創建不同類型的3D模型

1. 球體

2. 圓柱體???????

3. 平面???????

加載外部3D模型

添加交互控制

創建可交互的3D場景


The ship.energy summit – the three key takeaways | ship.energy

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 --savenpm 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函數中更新controlscontrols.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不吃飯

      本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
      如若轉載,請注明出處:http://www.pswp.cn/bicheng/88386.shtml
      繁體地址,請注明出處:http://hk.pswp.cn/bicheng/88386.shtml
      英文地址,請注明出處:http://en.pswp.cn/bicheng/88386.shtml

      如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

      相關文章

      云蝠智能 Voice Agent 落地展會邀約場景:重構會展行業的智能交互范式

      一、行業痛點與 AI 破局在會展行業數字化轉型的浪潮中&#xff0c;傳統展會邀約模式面臨多重挑戰&#xff1a;人工外呼日均僅能處理 300-500 通電話&#xff0c;且無效號碼占比高達 40% 以上&#xff0c;導致邀約效率低下。同時&#xff0c;個性化邀約話術設計依賴經驗&#xf…

      idea如何打開extract surround

      在 IntelliJ IDEA 中&#xff0c;"Extract Surrounding"&#xff08;提取周圍代碼&#xff09;通常指 ?將一段代碼提取到新的方法、變量或類中&#xff0c;但更常見的操作是 ??"Surround With"&#xff08;用代碼結構包圍&#xff09;?。以下是兩種場景…

      window顯示驅動開發—XR_BIAS 和 BltDXGI

      Direct3D 運行時調用驅動程序的 BltDXGI 函數&#xff0c;以僅對XR_BIAS源資源執行以下操作&#xff1a;復制到也XR_BIAS的目標未修改的源數據的副本可接受點樣本的拉伸旋轉由于 XR_BIAS 不支持 MSAA) (多個示例抗鋸齒&#xff0c;因此驅動程序不需要解析XR_BIAS資源。核心規則…

      web網頁開發,在線%ctf管理%系統,基于html,css,webform,asp.net mvc, sqlserver, mysql

      webform,asp.net mvc。數據庫支持mysql,sqlserver經驗心得 每次我們寫crud沒啥技術含量&#xff0c;這沒法讓咱們進入大廠&#xff0c;剛好這次與客戶溝通優化方案建議&#xff0c;咱們就把能加的幫他都加上去。一個ctf管理系統基本crud&#xff0c;并進行不同分層開發&#xf…

      面試技術問題總結一

      MySQL的幾種鎖機制一、從鎖的粒度角度劃分表級鎖機制&#xff1a;它是對整張表進行鎖定的一種鎖。當一個事務對表執行寫操作時&#xff0c;會獲取寫鎖&#xff0c;在寫鎖持有期間&#xff0c;其他事務無法對該表進行讀寫操作&#xff1b;而當事務執行讀操作時&#xff0c;會獲取…

      π0.5的KI改進版——知識隔離:讓VLM在不受動作專家負反饋的同時,繼續輸出離散動作token,并根據反饋做微調(而非凍結VLM)

      前言 過去的一個月(25年6.4-7.4)&#xff0c;我司「七月在線」具身長沙分部為沖刺一些為客戶來現場看的演示項目&#xff0c;基本都用lerobot的那套框架 比如上周五(7.4日)晚上&#xff0c;通過上周五下午新采的第五波數據做『耳機線插入耳機孔』的任務&#xff0c;推理十次之…

      Eigen中Isometry3d的使用詳解和實戰示例

      Eigen::Isometry3d 是 Eigen 庫中用于表示 三維空間中的剛性變換&#xff08;Rigid Transformation&#xff09; 的類&#xff0c;屬于 Eigen::Transform 模板類的一個特化版本。它結合了 旋轉和平移&#xff0c;廣泛應用于機器人學、SLAM、三維幾何計算等場景。一、核心定義 #…

      《未來已來:當人類智慧遇上AI智能體》

      在這個充滿奇跡的時代,人類的智慧與科技的力量正以前所未有的速度交織在一起。 我們站在一個新時代的門檻上,一邊是古老而深邃的自然規律,另一邊是充滿可能性的未來世界。 今天,就讓我們一起走進這場關于人類智慧與AI智能體Kimi的對話,看看未來究竟會帶給我們怎樣的驚喜…

      【三維生成】FlashDreamer:基于擴散模型的單目圖像到3D場景

      標題&#xff1a;<Enhancing Monocular 3D Scene Completion with Diffusion Model> 代碼&#xff1a;https://github.com/CharlieSong1999/FlashDreamer 來源&#xff1a;澳大利亞國立大學 文章目錄摘要一、前言二、相關工作2.1 場景重建2.2 擴散模型2.3 Vision languag…

      CANFD記錄儀設備在無人駕駛快遞車的應用

      隨著物流行業的快速發展&#xff0c;無人駕駛快遞車因其高效、低成本的優勢&#xff0c;逐漸成為“最后一公里”配送的重要解決方案。然而&#xff0c;無人駕駛系統的穩定性和安全性高度依賴車輛總線數據的精準采集與分析。南金研CANFDlog4 4路記錄儀憑借其多通道、高帶寬、高可…

      Kubernetes存儲入門

      目錄 前言 一、Volume 的概念 二、Volume 的類型 常見的卷類型 Kubernetes 獨有的卷類型 三、通過 emptyDir 共享數據 1. 編寫 emptyDir 的 Deployment 文件 2. 部署該 Deployment 3. 查看部署結果 4. 登錄 Pod 中的第一個容器 5. 登錄 Pod 中的第二個容器查看/mnt下…

      10.Docker安裝mysql

      (1)docker pull mysql:版本號eg&#xff1a;docker pull mysql(默認安裝最新版本)docker pull mysql:5.7(2)啟動并設置mysql鏡像docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD123456 --name mysql1 mysql其他參數都不多講&#xff0c;下面這個參數指的是設置數據庫用戶ro…

      Debian-10編譯安裝Mysql-5.7.44 筆記250706

      Debian-10編譯安裝Mysql-5.7.44 筆記250706 單一腳本安裝 ### 1. 安裝編譯依賴 sudo apt install -y cmake gcc g build-essential libncurses5-dev libssl-dev \ pkg-config libreadline-dev zlib1g-dev bison curl wget libaio-dev \ libjson-perl libnuma-dev libsystemd-d…

      HarmonyOS 中狀態管理 V2和 V1 的區別

      鴻蒙ArkUI框架中的ComponentV2與V1在狀態管理、組件開發模式、性能優化等方面存在顯著差異。以下是兩者的核心區別及技術解析&#xff1a;一、狀態管理機制V1的局限性V1的Observed裝飾器只能觀察對象的第一層屬性變化&#xff0c;需配合ObjectLink手動拆解嵌套對象。例如&#…

      centos7 安裝jenkins

      文章目錄前言一、pandas是什么&#xff1f;二、安裝依賴環境1.前提準備2.安裝git3.安裝jdk&#xff0c;以及jdk版本選擇4.安裝maven5.安裝NodeJS6.驗證三、安裝Jenkins四、驗證Jenkins總結前言 正在學習jenkinsdocker部署前后端分離項目&#xff0c;安裝jenkins的時候遇到了一…

      Leetcode刷題營第二十題:刪除鏈表中的重復節點

      面試題 02.01. 移除重復節點 編寫代碼&#xff0c;移除未排序鏈表中的重復節點。保留最開始出現的節點。 示例1&#xff1a; 輸入&#xff1a;[1, 2, 3, 3, 2, 1]輸出&#xff1a;[1, 2, 3]示例2&#xff1a; 輸入&#xff1a;[1, 1, 1, 1, 2]輸出&#xff1a;[1, 2]提示&…

      關于市場主流自動化測試工具和框架的簡要介紹

      下面我會分別講解 Selenium、Appium、Playwright 等主流自動化框架的區別、聯系、適用場景和歸屬范疇&#xff0c;幫助你更系統地理解它們。&#x1f527; 一、它們都屬于哪一類工具&#xff1f;Selenium、Appium、Playwright、Cypress 等都屬于&#xff1a;?? 自動化測試框架…

      基于cornerstone3D的dicom影像瀏覽器 第三十二章 文件夾做pacs服務端,fake-pacs-server

      文章目錄 前言一、實現思路二、項目與代碼三、dicom瀏覽器調用1. view2d.vue前言 本系列最后一章,提供一個模擬pacs服務,供訪問dicom圖像測試。 修改nodejs本地目錄做為http服務根目錄,提供一個根目錄,其中的每個子目錄代表一個檢查。在dicom瀏覽器url中帶入參數studyId=目…

      【Python 核心概念】深入理解可變與不可變類型

      文章目錄一、故事從變量賦值說起二、不可變類型 (Immutable Types)三、可變類型 (Mutable Types)四、一個常見的陷阱&#xff1a;當元組遇到列表五、為什么這個區別如此重要&#xff1f;1. 函數參數的傳遞2. 字典的鍵 (Dictionary Keys)3. 函數的默認參數陷阱六、進階話題與擴展…

      wpf使用webview2顯示網頁內容(最低兼容.net framework4.5.2)

      wpf使用webview2顯示網頁內容(最低兼容.net framework4.5.2 一、核心功能與架構混合開發支持?進程隔離模型?通信機制?二、核心優勢性能與兼容性?跨平臺部署?開發效率?安全機制?三、適用場景四、開發部署要點WebView2 是微軟推出的現代瀏覽器控件,基于 Chromium 內核的 …