uniform int seq;

uniform sampler2D iChannel0;
uniform sampler2D iChannel1;
uniform sampler2D iChannel2;

uniform float iTime;

uniform float testvalue;

uniform float spheresfactor;

uniform vec3 rayorigin;
uniform vec3 raydirection;
uniform vec3 upvector;
uniform float fov;
//uniform mat4 glmatrix;
float totalindex,currentindex,useindex;

//float doff;

vec2 iResolution=vec2(1920.0,1080.0);

#define AA 0
// keep this 0 at all times

vec4 col2;

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

vec4 opElongate( in vec3 p, in vec3 h )
{
    //return vec4( p-clamp(p,-h,h), 0.0 ); // faster, but produces zero in the interior elongated box
    
    vec3 q = abs(p)-h;
    return vec4( max(q,0.0), min(max(q.x,max(q.y,q.z)),0.0) );
}

vec2 opU( vec2 d1, vec2 d2 ) { 
if (d1.x<d2.x) return d1; else return d2;
//return min(d1,d2); 
}

float opUp( float d1, float d2 ) { 
if (d1<d2) return d1; else return d2;
//return min(d1,d2); 
}

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

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) { ///not tested
    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)
    );
}

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

float sdCappedCylinder( 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 sdTorus( vec3 p, vec2 t )
{
  vec2 q = vec2(length(p.xz)-t.x,p.y);
  return length(q)-t.y;
}

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 map(in vec3 pos)
{
    float d = 1e10;
    

    // ellipsoide
    {
    vec3 q = pos - vec3(-3.0,0.0,-1.0);
    d = min( d, sdEllipsoid( q.yzx, vec3(0.4,0.2,0.1) ) );
    }
    
    // elongated ellipsoide
    {
    vec3 q = pos - vec3(-3.0,0.0,1.0);
    vec4 w = opElongate( q, vec3(0.2,0.0,0.3) );
    d = min( d, w.w+sdEllipsoid( w.yzx, vec3(0.4,0.2,0.1) ) );
    }

    // cylinder
    {
    vec3 q = pos - vec3(-1.0,0.0,-1.0);
    d = min( d, sdCappedCylinder( q, vec2(0.4,0.1) ) );
    }
    
    // elongated cylinder
    {
    vec3 q = pos - vec3(-1.0,0.0,1.0);
    vec4 w = opElongate( q, vec3(0.2,0.0,0.3) );
    d = min( d, w.w+sdCappedCylinder( w.xyz, vec2(0.4,0.1) ) );
    }

    // torus
    {
    vec3 q = pos - vec3(1.0,0.0,-1.0);
    d = min( d, sdTorus( q, vec2(0.4,0.05) ) );
    }
    
    // elongated torus
    {
    vec3 q = pos - vec3(1.0,0.0,1.0);
    vec4 w = opElongate( q, vec3(0.2,0.0,0.3) );
    d = min( d, w.w+sdTorus( w.xyz, vec2(0.4,0.05) ) );
    }

    // torus
    {
    vec3 q = pos - vec3(3.0,0.0,-1.0);
    d = min( d, sdTorus( q.xzy, vec2(0.4,0.05) ) );
    }
    
    // elongated torus
    {
    vec3 q = pos - vec3(3.0,0.0,1.0);
    vec4 w = opElongate( q, vec3(0.2,0.0,0.3) );
    d = min( d, w.w+sdTorus( w.xzy, vec2(0.4,0.05) ) );
    }

    return d;
}


/// pyramid sdf by TheTurk

// signed distance to a pyramid of base 1x1 and height h
bool flipp=false;
float sdPyramid( in vec3 p, in float h, in vec3 scale )
{
    //p.x/=4.0;
    
    //p.x+=0.4;
  
    p.x/=scale.x;
    p.y/=scale.y;
    p.z/=scale.z;

    //if (false)
    if (flipp)
    {
        //p.y*=-1.0;
        p.y-=1.0;
        p=(vec4(p,1.0)*rotateX(3.14)).xyz;
    }

    float m2 = h*h + 0.25;
    
    // symmetry
    p.xz = abs(p.xz); // do p=abs(p) instead for double pyramid
    p.xz = (p.z>p.x) ? p.zx : p.xz;
    p.xz -= 0.5;
	
    // project into face plane (2D)
    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*q.x)/(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 = max(-q.y,q.x*m2+q.y*0.5) < 0.0 ? 0.0 : min(a,b);
    
    // recover 3D and scale, and add sign
    return sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y));;
}


float opSubstP( float d1, float d2 ) { return max(-d1,d2); }
float sdBoxP( vec3 p, vec3 b )
{
  vec3 q = abs(p) - b;
  return length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0);
}

