const int blobcount=200;
//uniform int activeboxes;
uniform mat4 glmatrix;
//uniform mat4 blobmatrix[blobcount];

//uniform vec3 rotateddim[blobcount];
//uniform vec3 rotatedangles[blobcount];
//uniform float index[blobcount];

uniform float blobx[blobcount];
uniform float bloby[blobcount];
uniform float blobz[blobcount];

uniform vec3 rayorigin;
uniform vec3 raydirection;
uniform vec3 upvector;
mat3 ca;

uniform float fov;

vec2 iResolution=vec2(1920.0,1080.0);
//vec4 iMouse=vec4(1920.0/2.0,1080.0/2.0,1.0,1.0);

uniform float testvalue;
uniform float iTime;
uniform sampler2D iChannel1; 
uniform sampler2D colorMap; 
uniform sampler2D depthMap;

const float pi=3.1415926535897932384626433832795;
vec3 globalpos;

vec2 simplerot(vec2 v, float angle){

    float co = cos(angle);
    float si = sin(angle);
    v.xy = mat2(co,-si,si,co)*v.xy;
    return v;
}
vec2 rot(vec2 v, float angle, vec2 origin){
v=v-origin;
v=simplerot(v,angle);
v=v+origin;
return v;
}
vec2 benddm(vec2 v, float xmax, float angle){
vec2 v2;
v2.x=0.0;
v2.y=v.y;
float factor=v.x/xmax;
vec2 origin;
origin.x=0.0; origin.y=xmax/2.0/pi/(angle/2.0/pi);
v2=rot(v2,angle*factor,origin);
return v2;
}






float h_=0.0;
vec2 opUsc( vec2 d1, vec2 d2, float k ) {
    float h = clamp( 0.5 + 0.5*(d2.x-d1.x)/k, 0.0, 1.0 );
    
    

    

    
    return vec2(mix( d2.x, d1.x, h) - k*h*(1.0-h), d1.y); 
}




#define AA 1

float dot2( in vec2 v ) { return dot(v,v); }
float dot2( in vec3 v ) { return dot(v,v); }
float ndot( in vec2 a, in vec2 b ) { return a.x*b.x - a.y*b.y; }

float sdPlane( vec3 p )
{
	return p.y;
}

float sdSphere( vec3 p, float s )
{
    return length(p)-s;
}

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 sdBoundingBox( vec3 p, vec3 b, float e )
{
       p = abs(p  )-b;
  vec3 q = abs(p+e)-e;

  return min(min(
      length(max(vec3(p.x,q.y,q.z),0.0))+min(max(p.x,max(q.y,q.z)),0.0),
      length(max(vec3(q.x,p.y,q.z),0.0))+min(max(q.x,max(p.y,q.z)),0.0)),
      length(max(vec3(q.x,q.y,p.z),0.0))+min(max(q.x,max(q.y,p.z)),0.0));
}
float sdEllipsoid( in vec3 p, in vec3 r ) 
{
    float k0 = length(p/r);
    float k1 = length(p/(r*r));
    return k0*(k0-1.0)/k1;
}

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

float sdCappedTorus(in vec3 p, in vec2 sc, in float ra, in float rb)
{
    p.x = abs(p.x);
    float k = (sc.y*p.x>sc.x*p.y) ? dot(p.xy,sc) : length(p.xy);
    return sqrt( dot(p,p) + ra*ra - 2.0*ra*k ) - rb;
}

float sdHexPrism( vec3 p, vec2 h )
{
    vec3 q = abs(p);

    const vec3 k = vec3(-0.8660254, 0.5, 0.57735);
    p = abs(p);
    p.xy -= 2.0*min(dot(k.xy, p.xy), 0.0)*k.xy;
    vec2 d = vec2(
       length(p.xy - vec2(clamp(p.x, -k.z*h.x, k.z*h.x), h.x))*sign(p.y - h.x),
       p.z-h.y );
    return min(max(d.x,d.y),0.0) + length(max(d,0.0));
}

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

float sdCapsule( vec3 p, vec3 a, vec3 b, float r )
{
	vec3 pa = p-a, ba = b-a;
	float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );
	return length( pa - ba*h ) - r;
}

