電腦圖學領域中,著色器(英語:shader)是一種電腦程式,原本用於進行圖像的濃淡處理(計算圖像中的光照亮度顏色等),但近來,它也被用於完成很多不同領域的工作,比如處理CG特效、進行與濃淡處理無關的影片後期處理英語video post-processing、甚至用於一些與電腦圖學無關的其它領域。[1]

著色器的常見應用是為三維模型生成光照和陰影。

使用著色器在圖形硬體上計算彩現效果有很高的自由度。儘管不是硬性要求,但目前大多數著色器是針對GPU開發的。GPU的可程式化繪圖管線已經全面取代傳統的固定管線,可以使用著色器語言對其編程。構成最終圖像的像素頂點紋理,它們的位置、色相、飽和度、亮度、對比度也都可以利用著色器中定義的演算法進行動態調整。呼叫著色器的外部程式,也可以利用它向著色器提供的外部變數、紋理來修改這些著色器中的參數。

電影後期處理、電腦成像電子遊戲等領域,著色器常被用來製作各種特效。除了普通的光照模型,著色器還可以調整圖像的色相飽和度亮度對比度,生成模糊高光、有體積光源、失焦、卡通彩現色調分離畸變凹凸貼圖色鍵(即所謂的藍幕、綠幕摳像效果)、邊緣檢測等效果。

歷史

編輯

1988年5月,Pixar公布了第三版RenderMan規範,將「著色器」的使用推廣到了我們目前所知的各大應用領域。[2]

隨著圖形處理器的進步,OpenGLDirect3D等主要的圖形軟體庫都開始支援著色器。第一批支援著色器的 GPU 僅支援像素著色器,但隨著開發者逐漸認識到著色器的強大,很快便出現了頂點著色器。2000年,第一款支援可程式化像素著色器的顯示卡 Nvidia GeForce 3(NV20)問世。Direct3D 10 和 OpenGL 3.2 則引入了幾何著色器。

目前,圖形硬體正在朝統一著色器模型英語Unified shader model發展。

設計

編輯

著色器是描述頂點或像素特徵的簡單程式。頂點著色器描述頂點的屬性(位置、紋理坐標、顏色等),而像素著色器描述像素的特徵(顏色、z深度和alpha值)。

基本圖形管線如下所示:

  • 中央處理器(CPU)傳送指令(已編譯的著色器程式)和幾何資料到位於顯示卡內的圖形處理器(GPU)。
  • 頂點著色器執行幾何變換。
  • 若幾何著色器位於圖形處理器內並已啟用,它便會修改一些場景中的幾何結構。
  • 若細分著色器位於圖形處理器內並已啟用,場景中的幾何結構會被細分。
  • 計算後的幾何結構被三角化(分割為三角形)。
  • 三角形被分解為2 × 2的像素塊。
  • 像素塊通過片段著色器被修改。
  • 進行深度測試;通過的片段將被寫入螢幕,並可能被混合到訊框緩衝區中。

種類

編輯

常用的著色器有三種。比較老的顯示卡傾向於使用不同的處理單元處理不同類型的著色器,但新出的顯示卡通常都支援統一著色器模型英語Unified shader model,可以執行任意類型的著色器、更好地發揮顯示卡的處理能力。[3]

二維著色器

編輯

二維著色器處理的是數位影像,也叫紋理,著色器可以修改它們的像素。二維著色器也可以參與三維圖形的彩現。目前只有「像素著色器」一種二維著色器。

像素著色器

編輯

像素著色器(英語:pixel shader)也叫片段著色器(英語:fragment shader),用於計算「片段」的顏色和其它屬性,此處的「片段」通常是指單獨的像素。最簡單的像素著色器只有輸出顏色值;複雜的像素著色器可以有多個輸入輸出[4]。像素著色器既可以永遠輸出同一個顏色,也可以考慮光照、做凹凸貼圖、生成陰影高光,還可以實現半透明等效果。像素著色器還可以修改片段的深度,也可以為多個彩現目標輸出多個顏色。

三維圖學中,單獨一個像素著色器並不能實現非常複雜的效果,因為它只能處理單獨的像素,沒有場景中其它幾何體的資訊。不過,像素著色器有螢幕坐標資訊,如果將螢幕上的內容作為紋理傳入,它就可以對當前像素附近的像素進行採樣。利用這種方法,可以實現大量二維後期特效,例如模糊和邊緣檢測

像素著色器還可以處理管線中間過程中的任何二維圖像,包括精靈紋理。因此,如果需要在柵格化後進行後期處理,像素著色器是唯一選擇。

三維著色器

編輯

