const float RING_STRENGTH = 0.0000; const float RING_BLUR = 0.0030; const float MARKER_STRENGTH = 0.0000; const float MARKER_BLUR = 0.0030; const vec2 VEC_HORZ = vec2(1.0, 0.0); const float PI = 3.1415926535897932384626433832795; /** * Calculate the a double ended smoothstep * * b0 --> b1 --> b2 --> b3 * 0.0 1.0 1.0 0.0 */ float smoothstep2(float b0, float b1, float b2, float b3, float v) { return smoothstep(b0, b1, v) * (1.0 - smoothstep(b2, b3, v)); } /** * Calculate a line (vertical or horizonal) * * @param actual The current value of the fragment * @param expected The expected value of the fragment * @param strength The strength of the line * @param blur Blur value of the line at the borders */ float calcLine(float actual, float expected, float strength, float blur) { return smoothstep2( expected - strength - blur, expected - strength, expected + strength, expected + strength + blur, actual); } /** * Calculate the angle between the two passed vectors */ float calcAngle(vec2 v1, vec2 v2) { v1 = -v1; return -atan( v1.x * v2.y - v1.y * v2.x, v1.x * v2.x + v1.y * v2.y); } /** * Calculate pseudo random value */ float random(float seed) { return fract(sin(dot(vec4(seed), vec4(12.9898, 78.233, 45.164, 53.1324))) * 43758.5453); } /** * Linear animation * * @param v0 Start value * @param v1 End value * @param t Time in range of 0.0 to 1.0 */ float animLinear(float v0, float v1, float t) { return v0 + t * (v1 - v0); } /** * Quadric ease in ease out animation * * @param v0 Start value * @param v1 End value * @param t Time in range of 0.0 to 1.0 */ float animEaseInOutQuadric(float v0, float v1, float t) { float x = t * t * (3.0 - 2.0 * t); return v0 + x * (v1 - v0); } /** * Calculate the position of the marker * * @param t Animation progress in range 0.0 to 1.0 * @param a Angle of the current fragment * @param r Radius of the current fragment * @param zoom Current zoom value */ float calcMarker(float t, float a, float r, float zoom) { float m = calcAngle(uMarker, VEC_HORZ); m = calcLine(a, m, MARKER_STRENGTH / r / zoom, MARKER_BLUR / r / zoom); m *= smoothstep2( t * (uRings[0] - 0.25), t * uRings[0], t * uRings[1], t * (uRings[1] + 0.10), r); m *= 0.75; return m; } /** * Calculate the animation value of a ring * * @param t Animation progress in range 0.0 to 1.0 * @param a Angle of the current fragment * @param overfill Overfilling the ring by the given value */ float calcRingsAnimation(float t, float a, float overfill) { float t_opn_ring = clamp((t - 0.25) / 0.75, 0.0, 1.0); float f = a / PI + 1.0; f = f * 2.0; f = fract(f + 0.5); f = smoothstep2( animLinear(0.4, 0.0 - overfill, t_opn_ring), animLinear(0.5, 0.1 - overfill, t_opn_ring), animLinear(0.5, 0.9 + overfill, t_opn_ring), animLinear(0.6, 1.0 + overfill, t_opn_ring), f); return f; } /** * Calculate the value of an ring * * @param t Animation progress in range 0.0 to 1.0 * @param anim Animation value calculated by 'calcRingsAnimation' * @param ring Value / position of the ring * @param r Radius of the current fragment * @param zoom Current zoom value */ float calcRing(float t, float anim, float ring, float r, float zoom) { return anim * calcLine(r, animEaseInOutQuadric(uSize, ring, t), RING_STRENGTH / zoom, RING_BLUR / zoom); } /** * Calculate the alpha value of the whole rendered primitive * * @param t_opn Progress of the start animation in the range of 0.0 to 1.0 * @param t_cls Progress of the close animation in the range of 0.0 to 1.0 */ float calcAlpha(float t_opn, float t_cls) { float as = (0.5 + 0.5 * step(1.0 - t_opn, random(uProgress))); float ae = (0.5 + 0.5 * step( t_cls, random(uProgress))) * (1.0 - t_cls); return as * ae; }