float sdRoundCone( in vec3 p, in float r1, float r2, float h )
{
    vec2 q = vec2( length(p.xz), p.y );
    
    float b = (r1-r2)/h;
    float a = sqrt(1.0-b*b);
    float k = dot(q,vec2(-b,a));
    
    if( k < 0.0 ) return length(q) - r1;
    if( k > a*h ) return length(q-vec2(0.0,h)) - r2;
        
    return dot(q, vec2(a,b) ) - r1;
}

float sdRoundCone(vec3 p, vec3 a, vec3 b, float r1, float r2)
{
    
    vec3  ba = b - a;
    float l2 = dot(ba,ba);
    float rr = r1 - r2;
    float a2 = l2 - rr*rr;
    float il2 = 1.0/l2;
    
    
    vec3 pa = p - a;
    float y = dot(pa,ba);
    float z = y - l2;
    float x2 = dot2( pa*l2 - ba*y );
    float y2 = y*y*l2;
    float z2 = z*z*l2;

    
    float k = sign(rr)*rr*rr*x2;
    if( sign(z)*a2*z2 > k ) return  sqrt(x2 + z2)        *il2 - r2;
    if( sign(y)*a2*y2 < k ) return  sqrt(x2 + y2)        *il2 - r1;
                            return (sqrt(x2*a2*il2)+y*rr)*il2 - r1;
}

float sdTriPrism( vec3 p, vec2 h )
{
    const float k = sqrt(3.0);
    h.x *= 0.5*k;
    p.xy /= h.x;
    p.x = abs(p.x) - 1.0;
    p.y = p.y + 1.0/k;
    if( p.x+k*p.y>0.0 ) p.xy=vec2(p.x-k*p.y,-k*p.x-p.y)/2.0;
    p.x -= clamp( p.x, -2.0, 0.0 );
    float d1 = length(p.xy)*sign(-p.y)*h.x;
    float d2 = abs(p.z)-h.y;
    return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.);
}


float sdCylinder( vec3 p, vec2 h )
{
    vec2 d = abs(vec2(length(p.xz),p.y)) - h;
    return min(max(d.x,d.y),0.0) + length(max(d,0.0));
}


float sdCylinder(vec3 p, vec3 a, vec3 b, float r)
{
    vec3 pa = p - a;
    vec3 ba = b - a;
    float baba = dot(ba,ba);
    float paba = dot(pa,ba);

    float x = length(pa*baba-ba*paba) - r*baba;
    float y = abs(paba-baba*0.5)-baba*0.5;
    float x2 = x*x;
    float y2 = y*y*baba;
    float d = (max(x,y)<0.0)?-min(x2,y2):(((x>0.0)?x2:0.0)+((y>0.0)?y2:0.0));
    return sign(d)*sqrt(abs(d))/baba;
}


float sdCone( in vec3 p, in vec2 c, float h )
{
    vec2 q = h*vec2(c.x,-c.y)/c.y;
    vec2 w = vec2( length(p.xz), p.y );
    
	vec2 a = w - q*clamp( dot(w,q)/dot(q,q), 0.0, 1.0 );
    vec2 b = w - q*vec2( clamp( w.x/q.x, 0.0, 1.0 ), 1.0 );
    float k = sign( q.y );
    float d = min(dot( a, a ),dot(b, b));
    float s = max( k*(w.x*q.y-w.y*q.x),k*(w.y-q.y)  );
	return sqrt(d)*sign(s);
}

float sdCappedCone( in vec3 p, in float h, in float r1, in float r2 )
{
    vec2 q = vec2( length(p.xz), p.y );
    
    vec2 k1 = vec2(r2,h);
    vec2 k2 = vec2(r2-r1,2.0*h);
    vec2 ca = vec2(q.x-min(q.x,(q.y < 0.0)?r1:r2), abs(q.y)-h);
    vec2 cb = q - k1 + k2*clamp( dot(k1-q,k2)/dot2(k2), 0.0, 1.0 );
    float s = (cb.x < 0.0 && ca.y < 0.0) ? -1.0 : 1.0;
    return s*sqrt( min(dot2(ca),dot2(cb)) );
}

