電腦圖形渲染基礎

最後更新: 2021-07-31 18:25:07 +0800 +0800
tags: Graphics | Webgl | Gpu
原文以英文撰寫。您正在閱讀AI翻譯版本。

渲染會將抽象幾何轉換為像素。GPU 管線會取得頂點、轉換它們、裁切它們、光柵化可見形狀,並對產生的片段進行著色。

管線 #

典型的渲染管線包含以下階段:

  1. 頂點處理;
  2. 基元組裝;
  3. 裁切與視埠轉換;
  4. 光柵化;
  5. 片段著色;
  6. 深度與混合;
  7. 畫格緩衝區寫回。

這個順序很重要,因為每個階段都會將問題從幾何逐步縮小到像素。

頂點資料 #

輸入通常從頂點清單與索引緩衝區開始。

  • 頂點包含位置,以及色彩、法線或紋理座標等選用屬性;
  • 索引會在三角形之間重複使用頂點;
  • 基元通常是三角形,因為三角形總是共平面。

頂點著色器會在每個頂點執行一次。它的工作是將位置轉換到裁切空間,並將每個頂點的資料傳遞到後續階段。傳統轉換會將每個物件空間位置乘以模型、視圖與投影矩陣:

text
clip_position = projection * view * model * object_position

模型矩陣將物件放置到世界空間,視圖矩陣表達相對於攝影機的世界,投影矩陣則將攝影機空間的視錐映射到齊次裁切空間。矩陣順序取決於 API 與向量慣例;著色器與主機程式碼必須一致。

裁切空間與裁切 #

裁切空間外的幾何會在光柵化前被裁切。在 OpenGL 與 WebGL 中,當 -w <= x, y, z <= w 時,裁切空間頂點位於內部。若三角形跨越邊界,GPU 會建立可見多邊形並捨棄外部部分。

裁切後,透視除法會將正規化裝置座標(NDC)計算為 (x/w, y/w, z/w)。接著視埠轉換會將 NDC 映射到視窗座標。透視相依屬性的插值會使用齊次 w 值,因此紋理座標不會像仿射螢幕空間值那樣失真。

光柵化 #

光柵化會將三角形轉換為片段,也就是候選像素。光柵器會決定哪些取樣位置位於三角形內,並在表面上插值屬性。

插值值包括:

  • 色彩;
  • 深度;
  • 紋理座標;
  • 法線或其他 varying。

即使輸入只在角落指定值,這項插值也能讓三角形呈現漸層。

片段著色 #

片段著色器會在每個片段執行一次,並計算最終色彩或捨棄決策。

典型的片段工作包括:

  • 紋理取樣;
  • 光照近似;
  • alpha 測試或捨棄;
  • 色彩校正;
  • 程序式圖樣。

許多視覺上重要的效果都發生在這個階段,因為著色器可以將插值屬性與紋理及 uniform 結合。

深度、混合與畫格緩衝區 #

深度緩衝區會解決重疊基元之間的可見性。若一個片段比另一個更接近,通常會保留較近的片段。

混合會組合半透明表面的來源與目的地色彩。它對透明度、粒子與 UI 效果很有用,但取決於繪製順序。通常會先啟用深度寫入繪製不透明幾何,再使用仔細選取的混合因子,由後往前繪製半透明幾何。

最終色彩會寫入畫格緩衝區,接著呈現到螢幕或影像目標。

WebGL 視角 #

WebGL 透過 JavaScript 暴露這條管線。canvas 提供繪製表面,著色器以來源字串提供,瀏覽器將工作交給 GPU。WebGL 繼承 OpenGL ES 的裁切空間慣例:NDC 在三個軸上都涵蓋 [-1, 1],而視窗座標將視埠原點放在左下角。瀏覽器影像來源通常是由上而下,因此紋理上傳或座標可能需要明確垂直翻轉。

心智模型仍然相同:

  • 上傳緩衝區;
  • 設定頂點屬性;
  • 編譯著色器;
  • 綁定程式、畫格緩衝區與其他必要狀態;
  • 繪製三角形;
  • 呈現產生的畫格。

實務規則 #

WebGL 是狀態機。繪製呼叫會使用目前綁定的程式、頂點陣列與緩衝區繫結、紋理、畫格緩衝區、視埠、深度狀態與混合狀態。當輸出錯誤時,應檢查繪製呼叫時的完整狀態,而不只是著色器來源。

評論

在 GitHub 上閱讀或評論(發表評論需要登入)