三維著色器處理的是三維模型或者其它幾何體,可以訪問用來繪製模型的顏色和紋理。頂點著色器是最早的三維著色器;幾何著色器可以在著色器中生成新的頂點;細分曲面著色器(英語:tessellation shader)則可以向一組頂點中添加細節。

頂點著色器

編輯

頂點著色器是最常見的一種 3D 著色器,對每個交給圖形處理器的頂點都執行一次。目的是將每個頂點在虛擬空間中的 3D 坐標變換到在螢幕上顯示的 2D 坐標(深度緩衝(Z-Buffer)的深度值也是如此)。頂點著色器可以掌控頂點的位置、顏色和紋理坐標等屬性,但無法生成新的頂點。頂點著色器的輸出傳遞到管線的下一步。如果有之後定義了幾何著色器,則幾何著色器會處理頂點著色器的輸出資料,否則,光柵化器繼續管線任務。

幾何著色器

編輯

幾何著色器在 OpenGL 3.2 和 Direct3D 10 中被引入, 以前可在帶擴充的 OpenGL 2.0+ 中使用。改類型的著色器可以生成新的圖形基元,比如點,線和三角形。幾何著色器可以從多邊形網格中增刪頂點。它能夠執行對 CPU 來說過於繁重的生成幾何結構和增加模型細節的工作。Direct3D 10 增加了支援幾何著色器的API,成為 Shader Model 4.0 的組成部分。OpenGL 只可通過它的一個外掛程式來使用幾何著色器,但極有可能在3.1版本中該功能將會合併。幾何著色器的輸出連接光柵化器的輸入。

曲面細分著色器

編輯

曲面細分著色器作為一類新的著色器,在 OpenGL 4.0 和 Direct3D 11 中被引入,並在著色器的模型增加了兩個階段:曲面細分控制著色器(或外殼著色器)和曲面細分評估著色器(或域著色器)。這允許了較簡單的網格藉由特定函式計算,實時被細分成更細膩的網格。這個函示可以與多種變數相關,包含與視點的距離,因此可以主動調整細節層次,使較接近相機的物體有著較多細節。藉由在著色器單元中才加上細節,這還可以大幅降低網格所需的頻寬,也不需要降採樣記憶體中的網格。有些計算方式可以上採樣任意的網格,有些則允許「提示」網格所要凸顯的頂點和邊緣。

圖元和網格著色器

編輯

大約 2017 年, 圖元著色器做為新的著色器階段被 AMD Vega 微體系結構所支援。類似可以訪問必要資料的計算著色器來處理幾何體。

光線追蹤著色器

編輯

光線追蹤著色器被微軟的 DirectX 光線追蹤,Khronos Group 的 Vulkan,GLSL 和 SPIR-V,蘋果的 Metal 所支援。

計算著色器

編輯

計算著色器並不僅限於圖形應用程式,還有使用相同的通用圖形處理單元執行資源的程式。它們可能在圖形管線中被使用,比如額外的動畫階段或光照演算法。 一些彩現 API 允許計算著色器輕鬆的與圖形管線共享資料資源。

並列處理

編輯

著色器被用來同時處理大量的資料,比如螢幕上的一整塊像素群,或者一個模型結構的所有頂點平行計算適用於這樣的情況,而且當今的GPU也設計有多核結構來極大的提高處理效率。

編程

編輯

用於編寫著色器的程式語言取決於目標環境。官方的OpenGL和OpenGL ES著色語言是OpenGL著色語言,也稱為GLSL,官方的Direct3D著色語言是進階著色器語言,也稱為HLSL。Cg是輝達開發的第三方著色語言,可輸出OpenGL和Direct3D著色器;然而,自2012年以來,它一直被棄用。蘋果發布了自己的著色語言,稱為Metal著色語言,作為Metal框架的一部分。

GUI 著色器編輯器

編輯

現代電子遊戲開發平台,如 UnityUnreal EngineGodot 越來越多的包含了基於節點的編輯器,允許建立著色器而無需編寫實際的代碼。向使用者展現了包含相互連接的節點的有向圖,允許使用者將各種各樣的紋理,對映和數學函式直接導向輸出值,如漫反射顏色,突顯和強度,金屬度/粗糙度,高度,法向量等。自動將這些圖編譯為實際的已編譯的著色器。

另見

編輯

參考資料

編輯
  1. ^ Best Practices Memo. Cra.org. [2014-05-01]. (原始內容存檔於2014-05-02). 
  2. ^ The RenderMan Interface Specification. (原始內容存檔於2019-06-16). 
  3. ^ Pipeline Stages (Direct3D 10) (Windows). msdn.microsoft.com. [2021-09-15]. (原始內容存檔於2010-05-21). 
  4. ^ 存档副本. [2018-06-25]. (原始內容存檔於2021-04-24). 

拓展閱讀

編輯

外部連結

編輯