和 C 的標准函數庫類似,Cg 提供了一系列內建的標准函數。這些函數用於執行數學上的通用計算或通用算法(紋理映射等),例如,需要求取入射光線的反射光線方向向量可以使用標准函數庫中的 reflect 函數,求取折射光線方向向量可以使用 refract 函數,做矩陣乘法運算時可以使用 mul 函數。
有些函數直接和 GPU 指令相對應,所以執行效率非常高。絕大部分標准函數都被重載過,用於支持不同長度的數組和向量作為輸入參數。
Cg 標准函數會隨着未來 GPU 硬件的發展而不斷優化,所以基於標准函數庫寫的程序是可以用在以后的 GPU 硬件上的。 Cg 標准函數庫主要分為五個部分:
數學函數(Mathematical Functions);
幾何函數(Geometric Functions);
紋理映射函數(Texture Map Functions)
偏導數函數(Derivative Functions);
調試函數(Debugging Function)
數學函數(Mathematical Functions)
數學函數用於執行數學上常用計算,包括:三角函數、冪函數、園函數、向量和矩陣的操作函數。這些函數都被重載,以支持標量數據和不同長度的向量作為輸入參數。
函數 功能
abs(x) 返回輸入參數的絕對值
acos(x) 反余切函數,輸入參數范圍為[-1,1],返回[0,π]區間的角度值
all(x) 如果輸入參數均不為0,則返回 ture;否則返回 flase。&&運算
any(x) 輸入參數只要有其中一個不為 0,則返回 true。||運算
asin(x) 反正弦函數,輸入參數取值區間為[−1,1],返回角度值范圍為[−π/2 ,π/2 ]
atan(x) 反正切函數,返回角度值范圍為⎡−π/2 ,π/2 ⎤
atan2(y,x) 計算 y/x 的反正切值。實際上和 atan(x)函數功能完全一樣,至少輸入參數不同。atan(x) = atan2(x, float(1))
ceil(x) 對輸入參數向上取整。例如:ceil(float(1.3)) ,其返回值為 2.0
clamp(x,a,b) 如果 x 值小於 a,則返回 a;如果 x 值大於 b,返回 b;否則,返回 x
cos(x) 返回弧度 x 的余弦值。返回值范圍為[−1,1]
osh(x) 雙曲余弦(hyperbolic cosine)函數,計算 x 的雙曲余弦值
cross(A,B) 返回兩個三元向量的叉積(cross product)。注意,輸入參數必須是三元向量
degrees(x) 輸入參數為弧度值(radians),函數將其轉換為角度值(degrees)
determinant(m) 計算矩陣的行列式因子
dot(A,B) 返回 A 和 B 的點積(dot product)。參數 A 和 B 可以是標量,也可以是向量(輸入參數方面,點
積和叉積函數有很大不同)
exp(x) 計算ex 的值,e= 2.71828182845904523536
exp2(x) 計算2x 的值
floor(x) 對輸入參數向下取整。例如floor(float(1.3)) 返回的值為 1.0;但是 floor(float(-1.3))返回的值為-2.0。
fmod(x,y) 返回 x/y 的余數。如果 y 為 0,結果不可預料
frexp(x, out exp) 將浮點數 x 分解為尾數和指數,即 x = m* 2^exp,返回 m,並將指數存入 exp 中;如果 x 為 0,則尾數和指數都返回 0
frac(x) Returns the fractional portion of a scalar or each vector component
isfinite(x) 判斷標量或者向量中的每個數據是否是有限數,如果是返回 true;否則返回false;無限的或者非數據(not-a-number NaN)
isinf(x) 判斷標量或者向量中的每個數據是否是無限,如果是返回 true;否則返回false;
isnan(x) 判斷標量或者向量中的每個數據是否是非數據(not-a-number NaN),如果是返回 true;否則返回 false;
ldexp(x, n) 計算x∗2n 的值
lerp(a, b, f) 計算(1− f )∗ + ∗a b f 或者a+ f ∗ −(b a)的值。即在下限 a 和上限 b 之間進行插值,f 表示權值。注意,如果 a 和 b 是向
量,則權值 f 必須是標量或者等長的向量。
lit(NdotL, NdotH, m) N 表示法向量;L 表示入射光向量;H 表示半角向量;m 表示高光系數。
函數計算環境光、散射光、鏡面光的貢獻,返回的 4 元向量:
1.位表示環境光的貢獻,總是 1.0;
2.位代表鏡面光的貢獻,如果 N •L <0,則為0;否則為 N •L;
3.位代表鏡面光的貢獻,如果N •L<0或者 N •H <0 ,則位 0;否則為(N •H)m ;
W 位始終位 1.0
log(x) 計算ln(x)的值,x 必須大於 0
log2(x) 計算log(2x) 的值,x 必須大於 0
log10(x) 計算log10(x) 的值,x 必須大於 0
max(a, b) 比較兩個標量或等長向量元素,返回 大值
min(a,b) 比較兩個標量或等長向量元素,返回 小值
modf(x, out ip) | |
mul(M, N) | 計算兩個矩陣相乘,如果 M 為 AxB 階矩陣,N 為 BxC階矩陣,則返回 AxC 階矩陣。下面兩個函數為其重載函數。 |
mul(M, v) | 計算矩陣和向量相乘 |
mul(v, M) | 計算向量和矩陣相乘 |
noise( x) | 噪聲函數,返回值始終在 0,1 之間;對於同樣的輸入,始終返回相同的值(也就是說,並不是真正意義上的隨機噪聲)。 |
pow(x, y) | |
radians(x) | 函數將角度值轉換為弧度值 |
round(x) | Round-to-nearest,或 closest integer to x 即四舍五入 |
rsqrt(x) | X 的反平方根,x 必須大於 0 |
saturate(x) | 如果 x 小於 0,返回 0;如果 x 大於 1,返回1;否則,返回 x |
sign(x) | 如果 x 大於 0,返回 1;如果 x 小於 0,返回01;否則返回 0。 |
sin(x) | 輸入參數為弧度,計算正弦值,返回值范圍為[−1,1] |
sincos(float x, out s, out c) | 該函數是同時計算 x 的 sin 值和 cos 值,其中s=sin(x),c=cos(x)。該函數用於“同時需要計算 sin 值和 cos 值的情況”,比分別運算要快很多! |
sinh(x) | 計算雙曲正弦(hyperbolic sine)值。 |
smoothstep(min, max, x) | 值 x 位於 min、max 區間中。如果 x=min,返回 0;如果 x=max,返回 1;如果 x 在兩者之間,按照下列公式返回數據: x−min x−min −2*( ![]() ![]() max−min max−min |
step(a, x) | 如果 x<a,返回 0;否則,返回 1。 |
sqrt(x) | 求 x 的平方根, x ,x 必須大於 0。 |
tan(x) | 輸入參數為弧度,計算正切值 |
tanh(x) | 計算雙曲正切值 |
transpose(M) | M 為矩陣,計算其轉置矩陣 |
幾何函數(Geometric Functions)
Cg 語言標准函數庫中有
3 個幾何函數會經常被使用到,分別是:normalize 函數,對向量進行歸一化;reflect 函數,計算反射光方向向量;refract 函數,計算折射光方向向量。注意:
1 着色程序中的向量 好進行歸一化之后再使用,否則會出現難以預料的錯誤;
2 reflect 函數和 refract 函數都存在以“入射光方向向量”作為輸入參數,注意這兩個函數中使用的入射光方向向量,是從外指向幾何頂點的;平時我們在着色程序中或者在課本上都是將入射光方向向量作為從頂點出發。
函數 | 功能 |
distance( pt1, pt2) | 兩點之間的歐幾里德距離(Euclidean distance) |
faceforward(N,I,Ng) | 如果Ng I• < 0 ,返回 N;否則返回-N。 |
length(v) | 返回一個向量的模,即 sqrt(dot(v,v)) |
normalize( v) | 歸一化向量 |
reflect(I, N) | 根據入射光方向向量 I,和頂點法向量 N,計算反射光方向向量。其中 I 和 N 必須被歸一化,需要非常注意的是,這個 I 是指向頂點的;函數只對三元向量有效 |
refract(I,N,eta) | 計算折射向量,I 為入射光線,N 為法向量,eta 為折射系數;其中 I 和 N 必須被歸一化,如果 I 和 N 之間的夾角太大,則返回(0,0,0),也就是沒有折射光線;I 是指向頂點的;函數只對三元向量有效 |
紋理映射函數(Texture Map Functions)
函數 |
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) 查詢投影立方體紋理 |
s 象征一元、二元、三元紋理坐標;z 代表使用“深度比較(depth comparison)” 的值;q 表示一個透視值(perspective value,其實就是透視投影后所得到的齊次坐標的 后一位),這個值被用來除以紋理坐標(S),得到新的紋理坐標(已歸一化到 0 和 1 之間)然后用於紋理查詢。
紋理函數非常多,總的來說,按照紋理維數進行分類,即:1D 紋理函數, 2D 紋理函數,3D 紋理函數,已經立方體紋理。需要注意,TexREC 函數查詢的紋理實際上也是二維紋理。 3D 紋理,另一個比較學術化的名稱是“體紋理(Volume Texture)”,體紋理通常用於體繪制,體紋理用於記錄空間中的體細節數據。
還有一類較為特殊的紋理查詢函數以 proj 結尾,主要是針對投影紋理進行查詢。所謂投影紋理是指:將紋理當做一張幻燈片投影到場景中,使用投影紋理技術需要計算投影紋理坐標,然后使用投影紋理坐標進行查詢。使用投影紋理坐標進行查詢的函數就是投影紋理查詢函數。 本質來說,投影紋理查詢函數和普通的紋理查詢函數沒有什么不同,唯一的區別在於“投影紋理查詢函數使用計算得到的投影紋理坐標,並在使用之前會將該投影紋理坐標除以透視值”。舉例而言,計算得到的投影紋理坐標為 float4 uvproj,使用二維投影紋理查詢函數:
tex2Dproj(texture,uvproj); 等價於按如下方法使用普通二維紋理查詢函數:
float4 uvproj = uvproj/uvproj.q; tex2D(texture,uvproj);
偏導函數(Derivative Functions)
函數 | 功能 |
ddx(a) | 參數 a 對應一個像素位置,返回該像素值在 X 軸上的偏導數 |
ddy(a) | 參數 a 對應一個像素位置,返回該像素值在 X 軸上的偏導數 |
- shader函數 ddx 和 ddy 用於求取相鄰像素間某屬性的差值;
- 函數 ddx 和 ddy 的輸入參數通常是紋理坐標;
- 函數 ddx 和 ddy 返回相鄰像素鍵的屬性差值;