記錄--使用Lunchbox 在 vue3 中創建一個 3D 地球

来源:https://www.cnblogs.com/smileZAZ/archive/2023/02/06/17096172.html
-Advertisement-
Play Games

這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 什麼是 Lunchbox.js Lunchbox.js 是 Three.js 的 Vue 3 自定義渲染器。 你可以把它想象成 Vue 的 react-three-fiber。 該庫通過組件提供對原始 Three.js 對象和類的訪問,例 ...


這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助

什麼是 Lunchbox.js

Lunchbox.js 是 Three.js 的 Vue 3 自定義渲染器。 你可以把它想象成 Vue 的 react-three-fiber

該庫通過組件提供對原始 Three.js 對象和類的訪問,例如:

  • mesh
  • lights
  • geometries
  • group
  • materials

這些組件是 Lunchbox.js 的構建塊。

例如,在 Three.js 項目中創建標準網格時,我們會使用像 BoxGeometry() 這樣的幾何類來創建長方體形狀,使用像 MeshBasicMaterial() 這樣的材質類對其應用顏色,就像在下麵的代碼中一樣:

// 創建邊長為 1 的幾何圖形
const geometry = new THREE.BoxGeometry(1, 1, 1)
// 創建黃色材質
const material = new THREE.MeshBasicMaterial({ color: 0xffff00 })
// 在網格中結合幾何圖形和材質
const mesh = new THREE.Mesh(geometry, material)
// 將該網格添加到場景中
scene.add(mesh)
為了在 Lunchbox.js 應用程式中創建相同的網格,我們將使用相同的類,除了作為組件,而不是將它們分配給變數並將它們與 Mesh() 類組合,我們將它們嵌套在 <mesh> 中 組件,如下所示:
<Lunchbox>
    <mesh>
        <boxGeometry :args="[1, 1 ,1]" />
        <meshBasicMaterial :color="0xffff00" />
    </mesh>
</Lunchbox>
你會註意到,在上面的示例中,每個 <Lunchbox> 組件都與對應的 Three.js 類和一個 camelCase 名稱相匹配。
// three.js
new THREE.Mesh()
<!-- Lunchbox -->
<mesh/>
// three.js
new THREE.BoxGeometry()
<!-- Lunchbox -->
<boxGeometry/>
Lunchbox.js 和 Three.js 的語法非常相似,但有一些不同之處需要註意。 例如,每個 <Lunchbox> 組件都使用 args 屬性將參數作為 props。 argsprop 接受一個參數數組並將其傳遞給組件的類構造函數。
new THREE.BoxGeometry(1, 2, 3)
上面的代碼將在 Lunchbox 中轉換為以下內容:
<boxGeometry :args="[1, 2, 3]" />
其他 Three.js 對象屬性,例如 MeshBasicMaterial 類的 color 屬性,可以作為響應式屬性添加到 <Lunchbox> 組件上。 這就像我們在前面的例子中看到的一樣。
<meshBasicMaterial :color="red" />
但是,使用點符號的屬性(例如位置向量)將在 <Lunchbox> 組件中使用破折號 - 進行設置,如下所示:
<mesh :position-x="3" />

Lunchbox為大多數 Three.js 類提供內置支持; 你可以在此處找到組件列表。

可以使用 Lunchbox的 app.extend 方法添加包含的組件中不可用的類。 例如,下麵是我們如何將 orbitControl 類添加到 Lunchbox:

import { createApp } from 'lunchboxjs'
import App from 'YourApp.vue'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'

createApp(App)
    .extend({ OrbitControls })
    .mount('#app')    

extend() 方法是 Lunchbox 的獨特功能之一,使用該方法添加的類繼承了 <Lunchbox> 組件的所有功能。

我們已經瞭解了 Lunchbox.js 的核心概念,接下來我們將瞭解如何使用 Lunchbox 進行構建。

開始

要設置一個 Lunchbox.js 應用程式,首先使用 Vite 的 CLI 安裝 Vue:

npm create vite@latest
運行命令後,從庫列表中選擇 Vue 併為項目命名。 接下來,cd 進入項目文件夾並運行以下命令:
npm install lunchboxjs three

