在工作中顷啼,因為編寫與瀏覽shader的需要逐虚,經(jīng)常會遇到各種平時不是特別熟悉的關(guān)鍵字刑赶,從而需要一而再的進行查詢克伊,這里嘗試將一些常用的關(guān)鍵字釋義及用法做一個歸納總結(jié)酥郭,方便后面查詢使用。
1. 函數(shù)
函數(shù)是使用頻率最高的“關(guān)鍵字”了愿吹,但是由于名字過于簡化不从,且不是每個函數(shù)都是經(jīng)常使用的,因此還是會經(jīng)常遇到函數(shù)名不知道具體的內(nèi)部實現(xiàn)的情況犁跪,因此這里首先對工作中碰到的一些shader函數(shù)進行查詢
1.1 smoothstep
這是一個三次插值的平滑函數(shù)椿息,使用格式為smoothstep(a, b, x)歹袁,其函數(shù)實現(xiàn)大致如下:
float smoothstep(float a, float b, float x)
{
float t = saturate((x - a)/(b - a));
return t*t*(3.0 - (2.0*t));
}
當a < b時,此函數(shù)時一個遞增函數(shù)寝优,當a > b時条舔,此函數(shù)時一個遞減函數(shù)。比如取a,b = 0,1時以及當取a,b = 1, 0時乏矾,對應(yīng)的函數(shù)曲線分別為:
函數(shù)中的a,b實際上是對應(yīng)于自變量x的取值范圍上下限孟抗,當超出上下限時,函數(shù)取值就被clamp到0/1钻心,這一點在上述曲線中沒有體現(xiàn)出來凄硼,需要注意。
1.2 lerp/mix
這是一個線性插值函數(shù)捷沸,在HLSL中摊沉,此函數(shù)名為lerp,在GLSL中亿胸,此函數(shù)名為mix坯钦,雖然名字不同,但是其用法與函數(shù)曲線是完全相同的侈玄,這個函數(shù)的使用格式為lerp(a, b, x)婉刀,對應(yīng)的函數(shù)實現(xiàn)為:
float lerp(float a, float b, float x)
{
float t = saturate(x);
return a + (b - a) * t;
}
這是一個線性函數(shù),當b > a時序仙,函數(shù)遞增突颊,當a > b時,函數(shù)遞減潘悼,對應(yīng)的兩個示例函數(shù)的曲線如下面兩圖所示:
同樣律秃,a,b對應(yīng)了函數(shù)數(shù)值的上下限,當自變量x超出0,1之外治唤,對應(yīng)的函數(shù)取值為上下限的clamp棒动,不過曲線中沒有顯示出來。
1.3 step
step函數(shù)是階躍函數(shù)宾添,其實現(xiàn)邏輯給出如下:
float step(float a, float x)
{
return x > a ? 1.0 : 0.0;
}
函數(shù)(step(0.5, x))曲線如下圖所示:
1.4 floor/ceil
floor函數(shù)是向下取整函數(shù)船惨,與之相對的是向上取整函數(shù)ceil,這兩個函數(shù)的曲線示意圖如下所示:
1.5 frac
frac函數(shù)是取小數(shù)函數(shù)缕陕,返回的是一個[0, 1)之間的小數(shù)粱锐,對于大于零的浮點數(shù),直接取小數(shù)部分即可扛邑,而對于小于零的浮點數(shù)怜浅,則是取1-frac(abs(x)):
float frac(float x)
{
return x - floor(x);
}
其對應(yīng)的函數(shù)曲線如下圖所示:
1.6 fmod
fmod(x, d)函數(shù)是取余函數(shù)(需要保證d不等于0济瓢,否則會引發(fā)異常)盹憎,返回值的符號與x保持一致粒竖,且其絕對值小于被除數(shù)d的絕對值忙芒,其實現(xiàn)函數(shù)可以用如下的代碼來表示:
float fmod(float x, fload d)
{
float remains = frac(x / d);
return remains * d - d * step(-x * d);
}
對應(yīng)的函數(shù)曲線如下圖所示:
從圖中可以看出哟忍,fmod函數(shù)的結(jié)果與被除數(shù)的符號是沒有關(guān)系的宛篇。
1.7 sign
sign函數(shù)是符號函數(shù)皆愉,當自變量小于零時返回-1证杭,當自變量大于零時返回1沪袭,當自變量等于0時湾宙,返回0,其實現(xiàn)可以用如下代碼來示意:
float sign(x)
{
if(x < 0.0)
return -1.0;
else if(x > 0.0)
return 1.0;
else
return 0.0;
}
函數(shù)曲線如下圖所示(為了清晰的顯示自變量為0時的結(jié)果冈绊,用散點圖表示):