視頻教學鏈接:
https://www.bilibili.com/video/av55565296
代碼:
https://github.com/zszen/godot_lesson/commit/6a80fad6051a678c26f6673e035d85373a32282c
shader_type canvas_item;
uniform vec3 color = vec3(.35,.48,.7);
uniform int OCTAVES = 4;
float rand(vec2 uv){
return fract(sin(dot(uv, vec2(56,78))*1000.0)*1000.0);
}
float noise(vec2 uv){
vec2 i = floor(uv);
vec2 f = fract(uv);
float a = rand(i);
float b = rand(i+vec2(1.,0.));
float c = rand(i+vec2(.0,1.));
float d = rand(i+vec2(1.,1.));
vec2 cubic = f*f*(3.-2.*f);
// return mix(a,b,f.x)+(c-a)*f.y*(1.-f.x)+(d-b)*f.x*f.y;
return mix(a,b,cubic.x)+(c-a)*cubic.y*(1.-cubic.x)+(d-b)*cubic.x*cubic.y;
}
float fbm(vec2 uv){
float val = 0.;
float scale = .5;
for(int i=0;i<OCTAVES;i++){
val+=noise(uv)*scale;
uv*=2.;
scale*=.5;
}
return val;
}
void fragment(){
vec2 uv = UV*20.;
uv.y*=2.;
vec2 motion = vec2(fbm(uv+vec2(TIME*-.5, sin(TIME*.3+fract(uv.x*uv.y)))));
float final = fbm(uv+motion);
COLOR = vec4(color, rand(uv));
// COLOR = vec4(color, final*.35);
}
解釋
-
偽隨機數(shù)
fract(sin(dot(uv, vec2(56,78))*1000.0)*1000.0);
其中uv和[56,78]點的關(guān)系就理解成他們之間的距離就好(非精準)
frac(sin(x*1000.)*1000.0)
的圖像
-
noise噪點作用是讓當前點在其周圍四個頂點實現(xiàn)二維連續(xù)
-
mix(a,b,f.x)
只能在x方向上連續(xù) -
(c-a)*f.y*(1.-f.x)
和(d-b)*f.x*f.y
都只能y方向上連續(xù) - 整體這樣看更直觀
(a+(c-a)*f.y)*(1.-f.x)+(b+(d-b)*f.y)*f.x
這個圖像的左上角趨近于a徐块,右上角趨近于b, 左下角趨近于c隐绵,右下角趨近于d, 記住這個公式就比較明確 -
混合在一起脖旱,向四個邊緣方向連續(xù)
-
Grapher公式: https://pan.baidu.com/s/1wX1VREvjqMipF6dJ0VSf0A 提取碼: h28g
- fbm函數(shù)用于將多次不同的霧層疊加在一起届搁,多次循環(huán)后返回值逼近1帕识,不需要再進行范圍處理
- 通關(guān)不同方向上的運動搔课,讓霧運動起來