float sdCappedCone(vec3 p, vec3 a, vec3 b, float ra, float rb)
{
    float rba  = rb-ra;
    float baba = dot(b-a,b-a);
    float papa = dot(p-a,p-a);
    float paba = dot(p-a,b-a)/baba;

    float x = sqrt( papa - paba*paba*baba );

    float cax = max(0.0,x-((paba<0.5)?ra:rb));
    float cay = abs(paba-0.5)-0.5;

    float k = rba*rba + baba;
    float f = clamp( (rba*(x-ra)+paba*baba)/k, 0.0, 1.0 );

    float cbx = x-ra - f*rba;
    float cby = paba - f;
    
    float s = (cbx < 0.0 && cay < 0.0) ? -1.0 : 1.0;
    
    return s*sqrt( min(cax*cax + cay*cay*baba,
                       cbx*cbx + cby*cby*baba) );
}


float sdSolidAngle(vec3 pos, vec2 c, float ra)
{
    vec2 p = vec2( length(pos.xz), pos.y );
    float l = length(p) - ra;
	float m = length(p - c*clamp(dot(p,c),0.0,ra) );
    return max(l,m*sign(c.y*p.x-c.x*p.y));
}

float sdOctahedron(vec3 p, float s)
{
    p = abs(p);
    float m = p.x + p.y + p.z - s;

    
    #if 0
    vec3 o = min(3.0*p - m, 0.0);
    o = max(6.0*p - m*2.0 - o*3.0 + (o.x+o.y+o.z), 0.0);
    return length(p - s*o/(o.x+o.y+o.z));
    #endif
    
    
    #if 1
 	vec3 q;
         if( 3.0*p.x < m ) q = p.xyz;
    else if( 3.0*p.y < m ) q = p.yzx;
    else if( 3.0*p.z < m ) q = p.zxy;
    else return m*0.57735027;
    float k = clamp(0.5*(q.z-q.y+s),0.0,s); 
    return length(vec3(q.x,q.y-s+k,q.z-k)); 
    #endif
    
    
    #if 0
	return m*0.57735027;
    #endif
}

float sdPyramid( in vec3 p, in float h )
{
    float m2 = h*h + 0.25;
    
    
    p.xz = abs(p.xz);
    p.xz = (p.z>p.x) ? p.zx : p.xz;
    p.xz -= 0.5;
	
    
    vec3 q = vec3( p.z, h*p.y - 0.5*p.x, h*p.x + 0.5*p.y);
   
    float s = max(-q.x,0.0);
    float t = clamp( (q.y-0.5*p.z)/(m2+0.25), 0.0, 1.0 );
    
    float a = m2*(q.x+s)*(q.x+s) + q.y*q.y;
	float b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t);
    
    float d2 = min(q.y,-q.x*m2-q.y*0.5) > 0.0 ? 0.0 : min(a,b);
    
    
    return sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y));;
}


float sdRhombus(vec3 p, float la, float lb, float h, float ra)
{
    p = abs(p);
    vec2 b = vec2(la,lb);
    float f = clamp( (ndot(b,b-2.0*p.xz))/dot(b,b), -1.0, 1.0 );
	vec2 q = vec2(length(p.xz-0.5*b*vec2(1.0-f,1.0+f))*sign(p.x*b.y+p.z*b.x-b.x*b.y)-ra, p.y-h);
    return min(max(q.x,q.y),0.0) + length(max(q,0.0));
}



vec2 opU( vec2 d1, vec2 d2 )
{
	return (d1.x<d2.x) ? d1 : d2;
}
vec2 opS( vec2 d2, vec2 d1 ) 
{ 
    return (-d1.x>d2.x) ? vec2(-d1.x,d1.y) : d2; 
}

float opUnion( float d1, float d2 ) { return min(d1,d2); }

float opSubtraction( float d1, float d2 ) { return max(-d1,d2); }

float opIntersection( float d1, float d2 ) { return max(d1,d2); }


#define ZERO 0




vec2 map_bkgnd(in vec3 pos){
   vec2 res;
    res = vec2( sdBox(    pos-vec3(0.0,-0.25, 0.0), vec3(5,0.25,5)), 1.0 );
    return res;
}