//float map( in vec3 pos )
float pyramid2(vec3 position, float halfWidth1, float halfDepth1, float halfWidth2, float halfDepth2, float halfHeight)
{//7*7
    vec3 pos=position;
    pos.y+=0.01;
    
    //float rad = 0.2*(0.5-0.45*cos(iTime*3.0));
    //float hei = 1.5*(0.5+0.45*sin(iTime*1.0));
    float hei=1.0;
    float h2=0.05; //0.075
    vec3 scale=vec3(1.4,1.0,1.4);
    float py=sdPyramid(pos,hei,scale);// - rad;
    vec3 posbox=pos; posbox+=vec3(0,-hei-h2,0);
    float box=sdBoxP(posbox,vec3(3.5,hei,3.5));
    py=opSubstP(box,py);
    return py;
}

float pyramid3(vec3 position, float halfWidth1, float halfDepth1, float halfWidth2, float halfDepth2, float halfHeight)
{//1*1
    vec3 pos=position;
    pos.y-=0.2;
    pos=(vec4(pos,1.0)*rotateZ(3.14)).xyz;
    
    //float rad = 0.2*(0.5-0.45*cos(iTime*3.0));
    //float hei = 1.5*(0.5+0.45*sin(iTime*1.0));
    float hei=0.6;
    float h2=0.075;
    vec3 scale=vec3(1.5,1.0,1.5);
    flipp=true;
    float py=sdPyramid(pos,hei,scale);// - rad;
    flipp=false;
    vec3 posbox=pos; posbox+=vec3(0,-hei-h2,0);
    float box=sdBoxP(posbox,vec3(3.5,hei,3.5));
    //py=opSubstP(box,py);
    return py;
}

float pyramid4(vec3 position, float halfWidth1, float halfDepth1, float halfWidth2, float halfDepth2, float halfHeight)
{//4*1
    vec3 pos=position;
    pos.y-=0.2;
    pos.x-=0.2;
    pos=(vec4(pos,1.0)*rotateZ(3.14)).xyz;
    
    //float rad = 0.2*(0.5-0.45*cos(iTime*3.0));
    //float hei = 1.5*(0.5+0.45*sin(iTime*1.0));
    float hei=0.6;
    float h2=0.075;
    //vec3 scale=vec3(4.75*1.0,1.0,1.35);
    vec3 scale=vec3(1.5,1.0,1.5);
    flipp=true;
    float py1=sdPyramid(pos-vec3(0.3,0,0),hei,scale);// - rad;
    float py2=sdPyramid(pos,hei,scale+vec3(2.0,0,0));// - rad;
    float py3=sdPyramid(pos+vec3(0.3,0,0),hei,scale);// - rad;
    flipp=false;
    vec3 posbox=pos; posbox+=vec3(0,-hei-h2,0);
    float box=sdBoxP(posbox,vec3(3.5,hei,3.5));
    //py=opSubstP(box,py);
    float py=opUp(opUp(py1,py2),py3);
    return py;
}

float pyramid3_(vec3 position, float halfWidth1, float halfDepth1, float halfWidth2, float halfDepth2, float halfHeight)
{//1*1
    vec3 pos=position;
    //pos*=-1.0;
    pos.y-=0.01;
    pos=(vec4(pos,1.0)*rotateX(3.14)).xyz;
    
    //float rad = 0.2*(0.5-0.45*cos(iTime*3.0));
    //float hei = 1.5*(0.5+0.45*sin(iTime*1.0));
    const float sc=1.5;
    float hei=0.1/0.05/sc;
    float h2=0.075/2.25*15.0;
    vec3 scale=vec3(0.2*sc,1.0,0.2*sc);
    float py=sdPyramid(pos,hei,scale);// - rad;
    vec3 posbox=pos; posbox+=vec3(0,+hei+h2,0);
    float box=sdBoxP(posbox,vec3(0.2,hei,0.2));
    py=opSubstP(box,py);
    return py;
}

float pyramid(vec3 position, float halfWidth1, float halfDepth1, float halfWidth2, float halfDepth2, float halfHeight) {
    position.xz = abs(position.xz);
    
    float s1 = abs(position.y) - halfHeight;
    // bottom
    vec3 base1 = vec3(max(position.x - halfWidth1, 0.0), abs(position.y + halfHeight), max(position.z - halfDepth1, 0.0));
    float d1 = dot(base1, base1);
    // top
    vec3 base2 = vec3(max(position.x - halfWidth2, 0.0), abs(position.y - halfHeight), max(position.z - halfDepth2, 0.0));
    float d2 = dot(base2, base2);
   
    vec3 point1 = vec3(halfWidth1, -halfHeight, halfDepth1);
    vec3 point2 = vec3(halfWidth2, halfHeight, halfDepth2);
    vec3 position1 = position - point1;
    vec3 position2 = position - point2;
    vec3 end = point2 - point1;
 
    vec3 segment = position1 - end * clamp(dot(position1, end) / dot(end, end), 0.0, 1.0);
    float d = dot(segment, segment);
    // side
    vec3 normal1 = vec3(end.y, -end.x, 0.0);
    float s2 = dot(position1.xy, normal1.xy);
    float d3 = d;
    if (dot(position1.xy, -end.xy) < 0.0 && 
        dot(position2.xy, end.xy) < 0.0 &&
        dot(position1, cross(normal1, end)) < 0.0) { 
        d3 = s2 * s2 / dot(normal1.xy, normal1.xy);
    }
    // front/back
    vec3 normal2 = vec3(0.0, -end.z, end.y);
    float s3 = dot(position1.yz, normal2.yz);
    float d4 = d;
    if (dot(position1.yz, -end.yz) < 0.0 &&
        dot(position2.yz, end.yz) < 0.0 && 
        dot(position1, cross(normal2, -end)) < 0.0) { 
        d4 = s3 * s3 / dot(normal2.yz, normal2.yz);
    }
    return sqrt(min(min(min(d1, d2), d3), d4)) * sign(max(max(s1, s2), s3));
}

