float secondsOfDay(float seconds) { return seconds - floor(seconds / 86400.0) * 86400.0; } float lineMask(float2 p, float angle, float innerRadius, float outerRadius, float width) { float2 direction = float2(sin(angle), cos(angle)); float along = dot(p, direction); float across = length(p - direction * along); float body = smoothstep(width, width * 0.35, across); float start = smoothstep(innerRadius - width, innerRadius + width, along); float end = 1.0 - smoothstep(outerRadius - width, outerRadius + width, along); return body * start * end; } float ringMask(float radius, float target, float width) { return smoothstep(width, 0.0, abs(radius - target)); } float tickMask(float2 p, int tick) { float angle = (float(tick) / 60.0) * 6.28318530718; float2 direction = float2(sin(angle), cos(angle)); float along = dot(p, direction); float across = length(p - direction * along); float major = (tick % 5) == 0 ? 1.0 : 0.0; float inner = lerp(0.82, 0.76, major); float outer = 0.9; float width = lerp(0.006, 0.011, major); float body = smoothstep(width, width * 0.35, across); float start = smoothstep(inner, inner + 0.025, along); float end = 1.0 - smoothstep(outer - 0.025, outer, along); return body * start * end; } float4 shadeVideo(ShaderContext context) { float2 aspect = float2(context.outputResolution.x / max(context.outputResolution.y, 1.0), 1.0); float2 p = (context.uv * 2.0 - 1.0) * aspect / max(clockScale, 0.01); float radius = length(p); float seconds = showLocalTime ? secondsOfDay(context.utcTimeSeconds + context.utcOffsetSeconds) : secondsOfDay(context.utcTimeSeconds); float hour = floor(seconds / 3600.0); float minute = floor((seconds - hour * 3600.0) / 60.0); float second = seconds - hour * 3600.0 - minute * 60.0; float secondAngle = second / 60.0 * 6.28318530718; float minuteAngle = (minute + second / 60.0) / 60.0 * 6.28318530718; float hour12 = hour - floor(hour / 12.0) * 12.0; float hourAngle = (hour12 + minute / 60.0) / 12.0 * 6.28318530718; float4 color = context.sourceColor; float face = smoothstep(1.0, 0.97, radius); color = lerp(color, faceColor, face * faceColor.a); float ring = ringMask(radius, 0.92, 0.01); float ticks = 0.0; for (int i = 0; i < 60; ++i) ticks = max(ticks, tickMask(p, i)); float hourHand = lineMask(p, hourAngle, -0.05, 0.48, 0.028); float minuteHand = lineMask(p, minuteAngle, -0.07, 0.72, 0.018); float secondHand = lineMask(p, secondAngle, -0.12, 0.8, 0.009); float hub = smoothstep(0.07, 0.0, radius); float whiteDetail = max(max(ring, ticks), max(hourHand, minuteHand)); color.rgb = lerp(color.rgb, float3(0.92, 0.96, 1.0), whiteDetail); color.rgb = lerp(color.rgb, accentColor.rgb, max(secondHand, hub) * accentColor.a); return color; }