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

雨中归途的暖灯

雨中归途的暖灯湿亮的路面伸向暖色地平线,琥珀光带随秋雨一路向前流淌。 · 雨 21–27°C
源码perspective-mapped flowing light ribbons with slanted rain streaks
2026-09-25.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);f=f*f*(3.0-2.0*f);
  return mix(mix(hash(i),hash(i+vec2(1.0,0.0)),f.x),mix(hash(i+vec2(0.0,1.0)),hash(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;
}

void main(){
  vec2 p=(gl_FragCoord.xy-0.5*u_resolution)/u_resolution.y;
  float t=u_time;
  const float hz=0.08;
  vec3 col;
  if(p.y>hz){
    vec3 skyLow=vec3(0.95,0.66,0.45);
    vec3 skyTop=vec3(0.27,0.32,0.46);
    col=mix(skyLow,skyTop,smoothstep(hz,0.5,p.y));
    float c=fbm(vec2(p.x*2.5-t*0.03,p.y*4.0+t*0.01));
    float cm=smoothstep(0.42,0.75,c)*smoothstep(hz,hz+0.2,p.y);
    col=mix(col,vec3(0.46,0.45,0.56),cm*0.7);
  }else{
    float d=1.0/(hz-p.y+0.02);
    float xw=p.x*d;
    vec3 road=vec3(0.12,0.12,0.2);
    float n=noise(vec2(p.x*12.0,p.y*3.0-t*0.2));
    vec3 glow=vec3(1.0,0.6,0.4)*exp(-(hz-p.y)*7.0)*(0.35+0.4*n);
    float fog=exp(-d*0.08);
    vec3 g=vec3(0.0);
    for(int i=0;i<5;i++){
      float fi=float(i);
      float x0=(fi-2.0)*1.1+sin(d*0.25+t*0.3+fi*1.7)*0.35;
      float dist=abs(xw-x0);
      float line=smoothstep(0.32,0.05,dist);
      float ph=fract(d*0.12-t*0.35+fi*0.37);
      float dash=smoothstep(0.0,0.3,ph)*smoothstep(1.0,0.6,ph);
      dash=mix(dash,0.5,smoothstep(10.0,25.0,d));
      vec3 lc=mix(vec3(1.0,0.64,0.3),vec3(0.98,0.42,0.42),mod(fi,2.0));
      if(i==2){lc=vec3(1.0,0.85,0.55);}
      g+=lc*line*(0.35+0.65*dash)*fog;
    }
    col=road+glow+g*0.9;
  }
  float mist=exp(-abs(p.y-hz)*18.0);
  col=mix(col,vec3(0.92,0.72,0.6),mist*0.5);
  vec2 r=vec2(p.x+p.y*0.25,p.y);
  const float cols=22.0;
  float cx=floor(r.x*cols);
  float h=hash(vec2(cx,3.1));
  float fy=fract(r.y*2.5+t*(1.6+h*0.8)+h*7.0);
  float streak=smoothstep(0.0,0.12,fy)*smoothstep(0.4,0.12,fy);
  float wx=abs(fract(r.x*cols)-0.5);
  streak*=smoothstep(0.2,0.05,wx)*step(0.45,h);
  col+=vec3(0.75,0.82,0.95)*streak*0.16;
  col*=1.0-0.35*dot(p,p);
  col=clamp(col,0.03,0.95);
  gl_FragColor=vec4(col,1.0);
}