此命令將安裝 Lunchbox.js 和 Three.js 作為 Vue 應用程式的依賴項。 你可以在根目錄的 package.json 文件中查看它們。

接下來清理項目中的樣板代碼,打開 main.js 文件,將內容替換為如下代碼:

import { createApp } from 'lunchboxjs'
import App from './App.vue'
createApp(App).mount('#app')

在這裡,我們從 lunchboxjs 而不是從 vue 導入 createApp 函數。 這會將 Vue 應用程式轉換為 Lunchbox 環境。

現在我們可以開始在我們的應用程式中構建和渲染 3D 對象。

創建場景

場景是允許我們設置要渲染的項目的對象。 它就像一個顯示區域,可以將對象放在一起並呈現給瀏覽器。 以下是 Three.js 中設置的場景示例:

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

在Lunchbox.js 中設置場景更直接且不那麼神秘。 該庫提供了一個 <Lunchbox> 組件,其中包含用於在 Three.js 中創建渲染器和場景的底層代碼。

要進行設置,請轉到 App.vue 主組件並將 <Lunchbox> 組件放在模板部分中,如下所示:

<template>
  <Lunchbox>
    <!-- ... -->
  </Lunchbox>
</template>
嵌套在 <Lunchbox> 標記中的每個對象都將呈現給瀏覽器。 如果你保存代碼並啟動開發伺服器,你應該會看到類似於下圖的黑屏。

 這個黑屏是我們應用的渲染器; 我們添加到場景中的任何內容都將顯示在這裡。 你可以使用背景道具更改背景顏色,如下所示:

<Lunchbox background="indigo">
            <!-- ... -->
</Lunchbox>

以下是你可以在 <Lunchbox> 組件上使用的一些 props:

  • background
  • cameraPosition
  • camera
  • zoom
  • shadow

添加網格

幾何是用於定義網格形狀的 Three.js 類。 在本文前面,我們演示瞭如何使用 boxGeometry 組件渲染長方體網格。 在這裡,我們將看到如何向瀏覽器渲染更多 3D 形狀。

Lunchbox.js 帶有幾個自動生成的內置幾何組件,你可以在此處查看可用組件的列表。

繼續併在Lunchbox標簽內添加一個 <mesh> 組件,併在其中嵌套你選擇的任何幾何組件。 不要忘記包含一個帶有顏色道具的材質組件。

<Lunchbox>
  <mesh>
     <boxGeometry />
     <MeshBasicMaterial color="red"/> 
  </mesh>
</Lunchbox>

材質組件利用 Three.js Material() 類來定義網格的各種錶面屬性。

<mesh> 組件只接受一個 Geometry()Material() 組件。 要為場景添加更多形狀,我們必須創建更多網格,每個 Geometry() 一個,如下所示。

<Lunchbox>
      <mesh>
         <boxGeometry />
         <MeshBasicMaterial color="red"/> 
      </mesh>
      <mesh>
         <torusKnotBufferGeometry />
         <MeshBasicMaterial color="grey"/> 
      </mesh>
</Lunchbox>
或者,我們可以為每個形狀創建單獨的組件並將它們導入到主組件中,如下所示:
<script>
      import {Sphere} from './Sphere.vue'
</script>
<template>
      <Lunchbox>
            <Sphere />
      </Lunchbox>
</template>
每個幾何組件都接受獨特的參數,這些參數可用於微調和操縱其寬度、高度、平滑度和其他視覺特征。 可以使用 args 屬性在 Lunchbox 中設置這些參數。
<torusKnotBufferGeometry :args="[1, 0.4, 240, 20]"/>
組件還接受多個 props。 由於它作為 Geometry() 的容器,它還可以用於操縱位置、旋轉等。
<Lunchbox>
  <mesh position-x="4" position-x="4">
      ...
  </mesh>
</Lunchbox>

在上面的代碼中,我們添加了一個 positoin 屬性,它將球體網格沿 x 軸向右移動 4px。

以下是一些可用於操縱形狀的網格 props:

  • position (x, y, z)
  • rotation (x, y, x)
  • scale (x, y)

網格也可以使用 <group> 組件進行分組。 該組件用作幾何圖形的容器,我們可以在每個 <group> 中添加任意數量的 <mesh>

