← 每日 shader~/adventure-log/shaders/2026-09-26

倦雨池面

倦雨池面整日的雨在灰绿水面上画着缓慢的圆,几片锈色落叶随波停泊。 · 雨 18–22°C
源码cellular rain-ripple normals over warped fbm reflections
2026-09-26.frag
precision mediump float;
uniform vec2 u_resolution;
uniform float u_time;

float h21(vec2 p){
  p = fract(p * vec2(123.34, 456.21));
  p += dot(p, p + 45.32);
  return fract(p.x * p.y);
}

float noise(vec2 p){
  vec2 i = floor(p);
  vec2 f = fract(p);
  f = f * f * (3.0 - 2.0 * f);
  return mix(mix(h21(i), h21(i + vec2(1.0, 0.0)), f.x),
             mix(h21(i + vec2(0.0, 1.0)), h21(i + vec2(1.0, 1.0)), f.x), f.y);
}

float fbm(vec2 p){
  float v = 0.0;
  float a = 0.5;
  for (int i = 0; i < 4; i++){
    v += a * noise(p);
    p = p * 2.03 + vec2(1.7, 9.2);
    a *= 0.5;
  }
  return v;
}

vec2 ripples(vec2 p, float t){
  vec2 id = floor(p);
  vec2 f = fract(p);
  vec2 acc = vec2(0.0);
  for (int j = 0; j < 3; j++){
    for (int i = 0; i < 3; i++){
      vec2 o = vec2(float(i) - 1.0, float(j) - 1.0);
      vec2 c = id + o;
      float h = h21(c);
      float per = 2.6 + h * 2.2;
      float age = mod(t + h * 17.0, per);
      vec2 ctr = o + 0.2 + 0.6 * vec2(h, h21(c + 3.7));
      vec2 q = f - ctr;
      float d = length(q) + 0.0001;
      float x = d - age * 0.42;
      float env = exp(-x * x * 50.0) * exp(-age * 1.3) * smoothstep(0.0, 0.3, age);
      acc += q / d * cos(x * 26.0) * env;
    }
  }
  return acc;
}

void main(){
  vec2 uv = (gl_FragCoord.xy - 0.5 * u_resolution) / u_resolution.y;
  float t = u_time;
  vec2 g = ripples(uv * 4.0, t) + ripples(uv * 6.5 + vec2(3.1, 7.4), t * 0.9 + 5.0) * 0.6;
  vec2 w = uv + g * 0.012;

  float c = fbm(w * vec2(1.5, 3.0) + vec2(t * 0.015, t * 0.01));
  vec3 deep = vec3(0.20, 0.26, 0.29);
  vec3 pale = vec3(0.50, 0.55, 0.56);
  float k = smoothstep(0.25, 0.8, c) * 0.75 + (uv.y + 0.5) * 0.25;
  vec3 col = mix(deep, pale, clamp(k, 0.0, 1.0));
  col = mix(col, vec3(0.30, 0.34, 0.31), 0.25 * fbm(w * 5.0 - t * 0.02));

  for (int i = 0; i < 3; i++){
    float fi = float(i);
    vec2 lp = vec2(sin(fi * 2.3 + t * 0.02) * 0.48, cos(fi * 1.7 + t * 0.017) * 0.3);
    vec2 q = w - lp;
    float a = fi * 1.9 + sin(t * 0.05 + fi) * 0.3;
    q = mat2(cos(a), -sin(a), sin(a), cos(a)) * q;
    float e = length(q * vec2(1.0, 2.1));
    float m = 1.0 - smoothstep(0.06, 0.09, e);
    vec3 leaf = mix(vec3(0.48, 0.30, 0.18), vec3(0.62, 0.44, 0.24), fbm(q * 12.0 + fi));
    col = mix(col, leaf, m * 0.8);
    col -= (1.0 - smoothstep(0.08, 0.14, e)) * (1.0 - m) * 0.03;
  }

  float s = dot(g, normalize(vec2(-0.4, 0.8)));
  col += s * 0.07;
  col += vec3(0.85, 0.9, 0.95) * pow(max(s, 0.0), 2.0) * 0.05;

  col *= 1.0 - 0.35 * dot(uv, uv);
  col = clamp(col, 0.05, 0.9);
  gl_FragColor = vec4(col, 1.0);
}