#define PI 3.1415926535897932384626433832795
#define DEG2RAD (2.0*PI/360.0)

in vec2 texCoord;

//uniform sampler2D colorMap;
uniform samplerCube envMap;

uniform vec4 glColor;

uniform vec3 camPos;
uniform vec3 camView;
uniform vec3 camUp;

uniform float testvalue;

uniform mat4 camMat;

/*void main (void)
{
	gl_FragColor = texture2D(colorMap, texCoord)*glColor;
}
*/
// Star Nest by Pablo Roman Andrioli
// License: MIT

/*
#define iterations 17
#define formuparam 0.53

#define volsteps 20
#define stepsize 0.1

#define zoom   0.800
#define tile   0.850
#define speed  0.000 

#define brightness 0.0015
#define darkmatter 0.300
#define distfading 0.730
#define saturation 0.850

void main()
{
	//get coords and direction
	//vec2 uv=fragCoord.xy/iResolution.xy-.5;
	vec2 uv=texCoord-.5;
	uv.y*=1080.0/1920.0;
	vec3 dir=vec3(uv*zoom,1.);
	float time=0.25; // iTime*speed+.25;
	
	//mouse rotation
	float a1=0.5;//+iMouse.x/iResolution.x*2.;
	float a2=0.8;//+iMouse.y/iResolution.y*2.;
	mat2 rot1=mat2(cos(a1),sin(a1),-sin(a1),cos(a1));
	mat2 rot2=mat2(cos(a2),sin(a2),-sin(a2),cos(a2));
	dir.xz*=rot1;
	dir.xy*=rot2;
	vec3 from=vec3(1.,.5,0.5);
	from+=vec3(time*2.,time,-2.);
	from.xz*=rot1;
	from.xy*=rot2;
	
	from = vec3(0.0);//camPos;
	//dir = normalize(camView-camPos);

	//volumetric rendering
	float s=0.1,fade=1.;
	vec3 v=vec3(0.);
	for (int r=0; r<volsteps; r++) {
		vec3 p=from+s*dir*.5;
		p = abs(vec3(tile)-mod(p,vec3(tile*2.))); // tiling fold
		float pa,a=pa=0.;
		for (int i=0; i<iterations; i++) { 
			p=abs(p)/dot(p,p)-formuparam; // the magic formula
			a+=abs(length(p)-pa); // absolute sum of average change
			pa=length(p);
		}
		float dm=max(0.,darkmatter-a*a*.001); //dark matter
		a*=a*a; // add contrast
		if (r>6) fade*=1.-dm; // dark matter, don't render near
		//v+=vec3(dm,dm*.5,0.);
		v+=fade;
		v+=vec3(s,s*s,s*s*s*s)*a*brightness*fade; // coloring based on distance
		fade*=distfading; // distance fading
		s+=stepsize;
	}
	v=mix(vec3(length(v)),v,saturation); //color adjust
	vec4 fragColor = vec4(v*.01,1.);	
	//fragColor=vec4(1,0,1,0.5);
	gl_FragColor = fragColor;//texture2D(colorMap, texCoord)*glColor;
}
*/


