// __multiversion__
// This signals the loading code to prepend either #version 100 or #version 300 es as apropriate.

#if __VERSION__ >= 300
	// version 300 code
	#define varying in
	#define texture2D texture
	out vec4 FragColor;
	#define gl_FragColor FragColor
	#define texture2D texture
#else
	// version 100 code
#endif

#include "PSutil.h"

varying vec4 color;
varying vec4 fogcolor;
varying float fogintense;
varying highp vec3 position;

uniform highp float TIME;
uniform vec2 FOG_CONTROL;

//=*=clouds=*=//
highp vec3 mod289(highp vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
highp vec2 mod289(highp vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
highp vec3 permute(highp vec3 x) { return mod289(x*(x * 34.0 + 1.0)); }

highp float snoise(highp vec2 v) {
	const highp vec4 C = vec4(
		0.211324865405187,   // (3.0-sqrt(3.0))/6.0
		0.366025403784439,   // 0.5*(sqrt(3.0)-1.0)
		-0.577350269189626,  // -1.0 + 2.0 * C.x
		0.024390243902439);  // 1.0 / 41.0

	highp vec2 i  = floor(v + dot(v, C.yy));
	highp vec2 x0 = v -   i + dot(i, C.xx);
	highp vec2 i1  = x0.x > x0.y ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
	highp vec4 x12 = x0.xyxy + C.xxzz;
	x12.xy -= i1;

	i = mod289(i);
	highp vec3 p =permute(permute(i.y + vec3(0.0, i1.y, 1.0)) + i.x + vec3(0.0, i1.x, 1.0));

	highp vec3 m = max(0.5 - vec3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), 0.0);
	m = m*m;
	m = m*m;

	highp vec3 x  = 2.0 * fract(p * C.www) - 1.0;
	highp vec3 h  = abs(x) - 0.5;
	highp vec3 ox = round(x);
	highp vec3 a0 = x - ox;

	m *= inversesqrt(a0 * a0 + h * h);
	highp vec3 g;
	g.x  = a0.x  * x0.x   + h.x  * x0.y;
	g.yz = a0.yz * x12.xz + h.yz * x12.yw;
	return 130.0 * dot(m, g);
}

highp float fBM(const int octaves, const float lowerBound, const float upperBound, highp vec2 st) {
	highp float value = 0.0;
	highp float amplitude = 0.5;
	for (int i = 0; i < octaves; i++) {
		value += amplitude * (snoise(st) * 0.5 + 0.5);
		if (value >= upperBound) {break;}
		else if (value + amplitude <= lowerBound) {break;}
		st        *= 2.0;
		st.x      -=TIME/256.0*float(i+1);
		amplitude *= 0.5;
	}
	return smoothstep(lowerBound, upperBound, value);
}
//=*=end clouds=*=//

//=*=aurora=*=//
float tri(float x){return clamp(abs(fract(x)-.5),0.001,0.52);}

float triNoise2d(vec2 p)
{
	float z=1.8;
	float z2=2.5;
	float rz = 0.0;
	p *= 0.55*(p.x*0.2);
	vec2 bp = p;
	for (float i=0.0; i<5.0; i++ )
	{
		vec2 dg = (bp*1.85)*0.75;
		dg *= 6.0;
		p -= dg/z2;
		bp *= 1.3;
		z2 *= 0.45;
		z *= 0.42;
		p *= 1.21 + (rz-1.0)*0.02;
		rz += tri(p.x+tri(p.y))*z;
		p*= -1.0;
	}
	return clamp(1.0/pow(rz*29.0, 1.3),0.0,0.55);
}

vec4 aurora(vec3 rd)
{
	vec4 col = vec4(0.0);
	float of = 0.006*fract(sin(0.96));
	float b = rd.y*2.0+0.4;
	vec3 c = vec3(sin(TIME*0.01)*0.5+1.5-vec3(2.15,-0.5,1.2));
	for(float i=0.0;i<AURORA_RP;i++)
	{
		float pt = (0.8+pow(i+1.0,AURORA_DS)*0.002)/b;
		vec3 bpos = vec3(0.0,0.0,-6.5) + (pt-of)*rd;
		float rzt = triNoise2d(bpos.zx);
		vec4 col2 = vec4(vec3((sin(c+i*AURORA_CC)*0.5+0.5)*rzt),rzt);
		col += col2*0.5*exp2(-i*0.065-2.5)*smoothstep(0.0,5.0,i);
	}
	return col*(clamp(rd.y*15.0+0.4,0.0,1.0))*AURORA_CS;
}
//=*=end aurora=*=//

void main()
{
vec4 _color = color;
float weather = smoothstep(0.8,1.0,FOG_CONTROL.y);
float ss = min(smoothstep(0.3,0.4,_color.b),smoothstep(0.5,0.4,_color.b));
_color = mix(_color,fogcolor,0.33);

#ifdef RENDERAURORA
	float night = smoothstep(0.25,0.05,color.b);
	if(night*weather>0.0){
		vec4 aur = vec4(smoothstep(0.0,1.5,aurora(normalize(vec3(position.x*4.0,1.0,position.z*4.0)))));
		_color.rgb = mix(_color.rgb,aur.rgb+vec3(0.0,0.05,0.1),night*weather);
	}
#endif

#ifdef RENDERCLOUDS
	vec3 cc = mix(CLOUDS_NC,CLOUDS_DC,smoothstep(0.2,0.3,fogcolor.g));
	float lb = mix(0.25,0.5,weather);
	float cm = fBM(RENDERCLOUDS,lb,0.9,position.xz*2.5-TIME*0.001);
	_color.rgb = mix(_color.rgb, cc, cm);
	_color.rgb = mix(_color.rgb, mix(color.rgb*0.4+0.25,CLOUDS_SC,ss), clamp(cm-0.5,0.0,1.0));
#endif

gl_FragColor = mix(_color, fogcolor, fogintense);
}
