Cg 中提供了三個關鍵字,in、out、inout,用於表示函數的 輸入參數的傳遞方式,稱為輸入\輸出關鍵字,這組關鍵字可以和語義詞合用表 達硬件上不同的存儲位置,即同一個語義詞,使用 in 關鍵字修辭和 out 關鍵詞修 辭,表示的圖形硬件上不同的寄存器。
1. in: 修辭一個形參只是用於輸入,進入函數體時被初始化,且該形參值 的改變不會影響實參值,這是典型的值傳遞方式。 2. out: 修辭一個形參只是用於輸出的,進入函數體時並沒有被初始化,這 種類型的形參一般是一個函數的運行結果; 3. inout: 修辭一個形參既用於輸入也用於輸出,這是典型的引用傳遞。 舉例如下: void myFunction(out float x); //形參 x,只是用於輸出 void myFunction(inout float x); //形參 x,即用於輸入時初始化,也用於輸出數據,也可以使用 return 語句來代替 out 修辭符的使用。輸入\輸出修辭符通常和語 義詞一起使用,表示頂點着色程序和片段着色程序的輸入輸出。
Cg 語言還提供兩個修辭符:uniform,用於指定變量的數據初始化方式;const 關鍵字的含義與 C\C++中相同,表示被修辭變量為常量變量。
Cg 語言將輸入數據流分為兩類:
1. Varying inputs,即數據流輸入圖元信息的各種組成要素。從應用程序輸入 到 GPU 的數據除了頂點位置數據,還有頂點的法向量數據,紋理坐標數據 等。Cg 語言提供了一組語義詞,用以表明參數是由頂點的哪些數據初始化 的。
2. Uniform inputs,表示一些與三維渲染有關的離散信息數據,這些數據通 常由應用程序傳入,並通常不會隨着圖元信息的變化而變化,如材質對光的 反射信息、運動矩陣等。Uniform 修辭一個參數,表示該參數的值由外部應 用程序初始化並傳入;例如在參數列表中寫:
uniform float brightness,
uniform float4x4 modleWorldProject
表示從“外部”傳入一個 float 類型數據,和一個 4 階矩陣。“外部”的含義 通常是用 OpenGL 或者 DirectX 所編寫的應用程序。 使用 Uniform 修辭的變量,除了數據來源不同外,與其他變量是完全一樣的。 需要注意的一點是:uniform 修辭的變量的值是從外部傳入的,所以在 Cg 程 序(頂點程序和片段程序)中通常使用 uniform 參數修辭函數形參,不容許聲明 一個用 uniform 修辭的局部變量!否則編譯時會出現錯誤提示信息: Error C5056:’uniform’not allowed on local variable 。
Cg 語言也提供 const 修辭符,與 C\C++中含義一樣,被 const 所修辭的變量 在初始化之后不能再去改變它的值。
在 C\C++中,當一個數組作為函數的形參時,實際上傳入的只是指向首元素 的指針,並且數組邊界被忽略(參閱 stephen C.Dewhurst 所著的《C++必知必會》)。 而在 Cg 語言中不存在指針機制(圖形硬件不支持),數組作為函數形參,傳遞 的是數組的完整拷貝。
Cg 語言支持函數重載(Functon Overlaoding),其方式和 C++基本一致,通 過形參列表的個數和類型來進行函數區分。
通常高級語言程序中只有一個入口函數,不過由於着色程序分為頂點程序和 片斷程序,兩者對應着圖形流水線上的不同階段,所以這兩個程序都各有一個入 口函數。 頂點程序和片段程序有且只有一個入口函數,當程序進行編譯時,需要指定 入口函數名稱,除非入口函數名為 main。頂點程序和片段程序的入口函數形式,已經完全由 它們在渲染管線中所處的階段所決定。在前面已經闡述過,頂點程序接收應用程 序傳遞的頂點數據(通常位於模型坐標空間),然后進行坐標空間轉換和光照處 理,最后輸出投影坐標和計算得到的光照顏色;而片段程序接收從頂點程序輸出 的數據,並進行像素顏色計算。在片段程序中往往涉及到紋理顏色的處理,其輸 入參數中常有紋理形參的聲明。所以通過觀察程序的輸入輸出語義綁定,就可以區分入口函數對應到頂點程序還是片段程序。
Cg 標准函數庫主要分為五個部分: 1. 數學函數(Mathematical Functions); 2. 幾何函數(Geometric Functions); 3. 紋理映射函數(Texture Map Functions); 4. 偏導數函數(Derivative Functions); 5. 調試函數(Debugging Function);
1.數學函數:
2.幾何函數:Cg 語言標准函數庫中有 3 個幾何函數會經常被使用到,分別是:normalize 函數,對向量進行歸一化;reflect 函數,計算反射光方向向量;refract 函數,計算折射光方向向量。強烈注意: 1. 着色程序中的向量最好進行歸一化之后再使用,否則會出現難以預料的 錯誤; 2. reflect 函數和 refract 函數都存在以“入射光方向向量”作為輸入參數, 注意這兩個函數中使用的入射光方向向量,是從外指向幾何頂點的;平時我 們在着色程序中或者在課本上都是將入射光方向向量作為從頂點出發。
3.紋理映射函數:s 象征一元、二元、三元紋理坐標;z 代表使用“深度比較(depth comparison)” 的值;q 表示一個透視值(perspective value,其實就是透視投影后所得到的齊次坐 標的最后一位),這個值被用來除以紋理坐標(S),得到新的紋理坐標(已歸一 化到 0 和 1 之間)然后用於紋理查詢。 紋理函數非常多,總的來說,按照紋理維數進行分類,即:1D 紋理函數, 2D 紋理函數,3D 紋理函數,已經立方體紋理。需要注意,TexREC 函數查詢的 紋理實際上也是二維紋理。
tex1D(sampler1D tex, float s) 一維紋理查詢
tex1D(sampler1D tex, float s, float dsdx, float dsdy) 使用導數值(derivatives)查詢一維紋理
Tex1D(sampler1D tex, float2 sz) 一維紋理查詢,並進行深度值比較
Tex1D(sampler1D tex, float2 sz, float dsdx,float dsdy) 使用導數值(derivatives)查詢一維紋理, 並進行深度值比較
Tex1Dproj(sampler1D tex, float2 sq) 一維投影紋理查詢
Tex1Dproj(sampler1D tex, float3 szq) 一維投影紋理查詢,並比較深度值
Tex2D(sampler2D tex, float2 s) 二維紋理查詢
Tex2D(sampler2D tex, float2 s, float2 dsdx, float2 dsdy) 使用導數值(derivatives)查詢二維紋理
Tex2D(sampler2D tex, float3 sz) 二維紋理查詢,並進行深度值比較
Tex2D(sampler2D tex, float3 sz, float2 dsdx,float2 dsdy) 使用導數值(derivatives)查詢二維紋理,並進行深度值比較
Tex2Dproj(sampler2D tex, float3 sq) 二維投影紋理查詢
Tex2Dproj(sampler2D tex, float4 szq) 二維投影紋理查詢,並進行深度值比較
texRECT(samplerRECT tex, float2 s)
texRECT (samplerRECT tex, float2 s, float2 dsdx, float2 dsdy)
texRECT (samplerRECT tex, float3 sz)
texRECT (samplerRECT tex, float3 sz, float2 dsdx,float2 dsdy)
texRECT proj(samplerRECT tex, float3 sq) texRECT proj(samplerRECT tex, float3 szq) Tex3D(sampler3D tex, float s) 三維紋理查詢
Tex3D(sampler3D tex, float3 s, float3 dsdx, float3 dsdy) 結合導數值(derivatives)查詢三維紋理
Tex3Dproj(sampler3D tex, float4 szq) 查詢三維投影紋理,並進行深度值比較
texCUBE(samplerCUBE tex, float3 s) 查詢立方體紋理
texCUBE (samplerCUBE tex, float3 s, float3 dsdx, float3 dsdy) 結合導數值(derivatives)查詢立方體紋理
texCUBEproj (samplerCUBE tex, float4 sq) 查詢投影立方體紋理
4.偏導函數:偏導數的物理含義是:在某一個方向上的變化快慢。 所以 ddx 求的是 X 方向上,相鄰兩個像素的某屬性值的變化量;ddy 球的是 Y 方向上,相鄰兩個像素的某屬性值的變化量。 如果函數 ddx 的參數為 myVar,該參數對應的像素點 記為 pij ( ) , ,則 ddx(myVar)的值為“像素點 pi j ( +1, ) 的值減去 myVar”。同理, 92 ddy(myVar)的值為“像素點 pij ( ) , 1+ 的值減去 myVar”。如果函數 ddx 和 ddy 的輸 入參數為常數,則函數返回值永遠為 0。
ddx(a) 參數 a 對應一個像素位置,返回該像素 值在 X 軸上的偏導數
ddy(a) 參數 a 對應一個像素位置,返回該像素 值在 X 軸上的偏導數
作用:1. 函數 ddx 和 ddy 用於求取相鄰像素間某屬性的差值; 2. 函數 ddx 和 ddy 的輸入參數通常是紋理坐標; 3. 函數 ddx 和 ddy 返回相鄰像素鍵的屬性差值;