uniform float iGlobalTime;
uniform vec3 iResolution;
uniform sampler2D iChannel0;
uniform samplerCube iChannel1;

uniform float u_spacepos;
uniform float u_explosion;

void rX(inout vec3 p, float a)
	{
        float c,s;
		vec3 q=p;
        c = cos(a); s = sin(a);
        p.y = c * q.y - s * q.z;
        p.z = s * q.y + c * q.z;
	}

void rY(inout vec3 p, float a)
	{
        float c,s;
		vec3 q=p;
        c = cos(a); s = sin(a);
        p.x = c * q.x + s * q.z;
        p.z = -s * q.x + c * q.z;
	}

void rZ(inout vec3 p, float a)
	{
        float c,s;
		vec3 q=p;
        c = cos(a); s = sin(a);
        p.x = c * q.x - s * q.y;
        p.y = s * q.x + c * q.y;
	}

void rotate(inout vec3 o, inout vec3 d)
{
    float t=iGlobalTime;
    float pi = 3.14159265;
    o.z-= 0.1;
  rX(o,t*.04);
    rY(o,t*.324);
    rZ(o,t*.24);

  rX(d,t*.04);
    rY(d,t*.324);
    rZ(d,t*.24);

}

void hullu(inout vec3 z, float zr0, inout float dr)
{


  float P=7.;
  //float zr = sqrt( dot(z,z) );
  float zo0 = asin( z.z/zr0 );
  float zi0 = atan( z.y,z.x );

  float zr = pow( zr0, P-1. );
  float zo = zo0 * P;
  float zi = zi0 * P;

  zr += u_explosion;
  
  dr = zr*dr*P + 1.;
  zr *= zr0;
  z  = zr*vec3( cos(zo)*cos(zi), cos(zo)*sin(zi), sin(zo) );

}

float mandelbulb(vec3 o) // 79
	{
  	vec3 z=o;
  	float r;
  	float dr=1.;
  	for (int k = 0; k < 6; k++)	 //max iteration count
  	{
   	r=length(z);
  	hullu(z,r,dr);
	z+=o;
	}
	return -0.3*log(r)*(r/dr);
}

float f(vec3 o, int i)
	{
#if 0
	float t=iGlobalTime;

    float pi = 3.14159265;
    o.z-= 0.1;
	rX(o,t*.04);
    rY(o,t*.324);
    rZ(o,t*.24);

#endif

	//float m=1.;
	float m=mandelbulb(o);
  
	if (m>0.0)
    {
		return length(2.*o);
	}
	else return 40.;

	}


vec3 rm(inout vec3 p, inout vec3 d, float s, float t, int n)	
		{
        vec3 q=p;
 
        float l;
	
		for (int i=0;i<64;i+=1)
			{
                vec3 rot;
                l=f(p,i);
                p+=l*d*s;
                if (l<.001) break;
        }
        
        return 2.0*vec3(length(q-p)*4.0 - 1.0);
	}

float rand(float x)
{
 return fract(sin(x) * 43758.5453);
}

void main(void)
{

//	vec2 p = -1.0 + 2.0 * vec2(gl_FragCoord.x,gl_FragCoord.y*(iResolution.y / iResolution.x)+iResolution.y / 5.0) / iResolution.xy;
  vec2 p = (gl_FragCoord.xy / iResolution.xy) - vec2(0.5);
  p.x *= iResolution.z;
  vec2 uv = p + 0.5;
  p *= vec2(2.0);

	vec3 o=vec3(p.x,p.y,-1.0);
	vec3 d=1.*vec3(p.x,p.y,.6)/(3.*512.);

#if 1
  rotate(o,d);
#endif

float spaceangle = atan(p.x,p.y) / 3.14159;
float spacedist = length(p);

vec2 spaceuv = vec2(spaceangle * 0.1, spacedist * 0.1- iGlobalTime * 0.0142);

  float vignet = 1.0;
 vignet = vignet - max(0.0, length(p) - 0.6 + rand(iGlobalTime)*0.01) * 1.0;

 vec4 star=textureCube(iChannel1, d);
 float spiralpos = mod((spaceangle - iGlobalTime * 0.2) * 2.0 + spacedist * 3.0, 1.0);
 spiralpos += texture2D(iChannel0, spaceuv).r * 0.5 * (1.0-clamp((spacedist - 0.7) * 20.0, 0.0, 1.0));
 float texmix = clamp(spiralpos + u_spacepos, 0.0, 1.0);
texmix *= min(pow(max(length(p) - 0.2, 0.0) * 1.5, 1.0), 1.0);

  //vignet *= texture2D(iChannel0, spaceuv).r * 0.3 * (1.0-clamp((spacedist - 1.0) * 20.0, 0.0, 1.0)) * (1.0-min(spacedist, 1.0));

	vec4 ray = vec4(rm(o,d,1.1,.5,25)/8.,1.0) * vignet;
  
	gl_FragColor = mix(ray, star, texmix);
//  gl_FragColor = star;

}