mat4 rotateY(float theta) {
    float c = cos(theta);
    float s = sin(theta);

    return mat4(
        vec4(c, 0, s, 0),
        vec4(0, 1, 0, 0),
        vec4(-s, 0, c, 0),
        vec4(0, 0, 0, 1)
    );
}

mat4 rotateX(float theta) {
    float c = cos(theta);
    float s = sin(theta);

    return mat4(
        vec4(1, 0, 0, 0),
        vec4(0, c, -s, 0),
        vec4(0, s, c, 0),
        vec4(0, 0, 0, 1)
    );
}

mat4 rotateZ(float theta) { 
    float c = cos(theta);
    float s = sin(theta);

    return mat4(
        vec4(c, -s, 0, 0),
        vec4(s, c, 0, 0),
        vec4(0, 0, 1, 0),
        vec4(0, 0, 0, 1)
    );
}
    
    
    
    
    
vec2 bend( in vec2 p, in float l, in float a)
{
    a=a/2.0;
    float w=0.5;
    
    
    if( abs(a)<0.001 )
    {
        float v = p.y;
        p.y -= clamp(p.y,0.0,l);
		return vec2(p.x, v );
    }
    
    
    vec2  sc = vec2(sin(a),cos(a));
    float ra = 0.5*l/a;
    
    
    p.x -= ra;
    
    
    vec2 q = p - 2.0*sc*max(0.0,dot(sc,p));

	
    float u = abs(ra)-length(q);
    float d = (q.y<0.0) ? length( q+vec2(ra,0.0) ) : abs(u);

    
    float s = sign(a);
    float v = ra*atan(s*p.y,-s*p.x);
    u = u*s;
    if( v<0.0 )
    {
        
        
        { v = abs(ra)*2.0*pi + v; }
        
    }
    
    return vec2( u, v );
}
    
vec2 bend_old( in vec2 p, in float l, in float a )
{
    a=a/2.0;

    if( abs(a)<0.001 ) return p;  
    
    float ra = 0.5*l/a;
    p.x -= ra;

    vec2 sc = vec2(sin(a),cos(a));
    vec2 q = p - 2.0*sc*max(0.0,dot(sc,p));

    float s = sign(a);

    
    
         
    
    
    if (p.y<=0.0)
        return vec2(sign(-s*p.x)*(q.x+ra), (s*p.x<0.0)?p.y:l-p.y);
        
    else
        return vec2(ra-s*length(q),        ra*atan(s*p.y,-s*p.x));
}

vec2 bend_( in vec2 p, in float l, in float a )
{
    if( abs(a)<0.001 ) return p;  
    
    float ra = 0.5*l/a;
    p.x -= ra;
    
    vec2 sc = vec2(sin(a),cos(a));
    vec2 q = p - 2.0*sc*max(0.0,dot(sc,p));
    
    float s = sign(a);
    return vec2( (p.y>0.0) ? ra-s*length(q)        : sign(-s*p.x)*(q.x+ra),
                 (p.y>0.0) ? ra*atan(s*p.y,-s*p.x) : (s*p.x<0.0)?p.y:l-p.y );
}

float hash(vec3 p)  
{
    p  = fract( p*0.3183099+.1 );
	p *= 17.0;
    return fract( p.x*p.y*p.z*(p.x+p.y+p.z) );
}

float noise( in vec3 x )
{
    x*=1.3;
    
    float time=0.0;
    
    x.y+=time*1.5;
    x.z+=time*1.9;

    vec3 i = floor(x);
    vec3 f = fract(x);
    f = f*f*(3.0-2.0*f);
	
    return mix(mix(mix( hash(i+vec3(0,0,0)), 
                        hash(i+vec3(1,0,0)),f.x),
                   mix( hash(i+vec3(0,1,0)), 
                        hash(i+vec3(1,1,0)),f.x),f.y),
               mix(mix( hash(i+vec3(0,0,1)), 
                        hash(i+vec3(1,0,1)),f.x),
                   mix( hash(i+vec3(0,1,1)), 
                        hash(i+vec3(1,1,1)),f.x),f.y),f.z);
}



