#version 330 core

in vec2 vTexCoord;

uniform float uTime;
uniform vec2 uResolution;
uniform vec2 uMouse;

uniform sampler2D uTextureUnit;
uniform vec4 uColor;
uniform float uDepth;

out vec4 fragColor;
out float gl_FragDepth;

#ifdef GL_ES
precision mediump float;
#endif

// shadertoy emulation
#define iTime uTime
#define iResolution uResolution
#define iMouse uMouse

float tanh(float x) {
    float ex = exp(2.0 * x);
    return ((ex - 1.) / (ex + 1.));
}

vec3 tanh(vec3 x) {
    vec3 ex = exp(2.0 * x);
    return ((ex - 1.) / (ex + 1.));
}

// --------[ Original ShaderToy begins here ]---------- //

#define rot(angle) mat2(cos(angle),sin(angle),-sin(angle),cos(angle))
#define PI 3.14159265

float SmoothMin(float d1,float d2,float k)
{
    float e1=exp(-k*d1);
    float e2=exp(-k*d2);
    return -log(e1+e2)/k;
}

float Cylinder(vec2 p,float size)
{
    return length(p)-size;
}

float Torus(vec3 p,vec2 size)
{
    return length(vec2(length(p.xy)-size.x,p.z))-size.y;
}

float Box(vec3 p,vec3 size)
{
    return length(max(abs(p)-size,0.0));
}

float map(vec3 p)
{

    p.xy*=rot(iTime);
    p.xz*=rot(iTime);
    p.yz*=rot(iTime);
    
    float radius=1.0;
    
    vec3 pos=p;
   
    
    for(int i=0;i<3;i++)
    {
        pos=abs(pos)-radius;
        if(pos.x<pos.y)pos.xy=pos.yx;
        if(pos.x<pos.z)pos.xz=pos.zx;
        if(pos.y<pos.z)pos.yz=pos.zy;
        pos.xy-=.25;
        
        pos.xy*=rot(PI/3.);
        pos.xz*=rot(PI/3.);
        pos.y-=0.5;
        
        //pos.yz*=rot(PI/3.);
    }
    
    float h=2.0;
    pos.x-=clamp(pos.x,-h,h);
    
    float d4=Torus(pos,vec2(0.5,0.15));
    float d5=Box(pos,vec3(0.1,0.1,4.0));
    return d4;
    
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 uv = (fragCoord.xy*2.0-iResolution.xy)/min(iResolution.x,iResolution.y);
    vec3 ro=vec3(0.0,0.0,10.0);
    vec3 rd=vec3(uv.xy,-1.0);
    
    float d,t=0.0;
    for(int i=0;i<64;i++)
    {
        d=map(ro+rd*t);
        if(d<0.001)
        {
            break;
        }
        t+=d;
    }
    
    
    vec3 col=vec3(exp(-0.1*t));
    fragColor = vec4(col,1.0);
}

// --------[ Original ShaderToy ends here ]---------- //

void main(void)
{
    mainImage(fragColor, vec2(vTexCoord.x, 1.0 - vTexCoord.y) * uResolution);

    fragColor *= uColor;
    gl_FragDepth = uDepth;
}
