Three.js 3D 渲染
WebGL 與 Three.js 的 3D 場景開發、材質光影與互動效果。以下為使用 React Three Fiber 實作的互動展示。
幾何體展示台
使用 Float 實現漂浮動態,搭配多組 PointLight 產生彩色反射光影,OrbitControls 支援拖曳與自動旋轉。
載入場景中…
粒子波浪場
以 BufferGeometry 管理 3,600 個頂點,每幀透過正弦函數計算高度,並以滑鼠位置作為相位偏移輸入,效能優於每幀重建幾何體。
載入場景中…
實作筆記
BufferAttribute 直接操作頂點(粒子波浪)
避免每幀重建 Geometry 造成 GC 壓力。直接取出 position attribute,原地修改 Y 值後標記 needsUpdate = true,讓 Three.js 僅上傳變動的 buffer 至 GPU。
useFrame(({ clock }) => {
const t = clock.getElapsedTime()
const posAttr = meshRef.current.geometry.attributes.position
for (let i = 0; i < GRID * GRID; i++) {
const x = posAttr.getX(i)
const z = posAttr.getZ(i)
// 滑鼠位置(mouse.x/y)作為相位偏移,讓波浪跟隨游標
const wave = Math.sin((x + mouse.x * 2) * 1.5 + t)
* Math.cos((z + mouse.y * 2) * 1.5 + t) * 0.6
posAttr.setY(i, wave)
}
posAttr.needsUpdate = true // 僅通知 GPU 更新,不重新分配記憶體
})Next.js SSR 相容:dynamic import + ssr: false
Three.js 直接存取 window / WebGL context,在 Node.js 環境會崩潰。透過 dynamic import 延遲至瀏覽器載入,並將 ssr: false 的呼叫包在 'use client' Client Component 中,避免 Next.js App Router 的限制。
// ThreeClientComponents.tsx ('use client' 必要)
import dynamic from 'next/dynamic'
// ssr: false 只能在 Client Component 中使用
export const GeometryShowcaseDynamic = dynamic(
() => import('./GeometryShowcase'),
{ ssr: false, loading: () => <div className="h-72 animate-pulse bg-neutral-900 rounded-2xl" /> }
)
// Server Component 直接 import 此檔案即可,無需感知 Three.js