計算機圖形學領域中,着色器(英語: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). 

拓展閱讀

外部連結