<Lunchbox>
     <group>
        <mesh>
           <boxGeometry />
           <MeshBasicMaterial color="red"/> 
        </mesh>
        <mesh>
           <torusKnotGeometry />
           <MeshBasicMaterial color="grey"/> 
        </mesh>
     </group>
</Lunchbox>

添加紋理

目前,我們的網格看起來不是很逼真。 應用的材料使它們看起來有點塑料。 我們可以使用 Lunchbox 中的 <textureLoader> 組件應用紋理,為每個網格賦予更逼真的外觀。

<textureLoader> 組件利用 Three.js Texture() 類,它讓我們可以將逼真的紋理映射到引擎蓋下的網格錶面。 為了演示這個過程,我們將創建一個地球的 3D 模型。

 

 要創建地球,請先清除場景,然後使用 <sphereGeometry/> 組件創建具有球面幾何形狀的新網格。

<Lunchbox>
  <mesh>
     <sphereGeometry />
  </mesh> 
</Lunchbox>
接下來,在網格中添加一個 <meshPhysicalMaterial> 組件並將 <textureLoader> 嵌套在其中,如下所示:
<Lunchbox>
  <mesh>
      <sphereGeometry :args="[1, 32, 32]" />
      <meshPhysicalMaterial>
            <textureLoader />
      </meshPhysicalMaterial>
  </mesh>
</Lunchbox>

組件接受 srcattach prop。 src 屬性接受紋理材質的相對或絕對路徑,而 attach 屬性接受映射選項。

我們將在這個例子中使用 mapbumpMap 選項。 換句話說,我們必須在網格組件內聲明第二個 <textureLoader>

複製下麵的圖像並將它們放在項目的 /public 文件夾中:

 

 接下來,將第一個圖像的路徑添加到第一個 <textureLoader> 組件的 src 屬性中,併為附加屬性賦予一個 “map” 值。

<meshPhysicalMaterial>
      <textureLoader src="/first-image" attach="map" />
      <textureLoader ... />
</meshPhysicalMaterial>
如果你現在保存項目,瀏覽器中將出現一個球形輪廓。 這是因為我們的場景沒有光源。

 

 要解決此問題,請在 <Lunchbox> 組件中添加 <pointLight /> 和 <directionalLight /> 組件。

<Lunchbox>
  <directionalLight />
  <pointLight />
  <mesh>
      ...
  </mesh>
</Lunchbox>
現在,如果你保存項目並返回瀏覽器,你應該會看到類似於下圖的內容:

為了使圖像更有趣和視覺上更令人驚嘆,我們將使用第二張圖像為地球添加逼真的輪廓。

我們將按照我們處理第一張圖像的方式進行處理。 將圖像的路徑添加到 src 道具,但這次給 attach prop一個 “bumpMap” 值。

添加動畫

Lunchbox.js 提供了一個 onBeforeRender 函數,在渲染之前或之後的每一幀都會調用該函數。 使用此函數,我們可以通過在每一幀上為其旋轉屬性添加一個值來為我們的地球設置動畫。

轉到 App.vue 組件的腳本部分並從 Vue 導入 ref 和從 Lunchbox 導入 onBeforeRender 函數。

import {ref} from 'vue'
import {onBeforeRender} from 'lunchboxjs'
接下來,將 ref 分配給一個 rotation 變數,並將一個具有以下屬性的對象傳遞給它:
const rotation = ref({y: 0});
然後,調用 onBeforeRender 函數並添加以下代碼:
onBeforeRender(() =>{
   rotation.value.y += 0.02
})
在這裡,我們在每一幀上為對象的 y 軸旋轉添加 0.02 度。 最後,為地球的網格添加一個 rotation-y 屬性,並將 rotation.y 值傳遞給它,如下所示:
<mesh rotation-y="rotation.y">
        <sphereGeometry />
        <meshPhysicalMaterial>
              <textureLoader ... />
              <textureLoader ... />
        </meshPhysicalMaterial>
</mesh>

現在,如果你保存項目,你的地球應該像下麵的例子一樣很好地動畫。 

Jul-30-2022 14-45-32.gif