mat4 getRot3(float xangle, float yangle){
float ct=cos(xangle); float st=sin(xangle);

	mat4 rotm=mat4(1.0, 0.0, 0.0,  0.0,
	         0.0,  ct, -st,  0.0,
	         0.0,  st,  ct,  0.0,
	         0.0, 0.0, 0.0,  1.0);
             

float ct2=cos(yangle); float st2=sin(yangle);
	mat4 rotm2=mat4( ct, 0.0,  st,  0.0,
	         0.0, 1.0, 0.0,  0.0,
	         -st, 0.0,  ct,  0.0,
	         0.0, 0.0, 0.0,  1.0);
             
    
    
    return rotm*rotm2;
}


float h_factor=0.7;
float r_factor=1.1;
vec3 uv;
vec2 map( in vec3 pos )
{

    //pos=-pos;
    vec2 res;
    
    
    res = vec2(-100.0,-120.0);
    
    

    for (int i=0;i<blobcount;i++){
        //float time=iTime/1000.0*6.28;
        //mat4 rotation=getRot3(rotatedangles[i].x,rotatedangles[i].y);
        //vec3 posnoise_=pos+(blobmatrix[i]*vec4(0,0,0,1.0)).xyz;
        

        
        //vec3 pos_=posnoise_*(-20.0*1.15);
        

        //vec3 q = 1.5*posnoise_*4.0/1.5/1.4+vec3(5.7,5.7,5.7)+vec3(0,0.08-1.0+2.16-1.0,0)+vec3(float(index[i]),0.0,0.0);
        //vec3 q2 = q*1.85; 
        //vec3 q3 =pos/4.0;
        //float f = 0.75*noise(q)/1.75;
        //float f2 = 0.5*noise(q2)/1.55*1.28;
        //float f3 = 0.5*noise(q3)/4.0;
        
        //const float r_factor=0.35;
        //float r=(r_factor/6.0+f*2.55)/1.2*1.32/1.1;
        //float r2=r+(r_factor/6.0+f2*2.55)/1.2*1.32/1.1*-3.0;
        //float r3=r2+(f3*2.55)/1.2*1.32/1.1;

        
        
        const float size=0.1;
        res = opUsc(res, vec2(sdBox(pos+vec3(blobx[i],bloby[i],blobz[i]),vec3(size,size,size)*testvalue), 120.0),0.05);
        res = opUsc(res, vec2(sdBox(pos+vec3(0,0,0),vec3(5,5,5)), 120.0),0.05);
        
    }

    return res;
}


vec2 iBox( in vec3 ro, in vec3 rd, in vec3 rad ) 
{
    vec3 m = 1.0/rd;
    vec3 n = m*ro;
    vec3 k = abs(m)*rad;
    vec3 t1 = -n - k;
    vec3 t2 = -n + k;
	return vec2( max( max( t1.x, t1.y ), t1.z ),
	             min( min( t2.x, t2.y ), t2.z ) );
}

float cloud_a=0.0;
vec2 res_bkgnd=vec2(0.0);
vec3 pos_bkgnd;
vec3 ro_bkgnd;
vec3 rd_bkgnd;

vec2 raycast_bkgnd( in vec3 ro, in vec3 rd )
{
    vec2 res = vec2(-1.0,-1.0);

    float tmin = 1.0;
    float tmax = 20.0;

    
    
    vec2 tb = iBox( ro-vec3(0.0,0.4,-0.5), rd, vec3(2.5,0.41,3.0) );
    if( tb.x<tb.y && tb.y>0.0 && tb.x<tmax)
    {
        
        tmin = max(tb.x,tmin);
        tmax = min(tb.y,tmax);

        float t = tmin;
        for( int i=0; i<70 && t<tmax; i++ )
        {
            vec2 h = map_bkgnd( ro+rd*t );
            if( abs(h.x)<(0.0001*t) )
            { 
                res = vec2(t,h.y);
                break;
            }
            
            t += h.x;
        }
    }
    
    return res;
}




