Unity Shader 之 Shader 常用函數(CG 標準函數庫)整理 ,數學函數、幾何函數、紋理映射函數、偏導函數
目錄
Unity Shader 之 Shader 常用函數(CG 標準函數庫)整理 ,數學函數、幾何函數、紋理映射函數、偏導函數、調試函數
3、紋理映射函數(Texture Map Functions)
一、簡單介紹
Shader Language的發展方向是設計出在便攜性方面可以和C++、Java等相比的高級語言,“賦予程序員靈活而方便的編程方式”,並“儘可能的控制渲染過程”同時“利用圖形硬件的並行性,提高算法效率”。
Shader 常用函數(CG 標準函數庫)整理 ,包括數學函數、幾何函數、紋理映射函數、偏導函數、調試函數。
二、Shader 常用函數(CG 標準函數庫)
和 C 的標準函數庫類似,Cg 提供了一系列內建的標準函數。這些函數用於執行數學上的通用計算或通用算法(紋理映射等),例如,需要求取入射光線的反射光線方向向量可以使用標準函數庫中的 reflect 函數,求取折射光線方向向量可以使用 refract 函數,做矩陣乘法運算時可以使用 mul 函數。
有些函數直接和 GPU 指令相對應,所以執行效率非常高。絕大部分標準函數都被重載過,用於支持不同長度的數組和向量作爲輸入參數。
Cg 標準函數會隨着未來 GPU 硬件的發展而不斷優化,所以基於標準函數庫寫的程序是可以用在以後的 GPU 硬件上的。 Cg 標準函數庫主要分爲五個部分:
-
數學函數(Mathematical Functions);
-
幾何函數(Geometric Functions);
-
紋理映射函數(Texture Map Functions)
-
偏導數函數(Derivative Functions);
-
調試函數(Debugging Function)
1、數學函數
數學函數用於執行數學上常用計算,包括:三角函數、冪函數、園函數、向量和矩陣的操作函數。這些函數都被重載,以支持標量數據和不同長度的向量作爲輸入參數。
函數 功能
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) |
|
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) |
|
sign(x) |
|
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) |
|
step(a, x) |
如果 x<a,返回 0;否則,返回 1。 |
sqrt(x) |
求 x 的平方根, x ,x 必須大於 0。 |
tan(x) |
輸入參數爲弧度,計算正切值 |
tanh(x) |
計算雙曲正切值 |
transpose(M) |
M 爲矩陣,計算其轉置矩陣 |
2、幾何函數(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 是指向頂點的;函數只對三元向量有效 |
3、紋理映射函數(Texture Map Functions)
函數 |
|
|
|
|
|
|
|
|
|
|
|
|
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) |
|
|
|
|
|
|
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);
4、偏導函數(Derivative Functions)
-
shader函數 ddx 和 ddy 用於求取相鄰像素間某屬性的差值;
-
函數 ddx 和 ddy 的輸入參數通常是紋理座標;
-
函數 ddx 和 ddy 返回相鄰像素鍵的屬性差值;
函數 |
功能 |
ddx(a) |
參數 a 對應一個像素位置,返回該像素值在 X 軸上的偏導數 |
ddy(a) |
參數 a 對應一個像素位置,返回該像素值在 X 軸上的偏導數 |