
uniform sampler2D texture0;
uniform vec2 textureSize0;
varying vec4 gl_TexCoord[];

uniform float u_Elapsed;
uniform vec2 u_WindowSize;

#define iGlobalTime u_Elapsed 
#define time u_Elapsed 
#define iResolution u_WindowSize

vec3 camUp = vec3(0.0, 1.0, 0.0);
vec3 camDir= vec3(0.0, 0.0, 1.0);
vec3 camPos= vec3(0.0, -0.96, -1.76);

vec3 lightPos= vec3(-2.36, 5.75, -7.3);


#define TAO 6.283
const int MAX_ITER = 1;
float PI=3.14159265;

//--------------------------------------------------

vec3 getNormal(in vec3 p);

//------------------------------------------------
vec3 getlightingLambert(in vec3 pos, in vec3 normal, in vec3 lightDir, in vec3 color)
{

    vec3 n2   = normalize ( normal);
    vec3 l2   = normalize ( lightDir-pos );
    vec3 diff = color * max ( dot ( n2, l2 ), 0.0 );   
    return diff;
}



//------------------------------------------
vec3 sim(vec3 p,float s){
   vec3 ret=p;
   ret=p+s/2.0;
   ret=fract(ret/s)*s-s/2.0;
   return ret;
}


//-------------------------------------------------- 
vec3 getmaterial( in vec3 p,  in float mat)
{
 
 vec3 pos = p; 
 vec3 color = vec3(1.);
  

 vec3 colorObject = vec3(0.5, 0.4, 0.3);
 vec3 colorObject1;
   
   if (mat == 0.)
      return vec3(0.4662, 0.4565, 0.4488);
   else if (mat == 1.)
      return vec3(1.0, 1.0, 1.0);   
   else if (mat == 2.)
   {

     float r = pow(colorObject.r, cos(iGlobalTime * 0.5)); 
     float g = pow(colorObject.g, cos(iGlobalTime * 0.3));
     float b = pow(colorObject.b, cos(iGlobalTime * 0.7));  
     colorObject1 = vec3(r, g, b);
     return colorObject1;         
   }
    else if (mat == 3.) 
      return vec3(0.7218, 0.4581, 0.0983);  
   else if (mat == 4.) 
      return vec3(0.5, 0.6, 0.2);     
   
   else   
      return vec3(0.3, 0.9,0.5);
}


//----------------------------------------------------

float makeshowflake(vec3 p)
{
  return length(p)- 0.02;
}
//----------------------------------------------------
float makeShow(vec3 p,float tx,float ty,float tz)
{
  p.y=p.y+time*tx;
  p.x=p.x+time*ty;
  p.z=p.z+time*tz;
  p=sim(p,8.0);
  return makeshowflake(p);
}
//----------------------------------------------------
vec2 show(vec3 p)
{
  float f=makeShow(p,1.11, 1.03, 1.38);
  f=min(f,makeShow(p,1.72, 0.74, 1.06));
  f=min(f,makeShow(p,1.93, 0.75, 1.35));

  return vec2(f,1.0);
}
//----------------------------------------------------
vec4 swag(vec2 pos)
{
 
  vec3 camSide = cross(camDir, camUp);
  mat4 cm=mat4(
    camUp.x,   camUp.y,   camUp.z,   -dot(camUp,camPos),
    camSide.x,   camSide.y,   camSide.z,   -dot(camSide,camPos),
    camDir.x, camDir.y, camDir.z, -dot(camDir,camPos),
    0.0,   0.0,   0.0,   1.0);

  vec4 pc=vec4(0,0,0,0);
  const float maxl=64.0;
  for(float i=0.0;i<maxl;i++)
  {

   vec4 pt=vec4(
    sin(i*PI*2.0*7.0/maxl) * 0.55 * (1.0-i/maxl), 
    i/maxl * 2.1,
    cos(i*PI*2.0*7.0/maxl) * 0.85 * (1.0-i/maxl),  
    1.0);
    
  pt=pt*cm;
  vec2 vPos = pos;
  vPos.y += 1.28;

  vec2 xy=(pt/(-pt.z )).yx + vPos;

  float c;
  c= 0.2/length(xy); 

  pc+=vec4(
          (sin(i*5.0+time*10.0)*0.5 + 0.5) * c,
          (cos(i*3.0+time*8.0)*0.5 + 0.5) * c,
          (sin(i*6.0+time*9.0)*0.5 + 0.5) * c ,0.0);
  }
  pc=pc/maxl; 

  pc=smoothstep(0.0,1.0,pc); 
  
  return pc;
 
}
//----------------------------------------------------

vec2 renderFunction(in vec3 pos)
{

  vec2 result;
  vec3 pos1 = pos;
 
  vec2 showMy = show(pos1);
  result = showMy; 
 
  return result;
}
//-------------------------------------------------
vec3 getNormal(in vec3 p)
{
  const float e = 0.0001;
  return
    normalize
    (
      vec3
      (
        renderFunction(p+vec3(e,0.0,0.0)).x - renderFunction(p+vec3(-e,0.0,0.0)).x,
        renderFunction(p+vec3(0.0,e,0.0)).x - renderFunction(p+vec3(0.0,-e,0.0)).x,
        renderFunction(p+vec3(0.0,0.0,e)).x - renderFunction(p+vec3(0.0,0.0,-e)).x
      )
    );
}

//-------------------------------------------------
vec4 render(in vec3 posOnRay, in vec3 camPos, in vec3 rayDir, out vec2 object)
{ 
  vec4 color = vec4(0.0);
  float t = 0.0;
  vec3 normal;
  vec3 lightDir = lightPos;
  vec4 colorMirror = vec4(0.);
  
 
  vec3 bcol = vec3(0.);              
                      
  //for(int i=0; i<MAX_ITER; ++i)
  //{

    object = renderFunction(posOnRay);
    

   // if(abs(object.x) < 0.004)
   // {
      normal = normalize(getNormal(posOnRay));   
      vec3 materialColor = getmaterial(posOnRay.xyz, object.y); 
      color.rgb = getlightingLambert(posOnRay, normal, lightDir, materialColor); 

      return color;
   // }    
   // t = object.x;
   // posOnRay = posOnRay + t*rayDir;  
  //}

  //color.rgb+=(bcol)*(1.0-clamp(color.w,0.0,0.5));
  //return vec4(color.rgb , 1.0);
}
//-------------------------------------------------

void main( )
{
  vec2 pos =   ( 2.0 * gl_FragCoord.xy - iResolution.xy ) / iResolution.y;

  vec3 camSide = cross(camDir, camUp);
  vec3 rayDir = normalize(camSide*pos.x + camUp*pos.y + camDir);

  float t = 0.0, s = 0.1;
  vec2 object = vec2(1., 1.);

  vec3 posOnRay = camPos;
  vec4 color = vec4(0.);
  gl_FragColor = color;

  color = render(posOnRay, camPos, rayDir, object);
  vec4 swagMy =  swag(pos); 
  gl_FragColor = color  + vec4(swagMy.g); 

}
