← 毎日のシェーダー~/adventure-log/shaders/2026-10-08

秋陽のステンドグラス

秋陽のステンドグラス澄んだ秋の日差しに、琥珀や朱、オリーブのガラスがそっと動き、ところどころに青空がのぞく。 · 晴れ時々くもり 16–24°C
ソースanimated Voronoi stained-glass cells with exact border distance, bevel shading, per-cell highlights and drifting sun glow
2026-10-08.frag
precision mediump float;
uniform vec2 u_resolution;
uniform float u_time;

vec2 hash2(vec2 p){
  p = vec2(dot(p, vec2(127.1, 311.7)), dot(p, vec2(269.5, 183.3)));
  return fract(sin(p) * 43758.5453);
}

float hash1(vec2 p){
  return fract(sin(dot(p, vec2(41.3, 289.1))) * 43758.5453);
}

vec3 pal(float h){
  vec3 c = mix(vec3(0.96, 0.64, 0.20), vec3(0.88, 0.34, 0.20), smoothstep(0.15, 0.35, h));
  c = mix(c, vec3(0.98, 0.80, 0.40), smoothstep(0.35, 0.50, h));
  c = mix(c, vec3(0.62, 0.68, 0.30), smoothstep(0.55, 0.70, h));
  c = mix(c, vec3(0.40, 0.66, 0.84), smoothstep(0.82, 0.90, h));
  return c;
}

vec2 cellOff(vec2 id, float t){
  vec2 o = hash2(id);
  return 0.5 + 0.36 * sin(t * 0.45 + 6.2831 * o);
}

void main(){
  vec2 p = (gl_FragCoord.xy - 0.5 * u_resolution) / u_resolution.y;
  float t = u_time;
  vec2 q = p * 4.0 + vec2(t * 0.03, 0.01 * sin(t * 0.2));
  vec2 ip = floor(q);
  vec2 fp = fract(q);

  float d1 = 8.0;
  vec2 r1 = vec2(0.0);
  vec2 id1 = vec2(0.0);
  for (int i = 0; i < 9; i++){
    vec2 g = vec2(mod(float(i), 3.0) - 1.0, floor(float(i) / 3.0) - 1.0);
    vec2 r = g + cellOff(ip + g, t) - fp;
    float d = dot(r, r);
    if (d < d1){ d1 = d; r1 = r; id1 = ip + g; }
  }

  float md = 8.0;
  for (int i = 0; i < 9; i++){
    vec2 g = vec2(mod(float(i), 3.0) - 1.0, floor(float(i) / 3.0) - 1.0);
    vec2 r = g + cellOff(ip + g, t) - fp;
    vec2 dr = r - r1;
    if (dot(dr, dr) > 0.0001){
      md = min(md, dot(0.5 * (r1 + r), normalize(dr)));
    }
  }

  float h = hash1(id1);
  float hs = fract(h + 0.04 * sin(t * 0.15 + h * 6.2831));
  vec3 glass = pal(hs);

  float bevel = 0.78 + 0.27 * smoothstep(0.0, 0.35, md);
  float twinkle = 0.88 + 0.12 * sin(t * 0.7 + h * 20.0);

  vec2 sp = vec2(-0.45 + 0.12 * sin(t * 0.08), 0.32 + 0.05 * cos(t * 0.11));
  float glow = exp(-length(p - sp) * 1.7);

  vec2 local = -r1 - vec2(-0.14, 0.14);
  float spec = smoothstep(0.24, 0.0, length(local)) * 0.18;

  vec3 col = glass * bevel * twinkle * (0.68 + 0.55 * glow);
  col += vec3(1.0, 0.92, 0.75) * (spec + glow * 0.10);

  float lead = smoothstep(0.035, 0.085, md);
  vec3 leadCol = vec3(0.20, 0.13, 0.10) + glow * vec3(0.10, 0.07, 0.04);
  col = mix(leadCol, col, lead);

  vec2 uv = gl_FragCoord.xy / u_resolution;
  float vig = 0.82 + 0.18 * smoothstep(0.9, 0.2, length(uv - 0.5));
  col *= vig;

  col = min(col, vec3(0.95));
  gl_FragColor = vec4(col, 1.0);
}