#version 330 core

// volcano frag shader with fog

uniform float mytime;
uniform vec2 resolution;

#define OCTAVES 5

// Squish and strech the tunnel
#define STRETCH 10.0
#define SQUISH 1.0

// Everthing should be a tunnel :)
// From http://glsl.heroku.com/e#11554.0

float rand(vec2 n) { 
	return fract(sin(dot(n, vec2(13, 5))) * 43758.5453);
}

float noise(vec2 n) {
	const vec2 d = vec2(0.0, 1.0);
	vec2 b = floor(n), f = smoothstep(vec2(0.0), vec2(1.0), fract(n));
	return mix(mix(rand(b), rand(b + d.yx), f.x), 
		mix(rand(b + d.xy), rand(b + d.yy), f.x), f.y);
}

float fbm(vec2 n) {
	float total = 0.0, amplitude = 1.0;
	for (int i = 0; i < OCTAVES; i++) {
		total += noise(n) * amplitude;
		n += n;
		amplitude *= 0.5;
	}
	return total;
}

vec3 tex(vec2 pos) {
	const vec3 c1 = vec3(.1,0,0);
	const vec3 c2 = vec3(.7,0,0);
	const vec3 c3 = vec3(.2,0,0);
	const vec3 c4 = vec3(1,.9,0);
	const vec3 c5 = vec3(.1);
	const vec3 c6 = vec3(.9);
	vec2 p = pos;
	float q = fbm(p - mytime * -0.1);
	vec2 r = 
		vec2(fbm(p + q + mytime - p.x - p.y), 
			fbm(p + q + mytime));
	vec3 c = 
		mix(c1, c2, fbm(p + r)) + 
			mix(c3, c4, r.x) - mix(c5, c6, r.y);
	return c;
}

in vec2 UV;

in vec4 aPos;

out vec4 color;




const float fStart=0.0;
const float fEnd=20.0;

float getFogFactor(float fFogCoord)
{
	float fResult = 0.0;
	fResult = (fEnd-fFogCoord)/(fEnd-fStart);
	fResult = 1.0-clamp(fResult, 0.0, 1.0);
	
	return sqrt(fResult);
}


//////// insert 20dec17 begin /////////////////////////////////////
uniform int fogcolr=2; // 0=>noFog, 1=>white, 2=>brown, 3=>purple, 4=>gray
uniform int foglevl=1; // 0=>noFog, 1=>Fog, 2=>heavy

const vec4 vFogColor=vec4(0.8,0.8,0.8,1.0); //normal white
const vec4 vDfogColor=vec4(0.3,0.3,0.3,1.0); //gray
const vec4 vSootColor=vec4(50.0/255,30.0/255,10.0/255,1.0); // brown
const vec4 vMystColor=vec4(0.7,0.5,0.7,1.0); // purple
//////// insert 20dec17 end /////////////////////////////////////




// halfspace discard uniforms: ////////////////////////////////////

uniform int iside=0; // 0=>noDiscard

uniform vec3 eyePos;

uniform vec3  port1;
uniform vec3  port2;

// halfspace discard uniforms end /////////////////////////////////


const float onepi = 3.14159;
const float twopi = 2.0*onepi;



void main(void) {
    vec2 p = (UV.xy - vec2(.5)) * vec2(resolution.x/resolution.y, 1.);

    float r = length(p); //original
    float a = atan(p.y, p.x);

    vec2 uv = vec2(sin(a), cos(a))
	 	/pow(r, 0.5+.0625*sin(0.1*mytime)); //best 17jan17
    
    vec3 col = tex(uv);
    //color = vec4(col*r,1); //original (blackest near center)
    color = vec4(col/r,1); //interesting bestSoFar
    //color = vec4(col*r*r,1);
    //color = vec4(col*(1.-r),1); //best (blackest near edge) 17jan17

	vec4 vEyePos = vec4( aPos.xyz-eyePos, 1.0 );

	if( foglevl>0 ) {

		float dist2 = pow(vEyePos.x,2) + pow(vEyePos.z,2);
		float dist = sqrt(dist2);

		if( fogcolr==4 )
			color = mix(color,  vDfogColor, getFogFactor(dist)); //gray
		else if( fogcolr==3 )
			color = mix(color, vMystColor, getFogFactor(dist)); //purple
		else if( fogcolr==2 )
			color = mix(color, vSootColor, getFogFactor(dist)); //brown
		else if( fogcolr==1 )
			color = mix(color,  vFogColor, getFogFactor(dist)); //white

	}



	// fastrgv:  my halfspace-discard addendum:
	vec3 cP1 =  port1 - eyePos;
	vec3 cP2 =  port2 - eyePos;
	vec3 vP0 = aPos.xyz - eyePos;
	float PRAD = 0.80; // larger, but synched with adagate.adb
	float FOV1 = atan(PRAD/length(cP1));
	float FOV2 = atan(PRAD/length(cP2));
	vec3 nP1 = normalize(cP1);
	vec3 nP2 = normalize(cP2);
	vec3 nP0 = normalize(vP0);
	float d1=dot(nP0,nP1);
	float d2=dot(nP0,nP2);
	float a1=acos(d1);
	float a2=acos(d2);
	if( iside != 0 ) {
		if( (iside==2) && (a1>FOV1) ) discard;
		if( (iside==1) && (a2>FOV2) ) discard;
	}

}

