Godot - Shader - 制作薄暮 Fog

视频教学链接:

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);
}

解释

  • 伪随机数 fract(sin(dot(uv, vec2(56,78))*1000.0)*1000.0); 其中uv和[56,78]点的关系就理解成他们之间的距离就好(非精准)
    frac(sin(x*1000.)*1000.0)的图像

    2d

    3d

  • noise噪点作用是让当前点在其周围四个顶点实现二维连续

    • mix(a,b,f.x) 只能在x方向上连续
    • (c-a)*f.y*(1.-f.x)(d-b)*f.x*f.y都只能y方向上连续
    • 整体这样看更直观
      (a+(c-a)*f.y)*(1.-f.x)+(b+(d-b)*f.y)*f.x
      这个图像的左上角趋近于a,右上角趋近于b, 左下角趋近于c,右下角趋近于d, 记住这个公式就比较明确
    • 混合在一起,向四个边缘方向连续


      mix(a,b,f.x)
(c-a)*f.y*(1.-f.x)
(d-b)*f.x*f.y
合并

Grapher公式: https://pan.baidu.com/s/1wX1VREvjqMipF6dJ0VSf0A 提取码: h28g

  • fbm函数用于将多次不同的雾层叠加在一起,多次循环后返回值逼近1,不需要再进行范围处理
  • 通关不同方向上的运动,让雾运动起来
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。