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

两片色域之间

两片色域之间灰蓝与赭黄两片湿润的色域之间,一线微光缓缓呼吸。 · 毛毛雨 18–23°C
源码fbm-feathered Rothko-style color fields with watercolor edge pooling
2026-09-27.frag
precision mediump float;
uniform vec2 u_resolution;
uniform float u_time;

float hash(vec2 p){ return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453); }

float noise(vec2 p){
  vec2 i = floor(p);
  vec2 f = fract(p);
  vec2 u = f * f * (3.0 - 2.0 * f);
  return mix(mix(hash(i), hash(i + vec2(1.0, 0.0)), u.x),
             mix(hash(i + vec2(0.0, 1.0)), hash(i + vec2(1.0, 1.0)), u.x), u.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;
}

float field(vec2 p, vec2 c, vec2 h, float seed){
  vec2 d = abs(p - c) - h;
  float dist = max(d.x, d.y);
  float n = fbm(p * 3.0 + vec2(seed + u_time * 0.02, seed * 0.5)) - 0.5;
  dist += n * 0.08;
  return 1.0 - smoothstep(-0.02, 0.03, dist);
}

void main(){
  vec2 uv = gl_FragCoord.xy / u_resolution;
  float asp = u_resolution.x / u_resolution.y;
  vec2 p = vec2((uv.x - 0.5) * asp, uv.y - 0.5);
  float t = u_time * 0.03;
  float breath = sin(u_time * 0.2) * 0.006;

  vec3 bg = vec3(0.30, 0.34, 0.37);
  vec3 col = bg * (0.92 + 0.12 * fbm(p * 1.5 + vec2(t, 0.0)));

  vec3 topCol = vec3(0.58, 0.63, 0.66);
  vec3 botCol = vec3(0.72, 0.57, 0.39);

  float wx = 0.5 * asp - 0.1;
  float mTop = field(p, vec2(0.0, 0.21), vec2(wx, 0.165 + breath), 3.1);
  float mBot = field(p, vec2(0.0, -0.19), vec2(wx, 0.15 - breath), 7.4);

  float pigT = 0.88 + 0.22 * fbm(p * 2.5 + vec2(t * 1.3, 2.0));
  float pigB = 0.88 + 0.22 * fbm(p * 2.2 + vec2(-t, 5.0));

  float damp = smoothstep(0.60, 0.74, fbm(p * 4.0 + vec2(11.0 + t * 0.5, 3.0)));
  vec3 topPaint = topCol * pigT * (1.0 - 0.10 * damp);
  vec3 botPaint = botCol * pigB * (1.0 - 0.07 * damp);

  col = mix(col, topPaint, mTop * 0.94);
  float eT = mTop * (1.0 - mTop) * 4.0;
  col *= 1.0 - 0.22 * eT;

  col = mix(col, botPaint, mBot * 0.94);
  float eB = mBot * (1.0 - mBot) * 4.0;
  col *= 1.0 - 0.22 * eB;

  float gy = (p.y - 0.018 - (fbm(vec2(p.x * 2.0 + t, 1.0)) - 0.5) * 0.03) / 0.028;
  float g = exp(-gy * gy) * smoothstep(wx + 0.05, wx - 0.25, abs(p.x));
  float pulse = 0.8 + 0.2 * sin(u_time * 0.25);
  col += vec3(0.88, 0.80, 0.62) * g * 0.22 * pulse;

  float grain = noise(uv * vec2(70.0 * asp, 70.0)) - 0.5;
  col += grain * 0.025;

  float vig = smoothstep(1.1, 0.3, length(p * vec2(1.0 / asp, 1.0) * 1.4));
  col *= 0.82 + 0.18 * vig;

  col = clamp(col, 0.04, 0.92);
  gl_FragColor = vec4(col, 1.0);
}