vec2 castRay( const vec3 ro, vec3 rd )
 {
    float scale=1.0;
    vec2 res=vec2(100,100);
    float tmin = 0.0000001;
    float t = tmin;
    
    
    int steps_=int(float(150)/2.0*0.6);
    float precision_=0.001/64.0*200.0/2.0/100.0*4.7/0.28*83.0;
    float stepper=0.85*0.7*1.2*0.74*0.3/4.0; 

     {
 
        float t = tmin;
        for( int i=0; i<steps_; i++ )
        {
            
            vec3 dest=ro+rd*t;

            /*
            if (dest.x<-2.0*1.9*1.7||dest.x>2.0*1.9*1.7||dest.y<0.0||dest.y>5.0*0.8) {
                res=vec2(100,-120);
                break;
            }
            */

            vec2 a = map(dest);

            vec2 h = a;
            
            if( abs(h.x)<(precision_*t) )
            {
                res = vec2(t,h.y);
                break;
            }
            t += h.x*stepper;
        }
    }

    
    float m = res.y;
    return res;
    
}

#define TOLERANCE       0.00001
#define MAX_RAY_LENGTH  10.0
#define MAX_RAY_MARCHES 50

float rayMarch(vec3 ro, vec3 rd) {
  float t = 0.0;
  int i = 0;
  for (i = 0; i < MAX_RAY_MARCHES; i++) {
    vec2 m = map(ro + rd*t);
    float d = m.x;
    if (d < TOLERANCE || t > MAX_RAY_LENGTH) break;
    t += d;
  }
  
  return vec2(t,m.y);
}




vec2 raycast( in vec3 ro, in vec3 rd )
{
    vec2 res = vec2(-1.0,-1.0);

    float tmin = 1.0;
    float tmax = 20.0;
    
    {
        float t = tmin;
        for( int i=0; i<70 && t<tmax; i++ )
        {
            vec2 h = map( ro+rd*t );
            if( abs(h.x)<(0.0001*t) )
            { 
                res = vec2(t,h.y);
                break;
            }
            
            t += h.x;
        }
    }
    
    return res;
}


float calcSoftshadow( in vec3 ro, in vec3 rd, in float mint, in float tmax )
{
    
    float tp = (0.8-ro.y)/rd.y; if( tp>0.0 ) tmax = min( tmax, tp );

    float res = 1.0;
    float t = mint;
    for( int i=ZERO; i<24; i++ )
    {
		float h = map( ro + rd*t ).x;
        float s = clamp(8.0*h/t,0.0,1.0);
        res = min( res, s*s*(3.0-2.0*s) );
        t += clamp( h, 0.02, 0.2 );
        if( res<0.004 || t>tmax ) break;
    }
    return clamp( res, 0.0, 1.0 );
}


vec3 calcNormal( in vec3 pos )
{
#if 0
    vec2 e = vec2(1.0,-1.0)*0.5773*0.0005;
    return normalize( e.xyy*map( pos + e.xyy ).x + 
					  e.yyx*map( pos + e.yyx ).x + 
					  e.yxy*map( pos + e.yxy ).x + 
					  e.xxx*map( pos + e.xxx ).x );
#else
    
    vec3 n = vec3(0.0);
    for( int i=ZERO; i<4; i++ )
    {
        vec3 e = 0.5773*(2.0*vec3((((i+3)>>1)&1),((i>>1)&1),(i&1))-1.0);
        n += e*map(pos+0.0005*e).x;
      
    }
    return normalize(n);
#endif    
}

float calcAO( in vec3 pos, in vec3 nor )
{
	float occ = 0.0;
    float sca = 1.0;
    for( int i=ZERO; i<5; i++ )
    {
        float h = 0.01 + 0.12*float(i)/4.0;
        float d = map( pos + h*nor ).x;
        occ += (h-d)*sca;
        sca *= 0.95;
        if( occ>0.35 ) break;
    }
    return clamp( 1.0 - 3.0*occ, 0.0, 1.0 ) * (0.5+0.5*nor.y);
}


float checkersGradBox( in vec2 p, in vec2 dpdx, in vec2 dpdy )
{
    
    vec2 w = abs(dpdx)+abs(dpdy) + 0.001;
    
    vec2 i = 2.0*(abs(fract((p-0.5*w)*0.5)-0.5)-abs(fract((p+0.5*w)*0.5)-0.5))/w;
    
    return 0.5 - 0.5*i.x*i.y;                  
}

