#ifdef GL_ES precision mediump float; #endif #extension GL_OES_standard_derivatives : enable uniform float time; uniform vec2 mouse; uniform vec2 resolution; const float eps = 1e-3; const float pi = 3.1415926535; const vec3 z_up = vec3(0.0, 0.0, 1.0); float rand(vec2 p) { return fract(sin(dot(p, vec2(12.9898, 4.1414))) * 43758.5453); } float rand(float n){return fract(sin(n) * 43758.5453123);} float noise(float p){ float fl = floor(p); float fc = fract(p); return mix(rand(fl), rand(fl + 1.0), fc); } float noise(vec2 n) { const vec2 d = vec2(0.0, 1.0); vec2 b = floor(n), f = smoothstep(vec2(0.0), vec2(1.0), fract(n)); return mix(mix(rand(b), rand(b + d.yx), f.x), mix(rand(b + d.xy), rand(b + d.yy), f.x), f.y); } float mod2(float p, float a) { return p - a * floor(p / a); } vec2 mod2(vec2 p, vec2 a) { return vec2(mod2(p.x, a.x), mod2(p.y, a.y)); } float sdf_circle(vec2 p, vec2 o, float r) { return length(p - o) - r; } float sdf_ring(vec2 p, float r, float lineWidth) { float outer = sdf_circle(p, vec2(0, 0), r + 0.5 * lineWidth); float inner = sdf_circle(p, vec2(0, 0), r - 0.5 * lineWidth); return max(-inner, outer); } float sdf(vec2 p) { return min(sdf_ring(p, 0.75, 0.175), sdf_ring(p, 0.35, 0.175)); } float sake_displacement(vec2 p, vec2 p0) { float dist = length(p - p0); vec2 dir = normalize(p - p0); float k = 5.0; float omega = 20.0; float basewave = 0.5 * sin(k * dist - mod2(omega * time, 2.0 * pi)) + 0.5; float k2 = 22.0; float omega2 = 44.0; float subwave = 0.5 * sin(k2 * dist - mod2(omega2 * time, 2.0 * pi)) + 0.5; float k3 = 45.0; float omega3 = 90.0; float subwave2 = 0.5 * sin(k3 * dist - mod2(omega3 * time, 2.0 * pi)) + 0.5; basewave = 2.0 * pow(basewave, 4.0) + 0.3 * pow(subwave, 2.0) + 0.09 * subwave2; float amp = min(1.0 / sqrt(eps + dist), 1.0); amp *= basewave; float outer_r = 0.82; amp += 100.0 * step(outer_r, length(p)) * (length(p) - outer_r) * (length(p) - outer_r); amp = 1.0 - exp(-amp); amp *= step(length(p0), 0.85); return -0.1 * amp; } vec3 sake_normal(vec2 p, vec2 p0) { float dfx = sake_displacement(p + vec2(1.0, 0.0) * eps, p0) - sake_displacement(p - vec2(1.0, 0.0) * eps, p0); float dfy = sake_displacement(p + vec2(0.0, 1.0) * eps, p0) - sake_displacement(p - vec2(0.0, 1.0) * eps, p0); return normalize(vec3(dfx, dfy, 2.0 * eps)); } void main( void ) { vec2 uv = (2.0 * gl_FragCoord.xy - resolution.xy) / resolution.xy; vec2 pos = (2.0 * gl_FragCoord.xy - resolution.xy) / min(resolution.x, resolution.y); vec2 mouse_pos = 2.0 * (mouse.xy - vec2(0.5));// min(resolution.x, resolution.y); mouse_pos.x *= resolution.x / resolution.y; vec3 light_dir = normalize(vec3(3.0, 2.0, 1.0)); const float max_sake_depth = 0.4; // float sake_depth = max_sake_depth * mouse_pos.y; float sake_depth = max_sake_depth * (0.5 + 0.5 * sin(time)); vec3 normal = sake_normal(pos, mouse_pos); vec3 refract_dir = refract(-z_up, normal, 1.4); vec2 displacement = refract_dir.xy / refract_dir.z * sake_depth; vec2 displaced_pos = pos + displacement; // rings vec3 ring_color = vec3(0.1, 0.1, 0.6); vec3 ring_edge_color = vec3(0.3, 0.6, 0.9); ring_color = mix(ring_edge_color, ring_color, smoothstep(-0.02, 0.02, -sdf(displaced_pos))); vec3 cup_color = vec3(0.98, 0.98, 0.98); vec3 color = mix(ring_color, cup_color, smoothstep(0.0, 0.02, sdf(displaced_pos))); color *= 1.0 - 1.0 * max(0.0, dot(displaced_pos, light_dir.xy)); color *= mix(0.8, 1.0, sake_depth / max_sake_depth); color *= mix(vec3(1.0), vec3(1.0, 1.0, 0.0), 1.0 - exp(-0.1 * sake_depth)); // reflection vec3 ref_dir = reflect(-z_up, normal); vec3 ref_color = 3.0 * vec3(1.0, 1.0, 1.0) * smoothstep(0.8, 0.9, dot(ref_dir, light_dir)); ref_color += 0.5 * noise(2.0 * ref_dir.xy); ref_color *= 1.0 - exp(-2.0 * sake_depth); color += 1.0 * ref_color; // edge color = mix(color, cup_color * 0.6, smoothstep(0.86, 0.87, length(pos))); color = mix(color, vec3(0.1), smoothstep(0.91, 0.92, length(pos))); color *= 1.0 - 0.5 * length(uv) * length(uv); gl_FragColor = vec4(color, 1.0); }