float Figure1(in vec2 p, in float r) {
    const vec3 k = vec3(-0.9238795325, 0.3826834323, 0.4142135623 );
    p = abs(p);
    p -= 2.0*min(dot(vec2( k.x,k.y),p),0.0)*vec2( k.x,k.y);
    p -= 2.0*min(dot(vec2(-k.x,k.y),p),0.0)*vec2(-k.x,k.y);
    p -= vec2(clamp(p.x, -k.z*r, k.z*r), r);
    return length(p)*sign(p.y);
}

float Figure2(in vec2 p, in float r) {
    return length(p) - r;
}

vec3 palette(float t) {
    vec3 a = vec3(0.14, 0.73, 0.49);
    vec3 b = vec3(0.08, 0.37, 0.46);
    vec3 c = vec3(1.2, 0.5, 0.16);
    vec3 d = vec3(5.25, 5.5, 5.9);
    
    return a + b * sin(10.28318 * (c * t + d));
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    // Normalized pixel coordinates (from 0 to 1)
    vec2 uv = (fragCoord * 2.0 - iResolution.xy) / iResolution.y;
    vec2 uv0 = uv;
    vec3 finalColor = vec3(0.0);
    
    for(float i = 0.0; i < 2.0; i++) {
        // Fractalize the figure
        uv = fract(uv * 2.0) - 0.5;

        // Sine Distance
        float fig1 = Figure1(uv, 0.5);
        float fig2 = Figure2(uv, 1.0) * exp(-length(uv0));

        // Color Palette
        vec3 color = palette(length(uv0) + i*0.25 + iTime*0.5);

        fig1 = sin(fig1 * 10.0 + iTime*2.0) / 10.0;
        fig1 = abs(fig1);
        fig1 = pow(0.025 / fig1, 1.25);
        
        fig2 = sin(fig2 * 8.0 + iTime) / 8.0;
        fig2 = abs(fig2);
        fig2 = pow(0.015 / fig2, 1.5);

        finalColor += color * (fig1 + fig2);
    }

    // Output to screen
    fragColor = vec4(finalColor, 1.0);
}