float sdf(in vec3 position, float halfWidth1, float halfDepth1, float halfWidth2, float halfDepth2, float halfHeight) { 
    float cornerRadius = 0.0001; //0.01
    /*
    float halfWidth1 = 0.55; //0.35
    float halfDepth1 = 0.35; //0.35
    float halfWidth2 = 0.4; //0.2
    float halfDepth2 = 0.2; //0.2
    float halfHeight = 0.25; //0.25
    */
    float d = pyramid(position, halfWidth1, halfDepth1, halfWidth2, halfDepth2, halfHeight);
    //d -= cornerRadius;
    return d;
}
float sdf2(in vec3 position, float halfWidth1, float halfDepth1, float halfWidth2, float halfDepth2, float halfHeight) { 
    float cornerRadius = 0.0001; //0.01
    float d = pyramid2(position, halfWidth1, halfDepth1, halfWidth2, halfDepth2, halfHeight);
    return d;
}

float sdf3(in vec3 position, float halfWidth1, float halfDepth1, float halfWidth2, float halfDepth2, float halfHeight) { 
    float cornerRadius = 0.0001; //0.01
    float d = pyramid3(position, halfWidth1, halfDepth1, halfWidth2, halfDepth2, halfHeight);
    return d;
}

float sdf4(in vec3 position, float halfWidth1, float halfDepth1, float halfWidth2, float halfDepth2, float halfHeight) { 
    float cornerRadius = 0.0001; //0.01
    float d = pyramid4(position, halfWidth1, halfDepth1, halfWidth2, halfDepth2, halfHeight);
    return d;
}

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 opS2( float d1, float d2 ) { return max(-d1,d2); }

vec2 opS_(vec2 d2, vec2 d1){return vec2(opS2(d1.x,d2.x),1.0);}

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


