簡介 React-Three-Fiber,淺談 WebGL 及 Three.js
WebGL (Web Graphics Library) 是一個基於 OpenGL ES 2.0 的 JavaScript API,允許瀏覽器在無需任何插件的情況下,透過 <canvas>
元素進行 2D 或 3D 的繪圖。
其中,OpenGL ES (OpenGL for Embedded System) 是 OpenGL 的精簡版本,專門為了嵌入式系統、行動裝置和瀏覽器設計。其渲染(Rendering)的基礎原理是將給定的數據計算後,產生出最終畫面。
舉例來說,輸入的數據包含物體的頂點座標、紋理、相機位置及光源資訊,而輸出的畫面則是從相機視角所看到的影像,OpenGL 的核心功能就是計算並渲染:算出 3D 物體在畫面上的位置、將 3D 物體轉換成 2D 像素,最後再加入光照來著色像素。
而 WebGL 在實務上,就是在瀏覽器中執行 OpenGL 的渲染功能。
Three.js 基礎原理
Three.js 則是將 WebGL 封裝成更高階的 API,使得開發者不需要關注 WebGL 較底層的細節。像是在繪製一個物體上,使用 WebGL 需要自己撰寫 Shaders(著色器程式)來完成 3D 轉 2D 像素的細節,而透過 Three.js 中則只要專注在畫什麼(物體的形狀、材質、光源)、如何觀看(拍攝物體的位置和角度)即可,不需考慮「怎麼畫出來」(底層的運算和渲染細節)。
基於這樣的簡化,Three.js 渲染的流程大致能歸納成 Scene(場景)、Camera(相機)、Renderer(渲染器)。Scene 就是 3D 世界的容器,可以放入各種物體、加入燈光;Camera 則決定觀看的視角,有 Perspective(透視)和 Orthographic(正交)兩種 Camera 可供選擇;而 Renderer 負責將 Scene 和 Camera 計算出的結果渲染至 HTML 的 <canvas>
元素上。
以下是一個繪製方塊的簡單例子
1 | import * as THREE from 'three'; |
這段程式碼使用了 Perspective Camera 模擬人眼的視覺效果,並設定視野(FoV, Field of View)為 70 度、畫面比例依照視窗的寬高比、最近和最遠可見距離分別為 0.01 和 10 個單位。
接著,我們在 Scene 中加入一個由 Geometry(幾何體)和 Material(材質)組成的 Mesh(網格物體),其中又指定 BoxGeometry(預設為寬高深皆為 1 的立方體)、MeshNormalMaterial(一種根據面的方向顯示不同顏色的材質),最後產生出來的方塊長成這樣。
為了同時看到立方體的三個面,我們設定了相機的位置 (5, 5, 5)
,也就是在方塊的右上後方,如此一來便能觀察到完整的一顆方塊了。
簡介 React-Three-Fiber
最後談到 React-Three-Fiber,這是一個基於 React 的 Three.js Renderer,可以將 Three.js 中的物體、材質、相機及光源等元素封裝成 React Components,讓開發者直覺地設計 3D 場景。
以下便是一個與前章節中能和 Three.js 範例裡呈現相同效果的程式碼:
1 | import { Canvas } from '@react-three/fiber'; |
此處同樣設定了相機,包含 FoV、位置等等,也加入了包含 <boxGeometry />
和 <meshNormalMaterial />
的 <mesh />
Component。
除了將 Three.js 封裝成 React 直覺式的 JSX 語法,也融入了 React Component 的生命週期。例如在 Three.js 中需要呼叫 scene.add()
及 dispose()
來管理 Scene 的資源,但是被封裝在 React Component 之後,這些資源都會自動在 Mount 及 Unmount 處理。