這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 什麼是 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>
組件接受 src
和 attach
prop。 src
屬性接受紋理材質的相對或絕對路徑,而 attach
屬性接受映射選項。
我們將在這個例子中使用 map
和 bumpMap
選項。 換句話說,我們必須在網格組件內聲明第二個 <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>
現在,如果你保存項目,你的地球應該像下麵的例子一樣很好地動畫。
你可以通過將 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>
現在地球的動畫在點擊時會暫停播放,如下圖:
現在,我們已經在 Vue 中成功構建了 3D 視覺效果!