
float sdBox( vec3 p, vec3 b )
{
  vec3 d = abs(p) - b;
  return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));
}

float sdTorus( vec3 p, vec2 t )
{
  vec2 q = vec2(length(p.xz)-t.x,p.y);
  return length(q)-t.y;
}

 mat3 rotationMatrix(vec3 axis, float angle)
{
    axis = normalize(axis);
    float s = sin(angle);
    float c = cos(angle);
    float oc = 1.0 - c;

    return mat3(oc * axis.x * axis.x + c,           oc * axis.x * axis.y - axis.z * s,  oc * axis.z * axis.x + axis.y * s,
                oc * axis.x * axis.y + axis.z * s,  oc * axis.y * axis.y + c,           oc * axis.y * axis.z - axis.x * s,
                oc * axis.z * axis.x - axis.y * s,  oc * axis.y * axis.z + axis.x * s,  oc * axis.z * axis.z + c);
}

float mixV(float a, float b, float d) {
	return (d * a)+(1.0 - d)*b;
}

float map(vec3 p)
{
   float displacement = .55 * sin(iTime + 5.*p.x)*cos(iTime * 1.1 + 5.*p.y)*sin(iTime * 1.2 + 5.*p.z);
   return displacement + sdTorus(p, vec2(7.0, 3.0));
}

void getCamPos(inout vec3 ro, inout vec3 rd)
{
    ro.z = -16.0;
}

vec3 palette( in float t, in vec3 a, in vec3 b, in vec3 c, in vec3 d )
{
    return a + b*cos( 6.28318*(c*t+d) );
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{


    vec2 _p = (iResolution.xy - 2.0 * fragCoord.xy) / iResolution.y;
    vec3 ray = normalize(vec3(_p, 1.0));
    vec3 cam = vec3(0.0, 0.0, 0.0);
    bool hit = false;
    getCamPos(cam, ray);

    mat3 rm = rotationMatrix(vec3(0.66, 1., 0.9), iTime);


    float depth = 0.0, d = 0.0, iter = 0.0;
    vec3 p;

    for( int i = 0; i < 30; i ++)
    {
    	p = depth * ray + cam;
        d = map(rm * p);

        if (d < 0.0001) {
			hit = true;
            break;
        }

		depth += d * 0.75;
		iter++;

    }

    vec3 col = vec3(1.0 - iter / 31.0);
    /*
    const vec3 a = vec3(0.5, 0.5, 0.5);
    const vec3 b = vec3(0.5, 0.5, 0.5);
    const vec3 c = vec3(2., 1., 0.);
    const vec3 da = vec3(0.5, 0.2, 0.25);
*/

    const vec3 a = vec3(0.5, 0.5, 0.5);
    const vec3 b = vec3(0.5, 0.5, 0.5);
    const vec3 c = vec3(1., 1., 0.5);
    const vec3 da = vec3(0.8, 0.9, 0.3);



    vec3 sq = sqrt(col);

    vec3 gg = palette(sq.x * sq.y * sq.z, a, b, c, da);

    fragColor = vec4(gg, 0.0);


}