身為一個3D列印及建模的業餘愛好者,關注不同建模軟體的特性是自然之事,最近發現一個能在瀏覽器上運行的3D雕塑軟體,畫面流暢性令人驚訝,我也留意到該網頁的標題為「A WebGL sculpting app」?為什麼是WebGL?

瀏覽器中的建模軟體

玩弄3D列印與建模至今,不覺已經有近四年的時間,作為一名程式開發者,當初首選程式碼作為建模的表達方式,因而使用OpenSCAD作為建模軟體,但在建模軟體的光譜中,它是一個極端,因為它完全依賴程式碼來建立模型,使用者的滑鼠操作對於移動、調整模型而言,是沒有作用的。

OpenSCAD適合基於立方體、圓柱體、球體等幾何體的組合建模,但如果想要建構柔軟的曲線面,找出相對應的數學公式會是比較困難的,因而近來我將目光望向了光譜的另一端──3D雕塑軟體。這類軟體的起點,通常是個代表泥塊的圓球,幾乎完全依賴滑鼠塑形為想要的模型。

這類3D雕塑軟體的代表,包括了功能強大的商用軟體ZBrush,或者是開放自由的Sculptris,由於通常被泥塑的對象需要細緻的網格(Mesh),在這些部分逐漸龐多而複雜之後,在繪圖呈現上就會是個負擔。然而,不久前,我發現基於瀏覽器的SculptGL(https://bit.ly/2fur76q),雖然也是個雕塑軟體,在瀏覽器中執行的流暢性,卻令人訝異。

簡單來說,SculptGL是基於WebGL的網頁應用程式,實際上,OpenSCAD也有瀏覽器的移植版OpenJSCAD(https://openjscad.org),可使用JavaScript建模,同時,也有採用積木語言來建模的BlockSCAD(https://bit.ly/2tYKEBo),我仔細調查了一下,它們在3D繪圖上也都是基於WebGL。

在更專業的建模軟體部份,著名的SketchUp於2018年推出基於瀏覽器的免費版本;跨平臺2D/3D遊戲引擎Unity,在Unity5時,也延伸到基於WebGL技術的HTML5網頁平臺……我不禁好奇了,WebGL是什麼神器?目前瀏覽器的支援度,以及相關工具的成熟度到哪了?

瀏覽器裡的OpenGL?

根據維基百科的記載,WebGL在2011年3月首次發布規範,2017年1月完成2.0規範,至今各大主流瀏覽器的新版本都有支援,連IE11都有支援(儘管微軟官方已說IE只是個相容性方案了)。

就功能而言,WebGL是基於OpenGL ES(OpenGL for Embedded Systems),是OpenGL的嵌入式系統特化版本。瀏覽器可以透過WebGL,將大部份的繪圖渲染運算,送進專司影像運算的圖形處理器(GPU),從而增加瀏覽器上的繪圖效率。

就運用方式來說,WebGL常被誤解為一套JavaScript API,實際上,除了JavaScript語言,以及封裝OpenGL ES的JavaScript API之外,想要使用WebGL,同時還需要瞭解GLSL(OpenGL Shading Language)──這是一個類似C語言的著色語言,開發者需要使用GLSL撰寫著色器(Shader)程式,透過JavaScript API編譯並送入GPU,而JavaScript語言則負責繪圖以外的運算工作,並將繪圖需要的資料透過API送給著色器來渲染。

實際上,WebGL本身不複雜,一般人初學這項技術時,主要是面對頂點著色器(Vertex shader),以及片段著色器(Fragment shader),前者主要負責頂點的運算,將頂點對應至畫面上的二維座標;後者則是計算出需要繪製的像素顏色值,最簡單的繪製是一個點,其次是線,然後是三角形,之後更複雜的圖形,就要自己想辦法用三角形組成了,而處理這類細節會比較麻煩,複雜的部份往往涉及艱深的圖學與數學。

簡單來說,WebGL是個柵格化(Rasterization)引擎,它只關心兩件事:空間中的座標及顏色。例如,繪製三角形,必須計算出三個頂點於二維畫面上的位置,然後對這三個點圍起的三角形做像素填充,這就是頂點著色器與片段著色器的作用,想要認識WebGL,〈WebGL Fundamentals〉(https://bit.ly/1TgmSbk)是個不錯而全面的網站。

而在該網站第一篇文件中,就談到「WebGL實際上是個很簡單的API」,這並不誇大,它需要的部分,就是頂點著色器、片段著色器,以便繪製點、線、三角形。如果需要對整個圖形做平移、旋轉、變形等,開發者必須自己來,也就是說,要回歸到對電腦圖學的認識。

WebGL的夥伴們

當然,直接編寫WebGL相關程式碼,本身還是充滿細節而比較枯燥,對於常用的繪圖需求,封裝為程式庫是必要的,時至今日,確實有著不少封裝WebGL、提供高階操作的程式庫,而其中最有名的就是Three.js。

雖然Three.js本身也有不少的類別與函式,其核心概念卻很簡單。程式庫本身的隱喻,就像是在搭建舞臺,有個場景作為容器,可以加入網格物件、燈光等,相機則決定了場景中哪些物件是可見的,渲染器則會根據相機看到的東西,計算出場景中的物件應當如何渲染,而最常使用的渲染器,就是WebGLRenderer(也有基於SVG等的渲染器)。

Three.js中的網格物件,是由幾何(Geometry),以及材質(Material)物件組成──根據程式碼中指定的幾何物件資訊(例如立方體的長寬高),會自動計算出相關頂點;而材質會與燈光等物件結合,運算出應有的顏色;對於大量物件的高效率繪製,Three.js也提供了粒子系統的支援。掌握這些基本概念之後,剩下的就是挑選出Three.js中適當的API,例如,正交或投影相機、基礎或法向材質等來繪製出想要達到的效果。

除了作為動畫、遊戲基礎之外,Three.js也可結合ThreeBSP的擴充,進行聯集、交集、減集等操作,而這可用來建立類似OpenSCAD,也就是一套可以運行於瀏覽器中的建模軟體。如果想要系統性地學習Three.js,可以參考《Learning Three.js: The JavaScript 3D Library for WebGL》。

當然,WebGL可以繪製3D,要用來繪製2D圖形自然不成問題,基於WebGL的2D程式庫,最常見的是PixiJS。相較於直接基於Canvas API或SVG的程式庫(例如D3.js),PixiJS這類程式庫在大量資料呈現,會有效能優勢。

除了Three.js、Pixi.js,還有其他基於WebGL的程式庫,有些進一步整合了動畫或遊戲的功能,有興趣的話,可以參考〈3D探索──Web 3D哪家強?〉(https://bit.ly/2XOoBei),其中針對了各家程式庫在2D/3D WebGL的支援等做了比較。

實踐圖學與數學

雖然不用處理細節,然而在運用Three.js這類封裝WebGL的程式庫時,有圖學與幾何數學作為基礎非常有用,實際上Three.js也允許自訂頂點,必要時也可基於三角形來定義更複雜的圖形,這讓我想到先前為OpenSCAD打造程式庫時,也曾自行定義三角形,來實作出貝茲曲面、路徑跟隨(Sweep)或者是處理頂點等功能。

現今可選的WebGL程式庫繁多,但能從中實踐圖學與數學才是重點,就算直接面對WebGL也不例外,我在研究WebGL的過程中,意識到GLSL實作著色器,實際上就是操作點、線、三角形之後,雖然先前玩OpenSCAD是為了建模,然而累積的相關圖學與數學技巧,在理解與撰寫WebGL時就派上用場,而這類可過渡的知識才是真正有價值的地方!

專欄作者

熱門新聞

Advertisement