// Star Nest by Pablo Román Andrioli
// copied from https://www.shadertoy.com/view/XlfGRj
//
// This content is under the MIT License.
// (copied for API availability + VR)
/*
#define iterations 17
#define formuparam 0.53

#define volsteps 20
#define stepsize 0.1

#define zoom   0.800
#define tile   0.850
#define speed  0.010 

#define brightness 0.0015
#define darkmatter 0.300
#define distfading 0.730
#define saturation 0.850

void mainVR(in vec3 ro, in vec3 rd )
{
	//get coords and direction
	//vec3 dir=normalize(camView-camPos)/testvalue/1000.0;//rd;
	//vec3 from=vec3(0.0)/testvalue/1000.0;//ro;
	vec3 dir=rd;
	vec3 from=ro;
	
	//volumetric rendering
	float s=0.1,fade=1.;
	vec3 v=vec3(0.);
	for (int r=0; r<volsteps; r++) {
		vec3 p=from+s*dir*.5;
		p = abs(vec3(tile)-mod(p,vec3(tile*2.))); // tiling fold
		float pa,a=pa=0.;
		for (int i=0; i<iterations; i++) { 
			p=abs(p)/dot(p,p)-formuparam; // the magic formula
			a+=abs(length(p)-pa); // absolute sum of average change
			pa=length(p);
		}
		float dm=max(0.,darkmatter-a*a*.001); //dark matter
		a*=a*a; // add contrast
		if (r>6) fade*=1.-dm; // dark matter, don't render near
		//v+=vec3(dm,dm*.5,0.);
		v+=fade;
		v+=vec3(s,s*s,s*s*s*s)*a*brightness*fade; // coloring based on distance
		fade*=distfading; // distance fading
		s+=stepsize;
	}
	v=mix(vec3(length(v)),v,saturation); //color adjust
	vec4 fragColor = vec4(v*.01,1.);	
	gl_FragColor = fragColor;
}

vec2 iResolution=vec2(1920.0,1080.0);
void main_()
{
	//get coords and direction
	vec2 uv=texCoord;//fragCoord.xy/iResolution.xy-.5;
	uv.y*=iResolution.y/iResolution.x;
	vec3 dir=vec3(uv*zoom,1.);
	float time=0.0;//.25;//iTime*speed+.25;

	//mouse rotation
	float a1=.5;//+iMouse.x/iResolution.x*2.;
	float a2=.8;//+iMouse.y/iResolution.y*2.;
	mat2 rot1=mat2(cos(a1),sin(a1),-sin(a1),cos(a1));
	mat2 rot2=mat2(cos(a2),sin(a2),-sin(a2),cos(a2));
	dir.xz*=rot1;
	dir.xy*=rot2;
	//vec3 from=vec3(10000,1000,100);
	vec3 from=vec3(0,0,0);
dir=from+vec3(uv*zoom/testvalue,1.)+normalize(camView-camPos);
	//vec3 from=vec3(1.,.5,0.5);
	//from+=vec3(time*2.,time,-2.);
	//from.xz*=rot1;
	//from.xy*=rot2;
	
	mainVR(from, dir);	
}
*/

