著色器

維基百科,自由的百科全書
前往: 導覽搜尋

著色器英語shader)應用於計算機圖形學領域,指一組供計算機圖形資源在執行渲染任務時使用的指令。程式設計師將著色器應用於圖形處理器(GPU)的可程式流水線,來實現三維應用程序。這樣的圖形處理器有別於傳統的固定流水線處理器,為GPU編程帶來更高的靈活性和適應性。

背景[編輯]

從技術的角度來看,著色器是渲染器的一個部分,它負責計算目標的顏色。

隨著圖形處理單元的進步,主要的圖形軟體庫,像OpenGLDirect3D都開始將目光投向更高階的功能,即用著色器給新型的GPU編程,這就需要開發一系列的應用程序介面(API)滿足著色功能。這樣的改動出現在OpenGL的1.5版本和Direct3D的8版本。

著色器的種類[編輯]

Direct3D和OpenGL都使用了以下三種著色器:

  • 頂點著色器處理每個頂點,將頂點的空間位置投影在螢幕上,即計算頂點的二維坐標。同時,它也負責頂點的深度緩衝(Z-Buffer)的計算。頂點著色器可以掌控頂點的位置、顏色和紋理坐標等屬性,但無法生成新的頂點。頂點著色器的輸出傳遞到流水線的下一步。如果有之後定義了幾何著色器,則幾何著色器會處理頂點著色器的輸出數據,否則,光柵化器繼續流水線任務。
  • 幾何著色器可以從多邊形網格中增刪頂點。它能夠執行對CPU來說過於繁重的生成幾何結構和增加模型細節的工作。Direct3D版本10增加了支持幾何著色器的API, 成為Shader Model 4.0的組成部分。OpenGL只可通過它的一個外掛程式來使用幾何著色器,但極有可能在3.1版本中該功能將會歸併。幾何著色器的輸出連接光柵化器的輸入。
  • 像素著色器(Direct3D),常常又稱為片斷著色器(OpenGL),處理來自光柵化器的數據。光柵化器已經將多邊形填滿並通過流水線傳送至像素著色器,後者逐像素計算顏色。像素著色器常用來處理場景光照和與之相關的效果,如凸凹紋理映射調色。名稱片斷著色器似乎更為準確,因為對於著色器的調用和螢幕上像素的顯示並非一一對應。舉個例子,對於一個像素,片斷著色器可能會被調用若干次來決定它最終的顏色,那些被遮擋的物體也會被計算,直到最後的深度緩衝才將各物體前後排序。

統一著色器模型將上述三種著色器統一起來,發佈於OpenGL和Direct3D 10裡面。

由於這些類型的著色器終究會用在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();
 ... 
 }

外部連結[編輯]

參見[編輯]

引用[編輯]

  1. ^ Search ARB_shader_objects for the issue "32) Can you explain how uniform loading works?". This is an example of how a complex data structure must be broken in basic data elements.
  2. ^ Required machinery has been introduced in OpenGL by ARB_multitexture but this specification is no more available since its integration in core OpenGL 1.2.
  3. ^ Search again ARB_shader_objects for the issue "25) How are samplers used to access textures?". You may also want to check out "Subsection 2.14.4 Samplers".