vec4 render( in vec3 ro, in vec3 rd, in vec3 rdx, in vec3 rdy )
{ 
    vec3 pos;
    vec3 nor;

    
    vec3 col = vec3(0.2, 0.2, 0.2);
    
    
    vec3 col2=vec3(0.0); 
    float a=0.0;
    int layers=0;
    cloud_a=0.0;


    vec3 pos_cloud=vec3(0.0);
    
    
    vec2 res = castRay(ro,rd);

    //vec2 res = rayMarch(ro,rd);

    float t = res.x;
	float m = res.y;

        float specular;
    if( m>-0.5 )
    {
        vec3 pos = ro + t*rd;
        pos_cloud=pos;
        globalpos=pos;
        nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal( pos );
        vec3 ref = reflect( rd, nor );
        
        
        col=vec3(0.0,0.0,0.0);
        
        float ks = 1.0;
        
        
        
        
col=col2;
vec3 col_bkgnd;
        
        
    if (false)
    {
    vec2 res = vec2(-100,-100);//raycast_bkgnd(ro,rd);
    float t = res.x;
	float m = res.y;
        vec3 pos = ro + t*rd;
        

#ifdef LIGHTING
        pos+=nor/4.0;
#endif
        
        
        
        
        col=col_bkgnd=texture2D(iChannel1,pos.xz/2.0).xyz;
    }


        




col=texture2D(iChannel1,vec2(uv.x,uv.y)).rgb;


        
        float occ = calcAO( pos, nor );
        
		vec3 lin = vec3(0.0);
        const float dim=1.1;
        
        
        {
            
            vec3  lig = normalize( vec3(-10.5, 6.4, 4.6) );
            vec3  hal = normalize( lig-rd );
            float dif = clamp( dot( nor, lig ), 0.0, 1.0 );
                  dif /= dim;
          
              

        	      
			float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0);
                  spe *= dif;
                  spe *= 0.04+0.96*pow(clamp(1.0-dot(hal,lig),0.0,1.0),5.0);
                  spe /= dim;
                  specular=clamp(spe,0,1);
            
            
        }
        
        if (false)
        {
            float dif = sqrt(clamp( 0.5+0.5*nor.y, 0.0, 1.0 ));
                  dif *= occ;
                  dif /= dim;
            float spe = smoothstep( -0.2, 0.2, ref.y );
                  spe *= dif;
                  spe *= 0.04+0.96*pow(clamp(1.0+dot(nor,rd),0.0,1.0), 5.0 );
                  spe /= dim;
          
                  
            lin += col*0.60*dif*vec3(0.40,0.60,1.15);
            lin +=     2.00*spe*vec3(0.40,0.60,1.30)*ks;
        }
        
        if (false)
        {
        	float dif = clamp( dot( nor, normalize(vec3(0.5,0.0,0.6))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0);
                  dif *= occ;
        	lin += col*0.55*dif*vec3(0.25,0.25,0.25);
        }
        
        if (false)
        {
            float dif = pow(clamp(1.0+dot(nor,rd),0.0,1.0),2.0);
                  dif *= occ;
        	lin += col*0.25*dif*vec3(1.00,1.00,1.00);
        }
     
col+=100.0*specular*1.3;
        
    }

	

    vec2 coos=gl_FragCoord.xy;
    float xc=coos.x/iResolution.x;
    float yc=coos.y/iResolution.y;
    float alpha = clamp(pow(abs(dot(normalize(nor),normalize(rd-ro))),1.2),0,1);
    
    float alpha2=alpha+(0.75-1.0);
    
if(res.y>100)
	///return vec4( mix(clamp(col,0.0,1.0),texture2D(colorMap,vec2(xc,yc)+(nor.xy)/35.0*2.5).rgb,alpha2),alpha-specular*-17.5+(1.5-1.0));
    return vec4(1,0,0,1);
else
   {
    vec2 coos=gl_FragCoord.xy;
    float xc=coos.x/iResolution.x;
    float yc=coos.y/iResolution.y;
    //return vec4(texture2D(colorMap,vec2(xc,yc)).xyz,0.0);
    return vec4(0,0,1,1);
   }
}

