中級Shader教程01 基礎函數

以下實例的圖片依次對上面圖片中應笛卡爾座標行列。

shader中函數的基本理解

1.smoothstep 獲取較爲平滑的過渡效果length(uv) 降維效果
2.length(uv)將2D的轉換爲1D
3.atan(u,v) 獲取角度 配合length 可以得到極座標
4.pow(f,n) 將曲線變化變得平滑或尖銳
5.sin cos 周期函數,用於實現週期的效果(如來回移動,循環的移動等)
6.hash 獲取標誌ID,常用於基於空間劃分的效果的實現
7.noise 同時具有隨機性和連續性的函數
8.fbm 在基本函數的基礎上,不斷的疊加高頻信息,豐富細節

假設uv 是 (-0.5,-0.5) 到(.5,0.5)

1.smoothstep eg:繪製smoothstep曲線
f(x) = x*x*(3.0-2.0*x)
具有淡入淡出效果

float3 DrawSmoothstep(float2 uv){
    uv+=0.5;
    float val = smoothstep(0.0,1.0,uv.x);
    val = step(abs(val-uv.y),0.01); 
    return float3(val,val,val);
}

2.length eg:繪製圓點

float3 DrawCircle(float2 uv){
    float val = (1.0-length(uv)*2);
    val = smoothstep(0.0,0.1,val);
    return float3(val,val,val);
}

3.atan eg:繪製花環

float3 DrawFlower(float2 uv){
    float deg = atan2(uv.y,uv.x) + _Time.y * -0.1;
    float len = length(uv)*3.0;
    float offs = abs(sin(deg*3.))*0.35;
    return smoothstep(1.+offs,1.+offs-0.05,len);
}

4.5.pow eg:讓圓變得更虛or實

float3 DrawWeakCircle(float2 uv){
    float val = clamp((1.0-length(uv)*2),0.,1.);
    val = pow(val,2.0);
    return float3(val,val,val);
}
float3 DrawStrongCircle(float2 uv){
    float val = clamp((1.0-length(uv)*2),0.,1.);
    val = pow(val,0.5);
    return float3(val,val,val);
}

6.sin eg:跳動的小球
sin函數給2D小球y軸上的移動

float3 DrawBounceBall(float2 uv){
    uv*=4.;//uv 空間[-2~2]
    uv.y+=sin(ftime*PI);
    float val = clamp((1.0-length(uv)),0.,1.);
    val = smoothstep(0.,0.05,val);
    return float3(val,val,val);
}

7.hash eg:不同顏色的格子
本教程中使用的Hash庫來自Dave_Hoskin
具體實現見Hash.cginc
這裏給出另外一種使用三角函數實現的Hash:

fixed2 Rand22(fixed2 co){
    fixed x = frac(sin(dot(co.xy ,fixed2(122.9898,783.233))) * 43758.5453);
    fixed y = frac(sin(dot(co.xy ,fixed2(457.6537,537.2793))) * 37573.5913);
    return fixed2(x,y);
}

fract(sin(x*bigVal1)*bigVal2)產生的數比較隨機的原因是:
sin(x*bigVal1) 會將x值的變化波動被放大,且隨機,設這個值的變化爲detX,則 frac(detX*bigVal2) 會讓本來的小的波動再次放大,然後fract會讓整體的數的變化受影響的因素變多,所以得到的了一個較爲隨機的值.
更多的說明請參考the book of shader

float3 DrawRandomColor(float2 uv){
    uv+=0.5;
    uv*=4.;
    return Hash32(floor(uv));
}

8.noise eg:Perlin Noise展示
本教程中使用的Noise庫來自ShaderToy多位作者,具體實現見Noise.cginc

本教程不再覆蓋noise等基礎函數的實,原理請參考candycat這篇blog
更多實例可以參考the book of shader
帶有法線的noise函數的推導請看iqMilo

float3 DrawRandomColor(float2 uv){
    uv+=0.5;
    uv*=4.;
    return Hash32(floor(uv));
}

9.fbm eg:PerlinNoise FBM展示
FBM更多實例請參考the book of shader

float3 DrawRandomColor(float2 uv){
    uv+=0.5;
    uv*=4.;
    return Hash32(floor(uv));
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章