uniform float fovDegrees;//=60.0;
/*
float vecAngle(float x1, float y1, float x2, float y2){
float vec1x=x1;
float vec1y=y1;
float vec2x=0.0;
float vec2y=1.0;
float r1=sqrt(vec1x*vec1x+vec1y*vec1y);
float r2=sqrt(vec2x*vec2x+vec2y*vec2y);
vec1x/=r1;
vec1y/=r1;
vec2x/=r2;
vec2y/=r2;
float vec1xabs=abs(vec1x);
float vec1yabs=abs(vec1y);

    float dot_ = (vec1xabs * vec2x) + (vec1yabs * vec2y);
    // dot is 0.0 when perpendicular, 1.0 when parallel
    float angle = 180.0-90.0+dot_*90.0;//180.0f
    if (vec1y<0.0) angle=180.0-angle;
    if (vec1x<0.0) angle=-angle;

    vec1x=x2;
    vec1y=y2;
    vec2x=0.0;
    vec2y=1.0;
    r1=sqrt(vec1x*vec1x+vec1y*vec1y);
    r2=sqrt(vec2x*vec2x+vec2y*vec2y);
    vec1x/=r1;
    vec1y/=r1;
    vec2x/=r2;
    vec2y/=r2;
    vec1xabs=abs(vec1x);
    vec1yabs=abs(vec1y);

    dot_ = (vec1xabs * vec2x) + (vec1yabs * vec2y);
    // dot is 0.0 when perpendicular, 1.0 when parallel
    float angle2 = 180.0-90.0+dot_*90.0;//180.0f
    if (vec1y<0.0) angle2=180.0-angle2;
    if (vec1x<0.0) angle2=-angle2;

    float res = angle-angle2;
    return res*DEG2RAD;
}


vec3 rotateXY(vec3 p, vec2 angle) {
    vec2 c = cos(angle), s = sin(angle);
    p = vec3(p.x, c.x*p.y + s.x*p.z, -s.x*p.y + c.x*p.z);
    return vec3(c.y*p.x + s.y*p.z, p.y, -s.y*p.x + c.y*p.z);
}
*/
void main(){
/*
	float hfovDegrees=90.0;//fovDegrees;
	float vfovDegrees=90.0/(1920.0/1080.0);;//fovDegrees/(1920.0/1080.0);
	
//float hfovDegrees = 120.0;
//float vfovDegrees = 60.0;

	vec2 uv = texCoord*2.0-1.0;
    vec3 camDir = normalize(vec3(uv.xy * vec2(tan(0.5 * hfovDegrees * DEG2RAD), tan(0.5 * vfovDegrees * DEG2RAD)), 1.0));
	//vec4 camDir_ = vec4(camDir,1.0)*camMat;

    //vec3 camRot = vec3( ((iMouse.xy / iResolution.xy) - 0.5) * vec2(2.0 * PI,  PI), 0.);
	vec3 camRot;
	vec3 c=normalize(camView-camPos);
	
	//camRot.x=dot(vec2(c.y,c.z),vec2(1,0))/4.0; //vertical movement
	//camRot.y=dot(normalize(vec2(c.x,c.z)),vec2(0,1)); //horizontal movement
	//camRot = vec3(vec2(camRot.xy/2.0) * vec2(2.0 * PI,  PI), 0.);
	


	//camRot.x=-vecAngle(c.y, c.z, 0.0, 1.0);//vertical movement
	//camRot.y=vecAngle(c.x, c.z, 0.0, 1.0);//horizontal movement
	//^^ semi working version
	camRot.x=-vecAngle(c.y, c.z, 0.0, 1.0);//vertical movement
	camRot.y=vecAngle(c.x, c.z, 0.0, 1.0);//horizontal movement



	//camRot = vec3(vec2(camRot.xy/2.0) * vec2(2.0 * PI,  PI), 0.);

	vec3 rd = normalize(rotateXY(camDir, camRot.xy));
	//vec3 rd = camDir_.xyz;
	//vec3 rd = camDir_.xyz+normalize(camView-camPos);
    //vec3 rd = normalize(rotateXY(camDir, camRot.yx));

	vec2 texCoord_ = vec2(atan(rd.z, rd.x) + PI, acos(-rd.y)) / vec2(2.0 * PI, PI);
*/	
	/*
float hfovDegrees = 90.0;
float vfovDegrees = 90.0/(1920.0/1080.0);

//place 0,0 in center from -1 to 1 ndc
    vec2 uv = texCoord.xy * 2. - 1.;
	
    //to spherical
    vec3 camDir = normalize(vec3(uv.xy * vec2(tan(0.5 * hfovDegrees * DEG2RAD), tan(0.5 * vfovDegrees * DEG2RAD)), 1.0));
    
    //camRot is angle vec in rad
    //vec3 camRot = vec3( ((iMouse.xy / iResolution.xy) - 0.5) * vec2(2.0 * PI,  PI), 0.);
    
    //rotate
    vec3 rd = camDir;// normalize(rotateXY(camDir, camRot.yx));
    
    //radial azmuth polar
    vec2 texCoord = vec2(atan(rd.z, rd.x) + PI, acos(-rd.y)) / vec2(2.0 * PI, PI);

    //fragColor = texture(iChannel0, texCoord);	
	*/
	//gl_FragColor = texture2D(colorMap, clamp(texCoord_,1.0/512.0,1.0-1.0/512.0));


///float hfovDegrees = 90.0;
///float vfovDegrees = 90.0*(1920.0/1080.0);
  vec2 uv = (texCoord.xy * 2. - 1.)/vec2(1.0,1920.0/1080.0);// *vec2(1080.0/1920.0,1.0);// *vec2(1920.0/1080.0,1.0);
  uv.y=-uv.y;
  vec3 ro = normalize(camView-camPos);
  //ro.y*=-1.0;
  vec3 z = normalize(ro);
  //vec3 x = normalize(cross(vec3(0.0, 1.0, 0.0), z));
  vec3 x = normalize(cross(camUp, z));
  vec3 rd = mat3(x, cross(z, x), z) * vec3(uv, -1.0);

	gl_FragColor = texture(envMap, rd);
}