mat3 setCamera( in vec3 ro, in vec3 ta, float cr )
{

    vec3 cw = normalize(ta-ro);

    
    vec3 cp = upvector;
    

    vec3 cu = normalize( cross(cw,cp) );
    vec3 cv = normalize( cross(cu,cw) );
    return mat3( cu, cv, cw );
}


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

    vec2 mo = vec2(0.0);
	float time = 0.0;

    
    
    vec3 ta = vec3( 0.0, -0.5, -0.0 );
    
    vec3 ro = ta + vec3( 0.0, 0.5, 0.0 );
    
    mat3 ca = setCamera( ro, ta, 0.0 );

    vec3 tot = vec3(0.0);
#if AA>1
    for( int m=ZERO; m<AA; m++ )
    for( int n=ZERO; n<AA; n++ )
    {
        
        vec2 o = vec2(float(m),float(n)) / float(AA) - 0.5;
        vec2 p = (2.0*(fragCoord+o)-iResolution.xy)/iResolution.y;
#else    
        vec2 p = (2.0*fragCoord-iResolution.xy)/iResolution.y;
#endif

        
        const float fl = 2.5;
        
        
        vec3 rd = ca * normalize( vec3(p,fl) );

         
        vec2 px = (2.0*(fragCoord+vec2(1.0,0.0))-iResolution.xy)/iResolution.y;
        vec2 py = (2.0*(fragCoord+vec2(0.0,1.0))-iResolution.xy)/iResolution.y;
        vec3 rdx = ca * normalize( vec3(px,fl) );
        vec3 rdy = ca * normalize( vec3(py,fl) );
        
        
        vec3 col = render( ro, rd, rdx, rdy );

        
        
        
		
       

        tot += col;
#if AA>1
    }
    tot /= float(AA*AA);
#endif
    
    fragColor = vec4( tot, 1.0 );
}

void mainImage2( out vec4 fragColor, in vec2 fragCoord )
{
    //vec2 mo = iMouse.xy/iResolution.xy;
    float time = 15.0 + iTime;


    vec2 p = (-iResolution.xy + 2.0*fragCoord)/iResolution.y;
    //vec2 p = (-iResolution.xy + fragCoord)/iResolution.y;


    //vec3 ro = vec3( -0.5+3.5*cos(0.1*time + 6.0*mo.x), 3.0 + 2.0*mo.y, 0.5 + 4.0*sin(0.1*time + 6.0*mo.x) );
    //vec3 ta = vec3( -0.5, -0.4, 0.5 );

    vec3 ro,ta;
    ro=rayorigin;
    ta=raydirection;

    ca = setCamera( ro, ta, 0.0 );

    float fov_=fov;
    vec3 rd = ca * normalize( vec3(p.x,p.y,fov_ ) );

    vec4 col = render( ro, rd, 0, 0 );
    //col=vec4(1,0,0,1);

    fragColor = vec4( col );
}


void main()
{

    vec4 color=vec4(0.0, 0.0, 0.0, 0.0);
    vec2 coos=gl_FragCoord.xy;
    
    
    
    
    float xc=coos.x/iResolution.x;
    float yc=coos.y/iResolution.y;
    
    
    
    float dim=0.9*2.0;
    

    mainImage2(color,coos);

    
    
    /*
    vec4 globalposscreen=(glmatrix*vec4(globalpos,1.0));

    float depth=globalposscreen.z/200.0;
    double x2=depth*(65536*256);
    double r2=floor(x2/(65536)); x2=x2-r2*(65536);
    double g2=floor(x2/(256)); x2=x2-g2*(256);
    double b2=floor(x2/(1)); x2=x2-b2*(1);
    float r1=float(r2/256.0);
    float g1=float(g2/256.0);
    float b1=float(b2/256.0);
    

    float currdepth=(r1*65536.0+g1*256.0+b1)/(65536.0*256.0)*200.0;
    vec4 f=texture2D(depthMap,vec2(xc,yc));
    
    float imagedepth=(f.r*65536.0+f.g*256.0+f.b)/(65536.0*256.0)*200.0;
    
    if (imagedepth<currdepth) color=vec4(0,0,0,0);
    */

    gl_FragColor = color;
}
