着色器

出自Wikipedia
跳至導覽 跳至搜尋
着色器的常見應用是為三維模型生成光照和陰影。

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

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

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

歷史[編輯]

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

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

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

種類[編輯]

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

二維着色器[編輯]

二維着色器處理的是數字圖像,也叫紋理,着色器可以修改它們的像素。二維着色器也可以參與三維圖形的渲染。目前只有「像素着色器」一種二維着色器。

像素着色器[編輯]

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

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

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

三維着色器[編輯]

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

  • 頂點着色器處理每個頂點,將頂點的空間位置投影在屏幕上,即計算頂點的二維坐標。同時,它也負責頂點的深度緩衝(Z-Buffer)的計算。頂點着色器可以掌控頂點的位置、顏色和紋理坐標等屬性,但無法生成新的頂點。頂點着色器的輸出傳遞到流水線的下一步。如果有之後定義了幾何着色器,則幾何着色器會處理頂點着色器的輸出數據,否則,光柵化器繼續流水線任務。
  • 幾何着色器可以從多邊形網格中增刪頂點。它能夠執行對CPU來說過於繁重的生成幾何結構和增加模型細節的工作。Direct3D版本10增加了支持幾何着色器的API, 成為Shader Model 4.0的組成部分。OpenGL只可通過它的一個插件來使用幾何着色器,但極有可能在3.1版本中該功能將會歸併。幾何着色器的輸出連接光柵化器的輸入。

由於這些類型的着色器終究會用在GPU的流水線中,下面簡述它們是如何被安排在流水線中的。

簡化圖形流水線[編輯]

對於圖形流水線的一般描述,參見繪圖管線

  • 中央處理器(CPU)發送指令(編譯的着色器程序)和幾何數據到位於顯卡內的圖形處理器(GPU)。
  • 頂點着色器執行幾何變換和光照計算。
  • 若幾何着色器位於圖形處理器內,它便會修改一些幾何信息。
  • 計算後的幾何模型被三角化(分割為三角形)。
  • 三角形被映射為2×2的像素塊。

並行計算[編輯]

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

對着色器編程[編輯]

OpenGL從版本1.5開始集成了一種類C語言着色語言,稱為OpenGL着色語言(GLSL)。同時NVidia也開發了Cg,其語法與GLSL類同。

在Direct3D里,着色器使用高級着色器語言HLSL)。它的數據類型和允許的算法複雜程度因不同的版本而異。下表簡述了Direct3D的不同版本:

Direct3D 版本 像素着色器 頂點着色器
8.0 1.0, 1.1 1.0, 1.1
8.1 1.2, 1.3, 1.4 1.0, 1.1
9.0 2.0 2.0
9.0a 2_A, 2_B 2.x
9.0c 3.0 3.0
10.0 4.0 4.0
10.1 4.1 4.1
11 5.0 5.0

XNA中實現Shader[編輯]

XNA中實現Shader很簡單。對XNA程式來說,Shader是一個小程式,只要把shader文件(.fx)導入到Contents 即可,會自動生成素材。再透過XNA Effect class 來加載和編譯shader。HLSL可以在XNA或是DirectX使用。

舊版:

 effect = Content.Load("MyShader"); 
 effect.CurrentTechnique = effect.Techniques ["AmbientLight" ]; 
 effect.Begin(); 
 foreach (EffectPass pass in effect.CurrentTechnique.Passes) 
 {
    pass.Begin(); 
 ... 
    pass.End();
 }
 effect.End(); // 終止使用 effect

新版(4.0):

 effect = Content.Load("MyShader"); 
 effect.CurrentTechnique = effect.Techniques ["AmbientLight" ];  
 foreach (EffectPass pass in effect.CurrentTechnique.Passes) 
 {
    pass.Apply();
 ... 
 }

參考資料[編輯]

拓展閱讀[編輯]

外部連結[編輯]