float h_=0.0;
float hindex_[3];
vec2 opUsc( vec2 d1, vec2 d2, float k ) {
    float h = clamp( 0.5 + 0.5*(d2.x-d1.x)/k, 0.0, 1.0 );
    //h_=clamp((d2.x-d1.x)/k, -1.0, 1.0 );
    //h_+=1.0; h_/=2.0;
    float mat=d2.y;
    if (h>0.5) mat=d1.y;
    h_=h;

    hindex_[int(currentindex)]=h_;
    useindex=mix(currentindex, totalindex, h_);
    totalindex=useindex;

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

float h1_,h2_,h3_;
vec2 map6( in vec3 pos ) /// intro sphere
{
float iTime_=iTime;//-(length(pos)*0.75);
//pos=(vec4(pos,1.0)*rotateZ(iTime_*1.005/2.0)).xyz;
///pos=(vec4(pos,1.0)*rotateY(iTime_*1.01)).xyz;
//pos=(vec4(pos,1.0)*rotateY(3.14/7.5)).xyz;
//pos=(vec4(pos,1.0)*rotateX(iTime_*1.002)).xyz;
//pos=(vec4(pos,1.0)*rotateX(3.14*2.0)).xyz;
//pos.y*=1.37;
//pos*=1.1;

float iTime2=iTime*1.15;
float iTime3=iTime*1.25;
float sf=spheresfactor;

    vec2 res=vec2(15.0, -100.0);
    //vec2 sphere=vec2(sdSphere(vec3(pos-vec3(0.0,0.0,2.5*abs(sin(iTime*2.0)))),0.6),3.0);
    float off=-1.25;
    vec2 sphere=vec2(sdSphere(vec3(pos-sf*vec3(1.75*(sin(iTime*2.7)),2.5*(sin(iTime*2.3)),off+4.5*abs(sin(iTime*2.0)))),0.6),4.0);
    vec2 sphere2=vec2(sdSphere(vec3(pos-sf*vec3(1.75*(sin(iTime2*2.7)),2.5*(sin(iTime2*2.3)),off+4.5*abs(sin(iTime2*2.0)))),0.6),4.0);
    vec2 sphere3=vec2(sdSphere(vec3(pos-sf*vec3(1.75*(sin(iTime3*2.7)),2.5*(sin(iTime3*2.3)),off+4.5*abs(sin(iTime3*2.0)))),0.6),4.0);
    //vec2 sphere=vec2(sdSphere(vec3(pos-vec3(0.0,0.0,4.0)),1.6),3.0);

/*
    float MAXH = 2.0;
    vec4 col=texture(iChannel0,vec2(pos.xy)/20.0*6.0+vec2(0.5,0.5));
    col2=col;
    float hhh=(col.r*65536.0+col.g*256.0+col.b)/(65536.0*256.0);// *200.0;
    float h=0.0-(hhh)*MAXH;
    vec2 terrain=vec2(pos.z-h,3.0);
*/
    float MAXH=65536.0;
    vec2 pozz=vec2(-pos.xy)/20.0*2.0+vec2(0.5,0.5);
    pozz.y/=4.0; pozz.y+=0.0*0.25;
    vec4 col=texture(iChannel0,pozz).rgba;
    col2=col;
    //vec4 col=col2.rgba;
    float hhh=(col.r*65536.0+col.g*256.0+col.b)/(65536.0*256.0);// *200.0;
    float MAXH2=0.0025*556.0*4.0 /1.2;
    float h=(1.0-((hhh)*MAXH))*MAXH2-2.0+12.0+19.5+1.25;
    vec2 terrain=vec2(pos.z-h,3.0);

    vec2 terrain2=vec2(0.0);
    if (seq==1)
{
    float MAXH=65536.0;
    vec2 pozz=vec2(-pos.xy)/20.0*2.0+vec2(0.5,0.5);
    pozz.y/=4.0; pozz.y+=1.0*0.25;
pozz.x+=0.25*sin(iTime*1.44);
    vec4 col=texture(iChannel0,pozz).rgba;
    col2=col;
    //vec4 col=col2.rgba;
    float hhh=(col.r*65536.0+col.g*256.0+col.b)/(65536.0*256.0);// *200.0;
    float MAXH2=0.0025*556.0*4.0 /1.2;
    float h=(1.0-((hhh)*MAXH))*MAXH2-2.0+12.0+19.5+1.25;
    vec2 terrain=vec2(pos.z-h,3.0);
    terrain2=terrain;
}
    //res=sphere;
    //res=terrain;
    float f=2.3;//1.75;
    if (seq==1) f*=0.269999891519547;
    //currentindex=0;
    if (seq!=1){
        f*=sf;
        res=opUsc(terrain,sphere,f);
        res=opUsc(res,sphere2,f);
        res=opUsc(res,sphere3,f);
    } else {
        res=opUsc(terrain,terrain2,f);
    }
    return res;
}


vec2 map2(in vec3 pos){
return map6(pos);
//pos.z-=0.5;
float iTime_=iTime;//-(length(pos)*0.75);
///pos=(vec4(pos,1.0)*rotateZ(iTime_*1.005/2.0)).xyz;
pos=(vec4(pos,1.0)*rotateY(iTime_*1.01)).xyz;
//pos=(vec4(pos,1.0)*rotateX(iTime_*1.002)).xyz;
pos=(vec4(pos,1.0)*rotateX(3.14/2.0)).xyz;
pos.y*=1.37;
pos*=1.1;
float d;
float db;
float d1,d2,d3,d4,d5,d6;
float f1,f2,f3,f4,f5,f6;
float fb1,fb2,fb3,fb4,fb5,fb6;

d1=sdBox(pos,vec3(0.7,0.1,0.7));
d2=sdBox(pos+vec3(-0.1,0,-0.4),vec3(0.4,0.3,0.1));
d3=sdBox(pos+vec3(-0.1,0,0),vec3(0.4,0.3,0.1));
d4=sdBox(pos+vec3(-0.1,0,0.4),vec3(0.4,0.3,0.1));
d5=sdBox(pos+vec3(0.4,0,0.2),vec3(0.1,0.3,0.1));
d6=sdBox(pos+vec3(0.4,0,-0.2),vec3(0.1,0.3,0.1));

//float sdf(in vec3 position, float halfWidth1, float halfDepth1, float halfWidth2, float halfDepth2, float halfHeight) { 
//f1=sdf(pos-vec3(0,.2,0),0.65,0.65,0.7,0.7,0.01);
const float he=0.7*2.0;
const float adj=-0.005;
const float adj2=0.02;
const float adj3=-0.04;
f1=sdf2(pos+vec3(0,+0.01-0.1-0.03*he-adj+adj2,0),0.7,0.7,0.67,0.67,0.03*he);
//f2=sdf(pos+vec3(-0.1,-0.1-0.04*he-adj,-0.4),0.4,0.1,0.475,0.15,0.04*he);
//f3=sdf(pos+vec3(-0.1,-0.1-0.04*he-adj,0.0),0.4,0.1,0.475,0.15,0.04*he);
//f4=sdf(pos+vec3(-0.1,-0.1-0.04*he-adj,0.4),0.4,0.1,0.475,0.15,0.04*he);
pos=(vec4(pos,1.0)*rotateZ(3.14)).xyz;
f2=sdf4(pos+vec3(0.275,+0.01-0.1-0.03*he-adj+adj3,-0.4),0.4,0.1,0.475,0.15,0.04*he);
f3=sdf4(pos+vec3(0.275,+0.01-0.1-0.03*he-adj+adj3,0.0),0.4,0.1,0.475,0.15,0.04*he);
f4=sdf4(pos+vec3(0.275,+0.01-0.1-0.03*he-adj+adj3,0.4),0.4,0.1,0.475,0.15,0.04*he);
//f5=sdf3(pos+vec3(-0.4,-0.1-0.04*he-adj,0.2),0.1,0.1,0.15,0.15,0.04*he);
//f6=sdf3(pos+vec3(-0.4,-0.1-0.04*he-adj,-0.2),0.1,0.1,0.15,0.15,0.04*he);
f5=sdf3(pos+vec3(-0.4,+0.01-0.1-0.03*he-adj+adj3,0.2),0.1,0.1,0.15,0.15,0.04*he);
f6=sdf3(pos+vec3(-0.4,+0.01-0.1-0.03*he-adj+adj3,-0.2),0.1,0.1,0.15,0.15,0.04*he);
/*
fb1=sdf(pos+vec3(0,-(-0.1-0.03*he),0),0.7,0.7,0.67,0.67,-0.03*he);
fb2=sdf(pos+vec3(-0.1,-(-0.1-0.04*he),-0.4),0.475,0.15,0.4,0.1,-0.04*he);
fb3=sdf(pos+vec3(-0.1,-(-0.1-0.04*he),0.0),0.4,0.1,0.475,0.15,0.04*he);
fb4=sdf(pos+vec3(-0.1,-(-0.1-0.04*he),0.4),0.4,0.1,0.475,0.15,0.04*he);
fb5=sdf(pos+vec3(0.4,-(-0.1-0.04*he),0.2),0.1,0.1,0.15,0.15,0.04*he);
fb6=sdf(pos+vec3(0.4,-(-0.1-0.04*he),-0.2),0.1,0.1,0.15,0.15,0.04*he);
*/
vec3 posb=pos;//(vec4(pos,1.0)*rotateZ(3.14)).xyz;

fb1=sdf2(posb+vec3(0,+0.01-0.1-0.03*he-adj+adj2,0),0.7,0.7,0.67,0.67,0.03*he);
//posb=(vec4(posb,1.0)*rotateZ(3.14)).xyz;
//fb2=sdf(posb+vec3(0.1,-0.1-0.04*he-adj,-0.4),0.4,0.1,0.475,0.15,0.04*he);
//fb3=sdf(posb+vec3(0.1,-0.1-0.04*he-adj,0.0),0.4,0.1,0.475,0.15,0.04*he);
//fb4=sdf(posb+vec3(0.1,-0.1-0.04*he-adj,0.4),0.4,0.1,0.475,0.15,0.04*he);
//fb5=sdf3(posb+vec3(0.4,-0.1-0.04*he-adj,0.2),0.1,0.1,0.15,0.15,0.04*he);
//fb6=sdf3(posb+vec3(0.4,-0.1-0.04*he-adj,-0.2),0.1,0.1,0.15,0.15,0.04*he);
posb=(vec4(posb,1.0)*rotateZ(3.14)).xyz;
fb2=sdf4(posb+vec3(0.1,+0.01-0.1-0.03*he-adj+adj3,-0.4),0.4,0.1,0.475,0.15,0.04*he);
fb3=sdf4(posb+vec3(0.1,+0.01-0.1-0.03*he-adj+adj3,0.0),0.4,0.1,0.475,0.15,0.04*he);
fb4=sdf4(posb+vec3(0.1,+0.01-0.1-0.03*he-adj+adj3,0.4),0.4,0.1,0.475,0.15,0.04*he);
fb5=sdf3(posb+vec3(0.4,+0.01-0.1-0.03*he-adj+adj3,0.2),0.1,0.1,0.15,0.15,0.04*he);
fb6=sdf3(posb+vec3(0.4,+0.01-0.1-0.03*he-adj+adj3,-0.2),0.1,0.1,0.15,0.15,0.04*he);

d=(opU(vec2(d1,1),vec2(f1,1))).x;
d=(opS(vec2(d,1),vec2(f2,1))).x;
d=(opS(vec2(d,1),vec2(f3,1))).x;
d=(opS(vec2(d,1),vec2(f4,1))).x;
d=(opS(vec2(d,1),vec2(f5,1))).x;
d=(opS(vec2(d,1),vec2(f6,1))).x;

db=fb1;
db=(opS(vec2(db,1),vec2(fb2,1))).x;
db=(opS(vec2(db,1),vec2(fb3,1))).x;
db=(opS(vec2(db,1),vec2(fb4,1))).x;
db=(opS(vec2(db,1),vec2(fb5,1))).x;
db=(opS(vec2(db,1),vec2(fb6,1))).x;

d=(opU(vec2(d,1),vec2(db,1))).x;

d=(opS(vec2(d,1),vec2(d2,1))).x;
d=(opS(vec2(d,1),vec2(d3,1))).x;
d=(opS(vec2(d,1),vec2(d4,1))).x;
d=(opS(vec2(d,1),vec2(d5,1))).x;
d=(opS(vec2(d,1),vec2(d6,1))).x;

return d;

//D(x,y,z) = max(|x|-a/2, |y|-b/2, |z|-c/2)
float a=1.0;
float b=3.0;
float c=2.0;
float x=pos.x+2.0;
float y=pos.y;
float z=pos.z-1.0;

//d=max(max(abs(x)-a/2.0,abs(y)-b/2.0),abs(z)-c/2.0);
//d=sdf(vec3(x,y,z));
return d;
}

float g(vec2 pos){
    //float MAXH = 5.1;
    //float h=texture(iChannel0,vec2(pos.xy)/20.0+vec2(0.5,0.5)).r;
    
    float MAXH=65536.0;
    vec2 pozz=vec2(-pos.xy)/20.0*2.0+vec2(0.5,0.5);
    pozz.y/=4.0; pozz.y+=0.0*0.25;
    vec4 col=texture(iChannel0,pozz).rgba;
    col2=col;
    //vec4 col=col2.rgba;
    /*
    float hhh=(col.r*65536.0+col.g*256.0+col.b)/(65536.0*256.0);// *200.0;
    float MAXH2=0.0025*556.0*4.0;
    float h=(1.0-((hhh)*MAXH))*MAXH2-2.0;
    */
    float hhh=(col.r*65536.0+col.g*256.0+col.b)/(65536.0*256.0);// *200.0;
    float MAXH2=0.0025*556.0*4.0 /1.2;
    float h=(1.0-((hhh)*MAXH))*MAXH2-2.0+12.0+19.5+1.25;

    return h;
}
// https://iquilezles.org/articles/normalsSDF
vec3 getNormal(vec2 p ) // for terrain g(p)
{
    float eps = 0.01*14.0; // or some other value
    vec2 h = vec2(eps,0);
    return normalize( vec3( g(p-h.xy) - g(p+h.xy),
                            2.0*h.x,
                            g(p-h.yx) - g(p+h.yx) ) );
}

vec3 calcNormal_( in vec3 pos )
{
    //return getNormal(pos.xz);
    float ep = 0.000001;
    vec2 e = vec2(1.0,-1.0)*0.5773*16.6;
    //vec2 e = vec2(1.0,-1.0)*1.7;
    return normalize( e.xyy*map2( pos + e.xyy*ep ).x + 
					  e.yyx*map2( pos + e.yyx*ep ).x + 
					  e.yxy*map2( pos + e.yxy*ep ).x + 
					  e.xxx*map2( pos + e.xxx*ep ).x );
}

float normaleps=0.005;
vec3 calcNormal( in vec3 pos )
{
    float normaleps_=normaleps/0.08;// /-0.4;
    vec3 eps = vec3( normaleps_, 0.0, 0.0 );

    vec3 nor = normalize(vec3(
        map2(pos+eps.xyy).x - map2(pos-eps.xyy).x,
        map2(pos+eps.yxy).x - map2(pos-eps.yxy).x,
        map2(pos+eps.yyx).x - map2(pos-eps.yyx).x ));
   
    return nor;

}

#define FAR 30.
float trace(vec3 ro, vec3 rd){
   
    float t = 0., d;
    
    for (int i = 0; i < 96; i++){

        d = map2(ro + rd*t);
        
        // Using the hacky "abs," trick, for more accuracy. 
        if(abs(d)<.001 || t>FAR) break;        
        
        t += d*.75;  // Using more accuracy, in the first pass.
    }
    
    return t;
}


float softShadow(vec3 ro, vec3 lp, float k){

    // More would be nicer. More is always nicer, but not really affordable... Not on my slow test 
    // machine, anyway.
    const int maxIterationsShad = 24; 
    
    vec3 rd = lp - ro; // Unnormalized direction ray.

    float shade = 1.;
    float dist = .002;    
    float end = max(length(rd), .001);
    float stepDist = end/float(maxIterationsShad);
    
    rd /= end;

    // Max shadow iterations - More iterations make nicer shadows, but slow things down. Obviously, 
    // the lowest number to give a decent shadow is the best one to choose. 
    for (int i = 0; i<maxIterationsShad; i++){

        float h = map(ro + rd*dist);
        //shade = min(shade, k*h/dist);
        shade = min(shade, smoothstep(0., 1., k*h/dist)); // Subtle difference. Thanks to IQ for this tidbit.
        // So many options here, and none are perfect: dist += min(h, .2), dist += clamp(h, .01, .2), 
        // clamp(h, .02, stepDist*2.), etc.
        dist += clamp(h, .02, .25);
        
        // Early exits from accumulative distance function calls tend to be a good thing.
        if (h<0. || dist>end) break; 
        //if (h<.001 || dist > end) break; // If you're prepared to put up with more artifacts.
    }

    // I've added 0.5 to the final shade value, which lightens the shadow a bit. It's a preference thing. 
    // Really dark shadows look too brutal to me.
    return min(max(shade, 0.) + .25, 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 )
void main()
{
totalindex=0.0;
    vec2 coos=gl_FragCoord.xy;
    vec2 p_ = (-iResolution.xy + 2.0*coos)/iResolution.y;

    //vec2 iResolution = vec2(1920,1080);

    //vec2 fragCoord=gl_FragCoord.xy;
    //vec2 uv = fragCoord/iResolution.xy;
	//vec2 p = uv*2.0-1.0;
	//p.x*=(iResolution.x/iResolution.y);
	//vec4 col = vec4(0.05);

    //vec3 ro = vec3(0.0,0.0,-1.0);
    //vec3 rd = normalize(vec3(p,0.0)-ro);

    //vec3 rp = ro;

    //const float fl = 2.5;

    vec3 ro_ = rayorigin;
    vec3 ta = raydirection;
    
    mat3 ca = setCamera(ro_,ta,0.0);

    float fov_=fov;
    vec3 rd_ = ca * normalize(vec3(p_.x,p_.y,fov_ ));















    //doff=testvalue;

    vec3 tot = vec3(0.0);
    
    #if AA>1
    for( int m=0; m<AA; m++ )
    for( int n=0; n<AA; n++ )
    {
        // pixel coordinates
        vec2 o = vec2(float(m),float(n)) / float(AA) - 0.5;
        vec2 p = (-iResolution.xy + 2.0*(gl_FragCoord+o))/iResolution.y;
        #else    
        vec2 p = (-iResolution.xy + 2.0*gl_FragCoord)/iResolution.y;
        #endif
 
        vec3 ro = ro_;// vec3(0.0+2.0*sin(iTime*2.9),1.35,6.0);
        vec3 rd = rd_;//normalize(vec3(p-vec2(0.0,0.5),-2.0));
        //ro = vec3(0.0+2.0*sin(iTime*2.9),1.35,6.0+2.0);
        //rd = normalize(vec3(p-vec2(0.0,0.5),-2.0));

        
float t;
if (seq==1){
int steps_;
const float precision_=0.0001;
const float tmin =     0.00001;
    steps_=90; //e logo twist
    vec2 res = vec2(-1.0,-1.0);
    {
        t = tmin+1.0/10000000.0;
        ///for( int i=0; i<70 ; i++ )
        for( int i=0; i<steps_ ; i++ )
        {
            float h = map2( ro+rd*t );
            ///if( abs(h.x)<(0.0001*t) )
            if( abs(h)<((precision_)*t)||t>FAR )
            {
                 //res = vec2(t,h.y);
                 break;
            }
            if (seq==1)
                t += h*0.85/24.22;
        }
    }
}
/*
    float t = 0., d;
    for (int i = 0; i < 96; i++){
        d = map2(ro + rd*t);
        // Using the hacky "abs," trick, for more accuracy. 
        if(abs(d)<.001 || t>FAR) break;        
        t += d*.75;  // Using more accuracy, in the first pass.
    }
*/          

if (seq==0){
    t = 0.;
    vec2 d;
    for (int i = 0; i < 96; i++){
        d = map2(ro + rd*t+vec3(0,0,0));
        // Using the hacky "abs," trick, for more accuracy. 
        ///if(abs(d)<.001 || t>FAR) break;        
        if(abs(d.x)<.00001 || t>FAR) break;        
        t += d.x*.25;  // Using more accuracy, in the first pass.
    }
}
    vec3 col = vec3(0.0);

        if(t<10.0)
        {
            vec3 pos = ro + rd*t+vec3(0,0,0);
            /*
            vec3 nor = calcNormal(pos);
            float dif = clamp(dot(nor,vec3(10.5703,0.6,0.5)*0.5),0.0,1.0);
            col = vec3(dif);//vec3(0.025,0.06,0.18) + dif*vec3(1.0,0.9,0.8);
            */

        vec3 e=rd;
        //vec3 pos = ro + t*rd;
        //vec3 n=calcNormal(pos)+vec3(-1,-0.2,0.5);
        //vec3 n1=calcNormal(pos);//+vec3(-0.25,-0.1,0.95);
        //vec3 n2=getNormal(pos.xy);//+vec3(-0.25,-0.1,0.95);
        //vec3 n=normalize(n1+n2);
        /*
        vec3 n;
        if (t==4.0) //4.0=spheres 3.0=terrain
        {
            n=calcNormal(pos);//+vec3(-0.25,-0.1,0.95);
        } else {
            n=getNormal(pos.xy);//+vec3(-0.25,-0.1,0.95);
        }
        */
        //vec3 n1=getNormal(pos.xy);//+vec3(-0.25,-0.1,0.95);
        vec3 n2=calcNormal(pos);
        vec3 n;
        //tot=mix(vec3(1,0,0),vec3(1,1,0),h_);
        //if (h_<0.5) n=n2; else n=n1;
        //n=mix(n2,n1,h_*0.03);
        n=n2;
        //if (d.y!=4.0) n=n1;
        vec3 r = reflect(e,n);
        float m = 2.0 * sqrt( pow( r.x, 2. ) + pow( r.y, 2. ) + pow( r.z, 2. ) );
        //float m = 2.0 * sqrt( r.x*r.x+r.y*r.y+ r.z*r.z);
        m=clamp(m,0.02,0.98)*5.6;
        vec2 vN = r.xy / m + .5;
        vN=clamp(vN,1.0/256.0*2.0,1.0-1.0/256.0*2.0);
        vec3 base = texture(iChannel1,vN).rgb;
        float pw=3.5;
        base.r = pow(base.r,pw);
        base.g = pow(base.g,pw);
        base.b = pow(base.b,pw);
        col = base/1.4/2.0;

        /*
        vec3  lig = normalize( vec3(-0.4, 0.7, -0.6) );
        float amb = clamp( 0.5+0.5*n.y, 0.0, 1.0 );
        float dif = clamp( dot( n, lig ), 0.0, 1.0 );
        float spe = pow(clamp( dot( r, lig ), 0.0, 1.0 ),16.0/1.5);
        base=amb+dif+spe;
        base/=7.4;
        col = base/1.4/2.0;
        */

        vec2 pozz=vec2(-pos.xy)/20.0*2.0+vec2(0.5,0.5);
        //poz=clamp(poz,0.0001,0.999);
        pozz.y/=4.0; pozz.y+=2.0*0.25;
        vec4 coltex=texture(iChannel0,pozz).rgba;
        if (seq==1){
            vec2 pozz=vec2(-pos.xy)/20.0*2.0+vec2(0.5,0.5);
            //poz=clamp(poz,0.0001,0.999);
            pozz.y/=4.0; pozz.y+=3.0*0.25;
pozz.x+=0.25*sin(iTime*1.44);
            vec4 coltex2=texture(iChannel0,pozz).rgba;
            coltex=mix(coltex,coltex2,1.0-h_);
        }
        col=coltex.rgb;
        col+=base.rgb/3.4;
        vec3 coldark=col*base.rgb*21.4;
        col=mix(col,coldark,0.53*1.2);
        //col=vec3(1,1,0);
        //col=vec3(1,0,0);
        
        //vec3 lp = ro + vec3(0, 1, -.5);
        /*
        vec3 lp = ro + vec3(-0.5, 1, -.5);
        float shadow=softShadow(ro,lp,2.6);
        col *= shadow;
        col *= shadow;
        col *= shadow;
        col *= shadow;
        */
    vec3 col3;
    /*
    float MAXH=65536.0;
    //col=texture(iChannel0,vec2(pos.xy)/20.0*6.0+vec2(0.5,0.5)).rgb;
    col3=col2.rgb;
    float hhh=(col2.r*65536.0+col2.g*256.0+col2.b)/(65536.0*256.0);// *200.0;
    float h=1.0-((hhh)*MAXH);
*/
/*
    float MAXH=65536.0;
    vec3 col=texture(iChannel0,vec2(-pos.xy)/20.0*2.0+vec2(0.5,0.5)).rgb;
    col3=col2.rgb;
    float hhh=(col.r*65536.0+col.g*256.0+col.b)/(65536.0*256.0);// *200.0;
    float MAXH2=0.0025*556.0*4.0 /1.2;
    float h=(1.0-((hhh)*MAXH))*MAXH2-2.0+12.0+19.5+1.25;

    col3=vec3(h);
    col*=col3*2.0;
  */      
//if (t==4.0) col=vec3(1,0,0);   
        ///col=base;

            }

        //col = sqrt( clamp(col,0.0,1.0) );




	    tot += col;
    #if AA>1
    }
    tot /= float(AA*AA);
    #endif
    float alpha;
    if (tot==vec3(0,0,0)) alpha=0.0; else alpha = 1.0;
	gl_FragColor = vec4( tot, alpha );
}