你可以通過將 x 和 z 屬性添加到 ref、onBeforeRender 函數和地球的網格來添加更多旋轉動畫。

添加事件

我們可以像添加 Vue 中的任何其他元素一樣向 <Lunchbox> 組件添加事件監聽器。 為了演示,我們將添加一個 click 事件,當它被觸發時會暫停我們的地球動畫。

繼續在地球網格上創建一個 onClick 事件,如下所示:

<mesh rotation-y="rotation.y" @click="">
    ...
</mesh>
接下來,使用 ref 創建一個變數,並將布爾值 true 傳遞給它。 使用 if 語句將聲明包裝在 onBeforeRender 函數中:
const active = ref(true)
onBeforeRender(() =>{
 if(active){
   rotation.value.y += 0.02
  }
})

在這裡,我們將活動變數分配為 if 語句的條件。 當該值設置為 false 時,語句中的代碼將不會被執行,動畫會暫停。

最後,將以下代碼添加到 <mesh> 組件的 onClick 事件中:

<mesh rotation-y="rotation.y" @click="active = !active">
    ...
</mesh>

現在地球的動畫在點擊時會暫停播放,如下圖:

Jul-30-2022 14-48-01.gif

現在,我們已經在 Vue 中成功構建了 3D 視覺效果!

本文轉載於:

https://juejin.cn/post/7126059371938709517

如果對您有所幫助,歡迎您點個關註,我會定時更新技術文檔,大家一起討論學習,一起進步。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一:背景 1. 講故事 在 SQLSERVER 的眾多阻塞場景中,有不小的一部分是由於 PFS 頁上的 閂鎖 等待造成的,畢竟寫頁操作一定是要串列化的,在面對 閂鎖(PAGELATCH_X) 等待問題上,一定要搞明白 PFS 頁到底是什麼? 這篇就來好好聊一聊。 二:PFS 詳解 1. 什麼是 PF ...
  • MySQL執行流程 select語句執行流程 增刪改語句執行流程 update語句的整體執行流程和select語句是一樣的。只是少了緩存的那一步驟。 mysql想完成數據的修改,會先從存儲引擎層讀取數據,把數據讀取到服務層進行數據的修改,再通過存儲引擎層把數據更新到資料庫中。 mysql每次讀取數據 ...
  • 閱識風雲是華為雲信息大咖,擅長將複雜信息多元化呈現,其出品的一張圖(雲圖說)、深入淺出的博文(雲小課)或短視頻(雲視廳)總有一款能讓您快速上手華為雲。更多精彩內容請單擊此處。 摘要: GaussDB(DWS)支持根據業務系統的不同使用需求,對膨脹的數據進行冷熱分級管理,將數據按照時間分為熱數據、冷數 ...
  • 我們在談數倉之前,為了讓大家有直觀的認識,先來談數倉架構,“架構”是什麼?這個問題從來就沒有一個準確的答案。這裡我們引用一段話:在軟體行業,一種被普遍接受的架構定義是指系統的一個或多個結構。結構中包括軟體的構建(構建是指軟體的設計與實現),構建的外部可以看到屬性以及它們之間的相互關係。 ...
  • 近年來,AR版塊成為時下大熱,這是一種將現實環境中不存在的虛擬物體融合到真實環境里的技術,用戶藉助顯示設備可以擁有真實的感官體驗。AR的應用場景十分廣泛,涉及娛樂、社交、廣告、購物、教育等領域:AR可以讓游戲更具互動性;商品通過AR展示更真實;使用AR進行教育教學讓抽象事物更形象等,可以說AR技術已 ...
  • 一、瞭解UniApp 插件的開發方式 Xcode Framework 、 Static Library 基於Cocoapods開發 pod lib 已知UniApp的插件開發方式有兩種, 第一種 Xcode Framework的方式,這種方式是官方指定的方式。 這種方式的優點就是簡單直接, 但也有不 ...
  • 使用語法結構創建的對象 function fn(){ var name="RoastDuck"; } 使用構造器創建的對象 function Duck() { this.name = []; this.age = []; } var RoastDuck = new Duck(); 使用 Object ...
  • When it comes to inheritance, JavaScript only has one construct: objects. Each object has a private property which holds a link to another object call ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...