前端圖形學和前端架構師是現在前端兩大重點方向,而當前市場人才緊缺。
進入3D圖形世界可能是非常令人生畏的。無論你是想建立一個互動式的 3D logo,還是設計一個完全成熟的遊戲,如果不瞭解3D渲染的原理,你將會陷入泥潭——使用抽象度很高的庫。
使用庫可能是正確的做法,同時 JavaScript 有一個令人驚奇的開源庫 three.js。不過使用預製的解決方案還有一些缺點:
- 它們有許多你用不到的功能。基於three.js特性的簡化版的大小約為500kB,任何額外的功能(例如:載入模型檔案)會使有效載荷更大。傳輸這麼多的資料只是為了在你的網站上顯示一個旋轉的logo將是一種浪費。
- 額外的抽象層會使本來就很繁雜的維護工作更加困難。您可以在螢幕上直接以物件的方式進行創造,也可以花費幾十個小時把自己的工作合併到庫的抽象中。
- 雖然庫在大多數情況下都做到了良好的優化,可以幫你裁剪出許多花裡胡哨的東西。渲染器可能需要在你的顯示卡上執行幾百萬次特定的程式操作。如果想要在效能較差的顯示卡上毫無問題地處理你的內容,那就意味著要從這些操作中刪除一些處理指令。
即使你打算使用高階圖形庫,掌握基本知識也可以讓您更有效地使用它。庫也可以具有高階功能,例如 three.js
中的 ShaderMaterial
。瞭解圖形渲染的原理會幫你開啟新世界的大門。
我們的目標是要學會渲染 3D 圖形背後的所有關鍵概念,並能夠使用WebGL實現它們。 你將通過最司空見慣的東西來掌握他們。

表示一個 3D 模型
你需要了解的第一件事是如何表示 3D 模型。 模型是由許多三角形網格組成的。 每個三角形由三個頂點表示,在頂點上附加了三個最常見的屬性。
頂點位置
位置是頂點最直觀的屬性。 它是 3D 空間中的位置,由座標的 3D 向量表示。 如果你知道空間中三個點的精確座標,那麼就能確定在它們之間繪製一個簡單三角形所需要的所有資訊。 為了使模型在渲染時看起來很逼真,還需要為渲染器提供更多的東西。
頂點法線

我們來看上面的兩個模型。 它們是由相同的頂點位置組成的,但是渲染後的效果完全不一樣。這是怎麼回事呢?
除了告訴渲染器頂點所在的位置之外,還需要告訴它一個關於曲面在這個位置是怎麼傾斜的。 這就是在模型上特定點上的表面法線,它用3D向量表示。 下圖描述了它的處理方式。

上圖分別對應於前之前圖中的兩個球體。 紅色箭頭表示為頂點指定的法線,而藍色箭頭表示渲染器的法線應該怎樣對頂點之間的其它所有點進行計算。 儘管該圖是2D 形式的,但它的原理適用於3D 圖形。
法線是計算燈光照射物體表面時反射的輔助。 光線的方向越接近法線,照射點越亮。 照射方向在法線方向上的變化會導致光線的變化,雖然在模型的頂點處出現了突然的變化,但是實際上法線和光照之間的角度應該是逐漸變化的,所以在渲染出的光照效果應該是漸變的。
紋理座標
最後一個重要屬性是紋理座標,通常被稱為UV貼圖。 假設你有一個模型和一個要作用在其上的紋理,紋理上有各種區域,表示我們想要作用在模型上的不同部分的影象。必須有一種方法來標記紋理應該貼在模型上的哪個部分。 這就是紋理對映的用武之地。

載入OBJ模型
OBJ檔案格式非常簡單,只需要幾行程式碼就可以實現。信不信由你,這就是建立一個簡單的模型載入器所需要做的一切。
執行空間變換
在我們載入的模型中,所有點都和它的座標系相關。 如果想要做到轉換、旋轉和縮放模型這些操作,我們需要做的就是在其座標系上執行空間變換。
轉換過程示意

縮放過程示意

旋轉過程示意

攝像機視角
這是在螢幕上呈現物件的關鍵部分:攝像機。 攝像機有兩個關鍵點: 1、位置。2、它是怎樣把觀察到的物體投射到螢幕上的。
攝像機位置可以通過一個簡單的技巧處理。把攝像機向前移動一米和把整個世界向後移動一米之兩種操作並沒有什麼不同。這些可以通過矩陣運算來實現。
第二個關鍵點是被觀察的物體被投射到鏡頭上的方式。 在WebGL中,螢幕上可見的所有內容都位於一個框中。可見的一切都在一個盒子裡。 可以使用相同的矩陣變換方法來建立投影矩陣。

最簡單的投影是正投影。 你在空間中取一個方框,假設它的中心位於立體座標系的零點位置。 然後調整框的大小使其適合前面所描述的框,WebGL 就能在其中觀察物件了。
使用WebGL圖形管道繪製物件
您可以繪製的最簡單的表面是三角形。 實際上,您在3D空間中繪製的大部分內容都包含大量三角形。

在這裡你需要知道的概念是:
- 預設幀緩衝區
- 頂點緩衝物件
- 著色器
- 頂點著色器
- 片段著色器
還需要這樣幾個步驟:
- 繪製模型
- 新增光照
- 新增紋理
最後就能得到我們想要的效果了:

以上,就是我今天想要分享給大家的內容,相信你對前端有了一些新的感受。
以上內容選自我的專題課《前端圖形學開發實踐指南》,這僅僅是這門課程的冰山一角。
如果感興趣,可以關注京程一燈公眾號:jingchengyideng,後臺回覆“1”,報名免費試聽活動。