//////////////////////////////////////////////////////////////////////////////
//    ##      #####   ######   ######     ##     ####     #######  ##  ##   //
//   ####    ##   ##  # ## #    ##  ##   ####     ##       ##   #  ##  ##   //
//  ##  ##   #          ##      ##  ##  ##  ##    ##       ## #     ####    //
//  ##  ##    #####     ##      #####   ##  ##    ##       ####      ##     //
//  ######        ##    ##      ## ##   ######    ##   #   ## #     ####    //
//  ##  ##   ##   ##    ##      ##  ##  ##  ##    ##  ##   ##   #  ##  ##   //
//  ##  ##    #####    ####    #### ##  ##  ##   #######  #######  ##  ##   //
//--------------------------------------------------------------------------//
//--------------------------------------------------------------------------//
//      #####   ##   ##    ##     #####    #######  ######    #####         //
//     ##   ##  ##   ##   ####     ## ##    ##   #   ##  ##  ##   ##        //
//     #        ##   ##  ##  ##    ##  ##   ## #     ##  ##  #              //
//      #####   #######  ##  ##    ##  ##   ####     #####    #####         //
//          ##  ##   ##  ######    ##  ##   ## #     ## ##        ##        //
//          ##  ##   ##  ######    ##  ##   ## #     ## ##        ##        //
//     ##   ##  ##   ##  ##  ##    ## ##    ##   #   ##  ##  ##   ##        //
//      #####   ##   ##  ##  ##   #####    #######  #### ##   #####         //
/////(BSL Shaders Edit)//////////////////////////////////////By LexBoosT//////

//Settings//
#include "/lib/settings.glsl"
#include "/lib/util/dither.glsl"

//Varyings//
varying vec2 texCoord;

varying vec3 upVec, sunVec;

varying vec4 color;

#ifdef DISTORTION
varying vec3 vUV;
varying vec2 vUVDot;
#endif

//Fragment Shader///////////////////////////////////////////////////////////////////////////////////
#ifdef FSH

//Uniforms//
uniform sampler2D noisetex;
uniform sampler2D colortex1;

#ifdef HYPER_SPEED
uniform sampler2D colortex4;
uniform float effectStrength;
uniform sampler2D depthtex1;
#endif


uniform float aspectRatio;
uniform float frameTimeCounter;
uniform float viewWidth, viewHeight;
uniform float blindness;

#ifdef DAMAGE_EFFECT
uniform float touchmybody;
#endif

uniform float rainStrength;
uniform float rainStrengthS;
uniform float rainStrengthS2;

#if MC_VERSION <= 11701
uniform float biomeHasRainSmooth;
uniform float biomeisNotColdSmooth;
#endif
#if MC_VERSION >= 11800
uniform float biomeHasRainSmooth2;
uniform float biomeisNotColdSmooth2;
#endif

#if defined (OVERWORLD) && defined DESERT_REFRACT
	#if MC_VERSION <= 11701
	uniform float biomeHasHeatSmooth;
	#endif
	#if MC_VERSION >= 11800
	uniform float biomeHasHeatSmooth02;
	#endif
#endif

#if defined (OVERWORLD) && defined MESA_REFRACT
	#if MC_VERSION <= 11701
	uniform float biomeHasHeatSmooth2;
	#endif
	#if MC_VERSION >= 11800
	uniform float biomeHasHeatSmooth22;
	#endif
#endif

#if defined (NETHER) && defined NETHER_REFRACT
	#if MC_VERSION <= 11701
	uniform float biomeHasHeatSmooth3;
	#endif
	#if MC_VERSION >= 11800
	uniform float biomeHasHeatSmooth32;
	#endif
#endif

uniform mat4 gbufferProjectionInverse;

uniform int worldTime;

#if defined (OVERWORLD) && defined ARC_EN_CIEL
uniform sampler2D depthtex0;
uniform float wetness;
uniform vec3 sunPosition;
vec3 sunPosNorm=normalize(sunPosition);
#endif

#if defined VISEUR || defined MODE_RAGE
uniform int heldItemId;
#endif

uniform ivec2 eyeBrightnessSmooth;

uniform int isEyeInWater;

//Optifine Constants//
/*
const int colortex0Format = R11F_G11F_B10F; //main scene
const int colortex1Format = RGB8; //raw translucent, bloom, final scene
const int colortex2Format = RGBA16; //temporal data
const int colortex3Format = RGB8; //specular data
const int gaux1Format = R8; //cloud alpha, ao
const int gaux2Format = RGBA8; //reflection image
const int gaux3Format = RG16; //normals
const int gaux4Format = RGB16; //fresnel
*/

const bool shadowHardwareFiltering = true;
const float shadowDistanceRenderMul = 1.0;
const int noiseTextureResolution = 512;
const float wetnessHalflife = 300.0;
const float drynessHalflife = 25.0;

//Common Functions//

float eBS = eyeBrightnessSmooth.y / 255.0;
float eBS3 = clamp((eyeBrightnessSmooth.y-220)/15.0,0.0,1.0);
float sunVisibility  = clamp(dot( sunVec,upVec) + 0.0625, 0.0, 0.125) * 8.0;

#ifdef BRUIT_CAMERA
float GetLuminance(vec3 color){
	return dot(color,vec3(0.299, 0.587, 0.114));
}
#endif

#ifdef DITHERING_SCREEN
#include "/lib/util/lexClosest.glsl"
#endif

////////////////////////////////////////////////////////////////////////
//////////////////////////////FILM GRAIN///////////////////////////////
//////////////////////////////////////////////////////////////////////

#ifdef FILM_GRAINS
#if FILM_GRAINS_STYLE==1
vec4 calcgrain(vec4 clr){
	
	float noiseX=clamp01(fract(sin(dot(texCoord.st*frameTimeCounter*.04,vec2(12.9898,78.223)))*43758.5453));
	float noiseY=clamp01(fract(sin(dot(texCoord.st*frameTimeCounter*.004,vec2(12.9898,78.223)*2.))*43758.5453));
	float noiseZ=clamp01(fract(sin(dot(texCoord.st,vec2(12.9898,78.223)*3.))*43758.5453));
	
	vec3 noise=vec3(noiseX,noiseY,noiseZ);
	
	vec3 scol=clr.rgb;
	
	scol+=noise*.005*mix(length(scol),1.,.7)*vec3(.2,.8,1.);
	scol*=mix(noise,vec3(1.),1.-FORCE_DU_GRAIN);
	return vec4(scol,1.);
}
#endif

#if FILM_GRAINS_STYLE==2

float rand(vec2 coord){
	return fract(sin(dot(coord.xy,vec2(12.9898,78.233)))*43758.5453);
}

vec3 filmgrain(vec3 color){
	
	const float noiseAmount=FORCE_DU_GRAIN;
	
	vec2 coord=texCoord.st+frameTimeCounter*.01;
	
	vec3 noise=vec3(0.);
	noise.r=rand(coord+.1);
	noise.g=rand(coord);
	noise.b=rand(coord-.1);
	
	return color*(1.-noiseAmount+noise*noiseAmount)+noise*noiseAmount;
	
}

#endif
#endif
//////////////////////////////////////////////////////////////////////
///////////////////////////////////GOUTTES ECRAN/////////////////////
////////////////////////////////////////////////////////////////////

vec2 underwaterRefraction(vec2 coord){

	if (isEyeInWater>0 && isEyeInWater <3){
		
			#ifdef MOUVEMENT_EAU

			const float refractionMultiplier=RMULTIPLIER;
			const float refractionSpeed=RSPEED;
			const float refractionSize=RSIZE;
			
			vec2 refractCoord=vec2(sin(frameTimeCounter*RSPEED+coord.x*25.*RSIZE+coord.y*12.5*RSIZE),0.);
			
			return bool(float(isEyeInWater)>.9)?coord+refractCoord*RMULTIPLIER:coord;
			
			#endif
	}

		return coord;
}


#if RAINDROP_STYLE == 0 || !defined OVERWORLD
vec2 raindropRefraction(vec2 coord){
	return coord;
}
#endif

#ifdef OVERWORLD

	#if MC_VERSION <=11701
		float rainSmooth = 	biomeHasRainSmooth;
		float notColdSmooth = biomeisNotColdSmooth;
	#endif
	#if MC_VERSION >=11800
		float rainSmooth = 	biomeHasRainSmooth2;
		float notColdSmooth = biomeisNotColdSmooth2;
	#endif
		
	
	
	#if RAINDROP_STYLE == 1
	vec2 raindropRefraction(vec2 coord){
		
		#ifndef RAINDROPS_IN_COLD
			rainSmooth *= notColdSmooth;
		#endif

		float rainVisibility = eBS3;
			rainVisibility *= rainSmooth;
			rainVisibility *= rainStrengthS2;
			if (rainVisibility < 0.1) rainVisibility = 0.0;

		const float refractionMultiplier=.04;
		
		#if GOUTTE_ECRAN == 1
		float a=RAINDROP_HEIGHT;
		float b=RAINDROP_SPEED;
		float c=SECOND_RAINDROP_HEIGHT;
		float d=SECOND_RAINDROP_SPEED;
		float e=15.;
		#endif
		
		#if GOUTTE_ECRAN == 2
		float a=.07;
		float b=.03;
		float c=.1;
		float d=.03;
		float e=15.;
		#endif
		
		#if GOUTTE_ECRAN == 3
		float a=.015;
		float b=.005;
		float c=.03;
		float d=.003;
		float e=15.;
		#endif

		#if GOUTTE_ECRAN > 0
		#ifdef OVERWORLD
		vec2 aspectcorrect=vec2(aspectRatio,1.);
		
		float noise=texture2D(noisetex,coord.st*aspectcorrect*a+vec2(0.,frameTimeCounter*b)).x;
			  noise+=texture2D(noisetex,coord.st*aspectcorrect*c+vec2(0.,frameTimeCounter*d)).x;
		
		float raindrops=clamp((noise-1.)*5.*pow(eBS,e),0.,1.);
		
		coord-=vec2(0.,coord.y)*refractionMultiplier*raindrops*rainStrengthS*rainVisibility;
		
		#endif
		#endif
		
		return coord;
		
	}
	#endif

	#if RAINDROP_STYLE == 2

	// this raindrop code was taken from https://www.shadertoy.com/view/ltffzl
	// (by Martijn Steinrucken aka BigWings) and modified by LexBoosT

	float dropSpeed = frameTimeCounter * DROP_SPEED;

	vec3 N13(float p) {

	vec3 p3 = fract(vec3(p) * vec3(.1031,.11369,.13787));
	p3 += dot(p3, p3.yzx + 19.19);
	return fract(vec3((p3.x + p3.y)*p3.z, (p3.x+p3.z)*p3.y, (p3.y+p3.z)*p3.x));
	}

	vec4 N14(float t) {
		return fract(sin(t*vec4(123., 1024., 1456., 264.))*vec4(6547., 345., 8799., 1564.));
	}
	float N(float t) {
		return fract(sin(t*12345.564)*7658.76);
	}

	float Saw(float b, float t) {
		return smoothstep(0., b, t)*smoothstep(1., b, t);
	}


	vec2 DropLayer2(vec2 uv, float t) {
		vec2 UV = uv;
		
		uv.y += t*0.75;
		vec2 a = vec2(6., 1.);
		vec2 grid = a*2.;
		vec2 id = floor(uv*grid);
		
		float colShift = N(id.x); 
		uv.y += colShift;
		
		id = floor(uv*grid);
		vec3 n = N13(id.x*35.2+id.y*2376.1);
		vec2 st = fract(uv*grid)-vec2(.5, 0);
		
		float x = n.x-.5;
		
		float y = UV.y*20.;
		float wiggle = sin(y+sin(y));
		x += wiggle*(.5-abs(x))*(n.z-.5);
		x *= .7;
		float ti = fract(t+n.z);
		y = (Saw(.85, ti)-.5)*.9+.5;
		vec2 p = vec2(x, y);
		
		float d = length((st-p)*a.yx);
		
		float mainDrop = smoothstep(.4, .0, d);
		
		float r = sqrt(smoothstep(1., y, st.y));
		float cd = abs(st.x-x);
		float trail = smoothstep(.13*r, .15*r*r, cd);
		float trailFront = smoothstep(-.02, .02, st.y-y);
		trail *= trailFront*r*r;
		
		y = UV.y;
		float trail2 = smoothstep(.2*r, .0, cd);
		float droplets = max(0., (sin(y*(1.-y)*120.)-st.y))*trail2*trailFront*n.z;
		y = fract(y*10.)+(st.y-.5);
		float dd = length(st-vec2(x, y));
		droplets = smoothstep(.3, 0., dd);
		float m = mainDrop+droplets*r*trailFront;
		
		return vec2(m, trail);
	}

	float StaticDrops(vec2 uv, float t) {
		uv *= 40.;
		
		vec2 id = floor(uv);
		uv = fract(uv)-.5;
		vec3 n = N13(id.x*107.45+id.y*3543.654);
		vec2 p = (n.xy-.5)*.7;
		float d = length(uv-p);
		
		float fade = Saw(.025, fract(t+n.z));
		float c = smoothstep(.3, 0., d)*fract(n.z*10.)*fade;
		return c;
	}

	vec2 Drops(vec2 uv, float t, float l0, float l1, float l2) {

		float s = StaticDrops(uv, t)*l0; 
		vec2 m1 = DropLayer2(uv, t)*l1;
		vec2 m2 = DropLayer2(uv*1.85, t)*l2;
		
		float c = s+m1.x+m2.x;
		c = smoothstep(.3, 1., c);
		
		return vec2(c, max(m1.y*l0, m2.y*l1));
	}

	vec2 raindropRefraction(vec2 coord){

			#ifndef RAINDROPS_IN_COLD
				rainSmooth *= notColdSmooth;
			#endif

			float rainVisibility = eBS3;
			rainVisibility *= rainSmooth;
			rainVisibility *= rainStrengthS2;
			if (rainVisibility < 0.1) rainVisibility = 0.0;
			if(rainVisibility > 0.0 && isEyeInWater == 0){
			
				float rainAmount0 = rainVisibility * STATIC_DROP;
				float rainAmount1 = rainVisibility * DROP_LAYER_1;
				float rainAmount2 = rainVisibility * DROP_LAYER_2;
			
				vec2 uv = (coord-vec2(0.5))*vec2(aspectRatio,1.0);
				float t = dropSpeed;
				float staticDrops = smoothstep(-.5, 1., rainAmount0)*2.;
				float layer1 = smoothstep(.25, .75, rainAmount1);
				float layer2 = smoothstep(.0, .5, rainAmount2);

				vec2 c = Drops(uv, t, staticDrops, layer1, layer2);
			
				vec2 e = vec2(.001, 0.);
				float cx = Drops(uv+e, t, staticDrops, layer1, layer2).x;
				float cy = Drops(uv+e.yx, t, staticDrops, layer1, layer2).x;
				vec2 n = vec2(cx-c.x, cy-c.x);

				return coord+n;
				}
		else
		{
			return coord;
		}
	}

	#endif
#endif

///////////////////////////////////////////////////////////////////////
//////////////////////////BIOMES_REFRACT//////////////////////////////
/////////////////////////////////////////////////////////////////////

vec2 biomeRefraction(vec2 coord){
	
	#if defined (NETHER) && defined NETHER_REFRACT
			const float refractionMultiplier3=STRENGTH_REFRACT;

				float heatVisibility3 = 1.0;
				#if NETHER_WEATHER_HEAT == 1

					#if MC_VERSION <=11701
					heatVisibility3 *= biomeHasHeatSmooth3;
					#endif
					#if MC_VERSION >=11800
					heatVisibility3 *= biomeHasHeatSmooth32;
					#endif

				#else
				#endif
				if (heatVisibility3 < 0.1) heatVisibility3 = 0.0;

	#endif

	#if defined (OVERWORLD) && defined DESERT_REFRACT

			const float refractionMultiplier=STRENGTH_DESERT_REFRACT;
			
			#if MC_VERSION <=11701
			float heatSmooth = biomeHasHeatSmooth;
			#endif
			#if MC_VERSION >=11800
			float heatSmooth = biomeHasHeatSmooth02;
			#endif

				float heatVisibility = clamp(pow(eBS,4.0),0.0,1.0);
				#if DESERT_WEATHER_HEAT == 1
					heatVisibility *= heatSmooth * sunVisibility * (1.0-rainStrength);
				#elif DESERT_WEATHER_HEAT == 2
					heatVisibility *= heatSmooth * sunVisibility;
				#elif DESERT_WEATHER_HEAT == 3
					heatVisibility *= heatSmooth * (1.0-rainStrength);
				#elif DESERT_WEATHER_HEAT == 4
					heatVisibility *= heatSmooth;
				#endif
				if (heatVisibility < 0.1) heatVisibility = 0.0;
	#endif


	#if defined (OVERWORLD) && defined MESA_REFRACT
			const float refractionMultiplier2=STRENGTH_MESA_REFRACT;

			#if MC_VERSION <=11701
			float heatSmooth2 = biomeHasHeatSmooth2;
			#endif
			#if MC_VERSION >=11800
			float heatSmooth2 = biomeHasHeatSmooth22;
			#endif

				float heatVisibility2 = clamp(pow(eBS,4.0),0.0,1.0);
				#if MESA_WEATHER_HEAT == 1
					heatVisibility2 *= heatSmooth2 * sunVisibility * (1.0-rainStrength);
				#elif MESA_WEATHER_HEAT == 2
					heatVisibility2 *= heatSmooth2 * sunVisibility ;
				#elif MESA_WEATHER_HEAT == 3
					heatVisibility2 *= heatSmooth2 * (1.0-rainStrength);
				#elif MESA_WEATHER_HEAT == 4
					heatVisibility2 *= heatSmooth2;
				#endif
				if (heatVisibility2 < 0.1) heatVisibility2 = 0.0;
	#endif


	#if defined (NETHER) && defined NETHER_REFRACT

	vec2 aspectcorrect=vec2(aspectRatio,1.);

	float noisec=texture2D(noisetex,coord.st*aspectcorrect*.008-vec2(0.,frameTimeCounter*.007)).x;
	noisec+=texture2D(noisetex,coord.st*aspectcorrect*.007-vec2(0.,frameTimeCounter*.007)).x;
	float netherfrac=clamp((noisec-1.)*5.,0.,1.);
	coord-=vec2(0.,coord.y)*refractionMultiplier3*netherfrac*heatVisibility3;
	
	noisec=texture2D(noisetex,coord.st*aspectcorrect*.007-vec2(0.,frameTimeCounter*.006)).x;
	noisec+=texture2D(noisetex,coord.st*aspectcorrect*.006-vec2(0.,frameTimeCounter*.006)).x;
	netherfrac=clamp((noisec-1.)*5.,0.,1.);
	coord-=vec2(0.,coord.y)*refractionMultiplier3*netherfrac*heatVisibility3;
	
	noisec=texture2D(noisetex,coord.st*aspectcorrect*.006-vec2(0.,frameTimeCounter*.005)).x;
	noisec+=texture2D(noisetex,coord.st*aspectcorrect*.005-vec2(0.,frameTimeCounter*.003)).x;
	netherfrac=clamp((noisec-1.)*5.,0.,1.);
	coord-=vec2(0.,coord.y)*refractionMultiplier3*netherfrac*heatVisibility3;
	
	noisec=texture2D(noisetex,coord.st*aspectcorrect*.005-vec2(0.,frameTimeCounter*.004)).x;
	noisec+=texture2D(noisetex,coord.st*aspectcorrect*.004-vec2(0.,frameTimeCounter*.004)).x;
	netherfrac=clamp((noisec-1.)*5.,0.,1.);
	coord-=vec2(0.,coord.y)*refractionMultiplier3*netherfrac*heatVisibility3;
	
	noisec=texture2D(noisetex,coord.st*aspectcorrect*.004-vec2(0.,frameTimeCounter*.003)).x;
	noisec+=texture2D(noisetex,coord.st*aspectcorrect*.003-vec2(0.,frameTimeCounter*.003)).x;
	netherfrac=clamp((noisec-1.)*5.,0.,1.);
	coord-=vec2(0.,coord.y)*refractionMultiplier3*netherfrac*heatVisibility3;
	
	noisec=texture2D(noisetex,coord.st*aspectcorrect*.003-vec2(0.,frameTimeCounter*.002)).x;
	noisec+=texture2D(noisetex,coord.st*aspectcorrect*.002-vec2(0.,frameTimeCounter*.002)).x;
	netherfrac=clamp((noisec-1.)*5.,0.,1.);
	coord-=vec2(0.,coord.y)*refractionMultiplier3*netherfrac*heatVisibility3;
	
	noisec=texture2D(noisetex,coord.st*aspectcorrect*.002-vec2(0.,frameTimeCounter*.001)).x;
	noisec+=texture2D(noisetex,coord.st*aspectcorrect*.001-vec2(0.,frameTimeCounter*.001)).x;
	netherfrac=clamp((noisec-1.)*5.,0.,1.);
	coord-=vec2(0.,coord.y)*refractionMultiplier3*netherfrac*heatVisibility3;

	#endif


	#if defined (OVERWORLD) && defined DESERT_REFRACT

	vec2 aspectcorrect=vec2(aspectRatio,1.);

	float noise=texture2D(noisetex,coord.st*aspectcorrect*.009-vec2(0.,frameTimeCounter*.009)).x;
	noise+=texture2D(noisetex,coord.st*aspectcorrect*.008-vec2(0.,frameTimeCounter*.009)).x;
	float desertfrac=clamp((noise-1.)*5.,0.,1.);
	coord-=vec2(0.,coord.y)*refractionMultiplier*desertfrac*heatVisibility;
	
	noise=texture2D(noisetex,coord.st*aspectcorrect*.008-vec2(0.,frameTimeCounter*.008)).x;
	noise+=texture2D(noisetex,coord.st*aspectcorrect*.007-vec2(0.,frameTimeCounter*.008)).x;
	desertfrac=clamp((noise-1.)*5.,0.,1.);
	coord-=vec2(0.,coord.y)*refractionMultiplier*desertfrac*heatVisibility;
	
	noise=texture2D(noisetex,coord.st*aspectcorrect*.007-vec2(0.,frameTimeCounter*.007)).x;
	noise+=texture2D(noisetex,coord.st*aspectcorrect*.006-vec2(0.,frameTimeCounter*.007)).x;
	desertfrac=clamp((noise-1.)*5.,0.,1.);
	coord-=vec2(0.,coord.y)*refractionMultiplier*desertfrac*heatVisibility;
	
	noise=texture2D(noisetex,coord.st*aspectcorrect*.006-vec2(0.,frameTimeCounter*.006)).x;
	noise+=texture2D(noisetex,coord.st*aspectcorrect*.005-vec2(0.,frameTimeCounter*.006)).x;
	desertfrac=clamp((noise-1.)*5.,0.,1.);
	coord-=vec2(0.,coord.y)*refractionMultiplier*desertfrac*heatVisibility;
	
	noise=texture2D(noisetex,coord.st*aspectcorrect*.005-vec2(0.,frameTimeCounter*.005)).x;
	noise+=texture2D(noisetex,coord.st*aspectcorrect*.004-vec2(0.,frameTimeCounter*.005)).x;
	desertfrac=clamp((noise-1.)*5.,0.,1.);
	coord-=vec2(0.,coord.y)*refractionMultiplier*desertfrac*heatVisibility;
	
	noise=texture2D(noisetex,coord.st*aspectcorrect*.004-vec2(0.,frameTimeCounter*.004)).x;
	noise+=texture2D(noisetex,coord.st*aspectcorrect*.003-vec2(0.,frameTimeCounter*.004)).x;
	desertfrac=clamp((noise-1.)*5.,0.,1.);
	coord-=vec2(0.,coord.y)*refractionMultiplier*desertfrac*heatVisibility;
	
	noise=texture2D(noisetex,coord.st*aspectcorrect*.003-vec2(0.,frameTimeCounter*.003)).x;
	noise+=texture2D(noisetex,coord.st*aspectcorrect*.002-vec2(0.,frameTimeCounter*.003)).x;
	desertfrac=clamp((noise-1.)*5.,0.,1.);
	coord-=vec2(0.,coord.y)*refractionMultiplier*desertfrac*heatVisibility;

	noise=texture2D(noisetex,coord.st*aspectcorrect*.002-vec2(0.,frameTimeCounter*.002)).x;
	noise+=texture2D(noisetex,coord.st*aspectcorrect*.001-vec2(0.,frameTimeCounter*.002)).x;
	desertfrac=clamp((noise-1.)*5.,0.,1.);
	coord-=vec2(0.,coord.y)*refractionMultiplier*desertfrac*heatVisibility;

	#endif

	#if defined (OVERWORLD) && defined MESA_REFRACT

	vec2 aspectcorrect2=vec2(aspectRatio,1.);

	float noiseb=texture2D(noisetex,coord.st*aspectcorrect2*.009-vec2(0.,frameTimeCounter*.009)).x;
	noiseb+=texture2D(noisetex,coord.st*aspectcorrect2*.008-vec2(0.,frameTimeCounter*.009)).x;
	float mesafrac=clamp((noiseb-1.)*5.,0.,1.);
	coord-=vec2(0.,coord.y)*refractionMultiplier2*mesafrac*heatVisibility2;
	
	noiseb=texture2D(noisetex,coord.st*aspectcorrect2*.008-vec2(0.,frameTimeCounter*.008)).x;
	noiseb+=texture2D(noisetex,coord.st*aspectcorrect2*.007-vec2(0.,frameTimeCounter*.008)).x;
	mesafrac=clamp((noiseb-1.)*5.,0.,1.);
	coord-=vec2(0.,coord.y)*refractionMultiplier2*mesafrac*heatVisibility2;
	
	noiseb=texture2D(noisetex,coord.st*aspectcorrect2*.007-vec2(0.,frameTimeCounter*.007)).x;
	noiseb+=texture2D(noisetex,coord.st*aspectcorrect2*.006-vec2(0.,frameTimeCounter*.007)).x;
	mesafrac=clamp((noiseb-1.)*5.,0.,1.);
	coord-=vec2(0.,coord.y)*refractionMultiplier2*mesafrac*heatVisibility2;
	
	noiseb=texture2D(noisetex,coord.st*aspectcorrect2*.006-vec2(0.,frameTimeCounter*.006)).x;
	noiseb+=texture2D(noisetex,coord.st*aspectcorrect2*.005-vec2(0.,frameTimeCounter*.006)).x;
	mesafrac=clamp((noiseb-1.)*5.,0.,1.);
	coord-=vec2(0.,coord.y)*refractionMultiplier2*mesafrac*heatVisibility2;
	
	noiseb=texture2D(noisetex,coord.st*aspectcorrect2*.005-vec2(0.,frameTimeCounter*.005)).x;
	noiseb+=texture2D(noisetex,coord.st*aspectcorrect2*.004-vec2(0.,frameTimeCounter*.005)).x;
	mesafrac=clamp((noiseb-1.)*5.,0.,1.);
	coord-=vec2(0.,coord.y)*refractionMultiplier2*mesafrac*heatVisibility2;
	
	noiseb=texture2D(noisetex,coord.st*aspectcorrect2*.004-vec2(0.,frameTimeCounter*.004)).x;
	noiseb+=texture2D(noisetex,coord.st*aspectcorrect2*.003-vec2(0.,frameTimeCounter*.004)).x;
	mesafrac=clamp((noiseb-1.)*5.,0.,1.);
	coord-=vec2(0.,coord.y)*refractionMultiplier2*mesafrac*heatVisibility2;
	
	noiseb=texture2D(noisetex,coord.st*aspectcorrect2*.003-vec2(0.,frameTimeCounter*.003)).x;
	noiseb+=texture2D(noisetex,coord.st*aspectcorrect2*.002-vec2(0.,frameTimeCounter*.003)).x;
	mesafrac=clamp((noiseb-1.)*5.,0.,1.);
	coord-=vec2(0.,coord.y)*refractionMultiplier2*mesafrac*heatVisibility2;

	noiseb=texture2D(noisetex,coord.st*aspectcorrect2*.002-vec2(0.,frameTimeCounter*.002)).x;
	noiseb+=texture2D(noisetex,coord.st*aspectcorrect2*.001-vec2(0.,frameTimeCounter*.002)).x;
	mesafrac=clamp((noiseb-1.)*5.,0.,1.);
	coord-=vec2(0.,coord.y)*refractionMultiplier2*mesafrac*heatVisibility2;

	#endif

	return coord;
}

///////////////////////////////////////////////////////////////////////////
//////////////////////////////BLINDNESS_EFFECT////////////////////////////
/////////////////////////////////////////////////////////////////////////

vec3 blindnessEffect(vec3 clr){
	
	const float blindnessAmount=.9;
	
	float dist=min(pow(distance(texCoord.st,vec2(.5)),1.4)*1.4,1.);
	
	return mix(clr,vec3(0.0),blindness*dist);
	
}

///////////////////////////////////////////////////////////////////////
///////////////////////////////////SCANLINE_BAND//////////////////////
/////////////////////////////////////////////////////////////////////

#ifdef SCANLINE_BAND

float sinEsp(float a,float esp)
{
	float cycle=mod(a/(2.0*PI),esp);
	if(cycle<=0.5)
	{
		return sin(a);
	}
	else
	{
		return 0.0;
	}
	
}
#endif

///////////////////////////////////////////////////////////////////////
////////////////////////////////////Tube Border///////////////////////
/////////////////////////////////////////////////////////////////////

#ifdef CRT_BORDER
#if CRT_BORDER_STRENGTH==1
float crtBorder=75.0;
#elif CRT_BORDER_STRENGTH==2
float crtBorder=55.0;
#elif CRT_BORDER_STRENGTH==3
float crtBorder=35.0;
#elif CRT_BORDER_STRENGTH==4
float crtBorder=25.0;
#endif

float tubeBorder(){
	vec2 a=texCoord.st*(1.-texCoord.st)*(crtBorder+texCoord.st);
	return mix(2.0-pow(a.x*a.y,0.25),1.0,0.9);
}

vec2 calculateDistortion(){
	vec2 coord=texCoord.st*2.-1.;
	coord*=tubeBorder();
	
	return coord*0.5+0.5;
}

void calculateBorder(inout vec3 color){
	color*=smoothstep(1.0,0.95,tubeBorder());
}
#endif

////////////////////////////////////////////////////////////////////////
//////////////////////////////BOTW_MAPPING/////////////////////////////
//////////////////////////////////////////////////////////////////////

#ifdef BOTW
vec3 BOTWTonemap(vec3 color){
	color=pow(color,vec3(1./1.2));
	
	float mixrgb=(color.r+color.g+color.b)/3.5;
	float weight=BOTWSAT+(1.-pow(1.-1.*mixrgb,2.))*.08;
	
	return mix(vec3(mixrgb),color,weight);
}
#endif

////////////////////////////////////////////////////////////////////////
///////////////////////////////LEX_AMBIANT/////////////////////////////
//////////////////////////////////////////////////////////////////////

#if defined (OVERWORLD) && defined LEX_AMBIANT

vec4 getAmbient(vec4 color)
{
	vec4 tint=vec4(1.,1.,1.,1.);
	float time;
	if(worldTime>=22000.)
	{// Lever du Soleil
		time=min(max((23000.-worldTime)/1000.,-1.),1.);
		if(time>0)
		{// Ciel commence à se colorier
			tint[0]=.95+(.15*(1.-time));// .95 to 1.1
			tint[1]=.95-(.05*(1.-time));// .95 to .9
			tint[2]=1.1-(.1*(1.-time));// 1.1 to 1.0
		}
		else
		{// Soleil Lever
			tint[0]=1.1-(.05*(abs(time)));// 1.1 to 1.05
			tint[1]=.9+(0.*(abs(time)));// .9 to .9
			tint[2]=1.+(.05*(abs(time)));// 1.0 to 1.05
		}
	}
	else if(worldTime>=12000)
	{// La nuit
		time=min(max((13000.-worldTime)/1000.,-1.),1.);
		if(time>0)
		{// Coucher de soleil
			tint[0]=1.1+(.15*(1.-time));// 1.1 to 1.25
			tint[1]=1.-(.05*(1.-time));// 1.0 to 0.95
			tint[2]=.9-(.15*(1.-time));// .9 to .75
		}
		else
		{// Commencement de la nuit
			tint[0]=1.25-(.3*(abs(time)));// 1.25 to .95
			tint[1]=.95-(0.*(abs(time)));// .95 to .95
			tint[2]=.75+(.35*(abs(time)));// .65 to 1.1
		}
	}
	else if(worldTime>=0)
	{// Jour, du crépuscule à l'aube
		time=min(max((6000.-worldTime)/6000.,-1.),1.);
		if(time>0)
		{// Matin
			tint[0]=1.05-(.05*(1.-time));// 1.05 to 1
			tint[1]=.9+(.1*(1.-time));// .9 to 1
			tint[2]=1.05-(.05*(1.-time));// 1.05 to 1
		}
		else
		{// Après_Midi
			tint[0]=1+(.1*(abs(time)));// 1 to 1.1
			tint[1]=1-(0.*(abs(time)));// 1 to 1
			tint[2]=1-(.1*(abs(time)));// 1 to .9
		}
	}
	return tint;
}
#endif

//////////////////////////////////////////////////////////////////////////
/////////////////////////////////HDR/////////////////////////////////////
////////////////////////////////////////////////////////////////////////

#ifdef HDR
vec3 LexHDR(in vec3 color){
	vec3 LexHDRImage;
	
	vec3 ExpositionGlobal=color*GLOBAL_EXPOSITION;//0.95
	
	vec3 SousExposition=color/SOUS_EXPOSITION;//1.50
	
	LexHDRImage=mix(SousExposition,ExpositionGlobal,color);
	
	return LexHDRImage;
}
#endif

////////////////////////////////////////////////////////////////////////
//////////////////////////////BRUIT_CAMERA/////////////////////////////
//////////////////////////////////////////////////////////////////////

vec3 doBruitCam(vec3 clr){
	
	const float noiseStrength=FORCE_BRUIT;
	const float noiseResoltion=7.5;
	
	#ifdef BRUIT_CAMERA
	
	vec2 aspectcorrect=vec2(aspectRatio,1.);
	
	vec3 rgbNoise=texture2D(noisetex,texCoord.st*noiseResoltion*aspectcorrect+vec2(frameTimeCounter*15.,frameTimeCounter*5.)).rgb;
	
	clr=mix(clr,rgbNoise,GetLuminance(rgbNoise)*noiseStrength);
	
	#endif
	
	return clr;
	
}

////////////////////////////////////////////////////////////////////////
/////////////////////////////////VISEUR////////////////////////////////
//////////////////////////////////////////////////////////////////////

#ifdef VISEUR

void aim(inout vec4 color)
{
	if(abs(texCoord.s-.4875)<.0005&&abs(texCoord.t-.45)<.1)color=vec4(1)-color;
	if(abs(texCoord.s-.5125)<.0005&&abs(texCoord.t-.45)<.1)color=vec4(1)-color;
	if(abs(texCoord.t-.45)<.0008&&abs(texCoord.s-.5)<.0075)color=vec4(1)-color;// 31 blocs au sol
	if(abs(texCoord.t-.4)<.0008&&abs(texCoord.s-.5)<.005)color=vec4(1)-color;// 43 blocs au sol
	if(abs(texCoord.t-.35)<.0008&&abs(texCoord.s-.5)<.0025)color=vec4(1)-color;// flemme de mesurer
	if(abs(texCoord.t-.3)<.0008&&abs(texCoord.s-.5)<.001)color=vec4(1)-color;// idem
}
#endif

////////////////////////////////////////////////////////////////////////
//////////////////////////////MODE_RAGE////////////////////////////////
//////////////////////////////////////////////////////////////////////

#ifdef MODE_RAGE
void killingVignette(inout vec4 color)
{
	#ifdef HEARTBEAT
	float heartBeat=sin(frameTimeCounter*1.*HEARTBEAT_SPEED)+1.+cos(frameTimeCounter*2.*HEARTBEAT_SPEED)+1.;
	#else
	float heartBeat=1.;
	#endif
	color+=vec4(.8118,.0706,.0706,1.)*pow(distance(texCoord.st,vec2(.5)),2.)*heartBeat;
}
#endif

////////////////////////////////////////////////////////////////////////
//////////////////////////ULTRA_VIGNETTE///////////////////////////////
//////////////////////////////////////////////////////////////////////

#ifdef ULTRA_VIGNETTE
vec3 getVignette(vec3 clr,vec2 pos){
	float factor=distance(pos,vec2(.5));
	
	factor*=factor*factor*factor*factor;
	factor*=FORCE_ULTRA_VIGNETTE;
	
	factor=clamp(1.-factor*2.,.02,.8);
	
	return clr*factor;
}
#endif

////////////////////////////////////////////////////////////////////////
//////////////////////////////////DAMAGE///////////////////////////////
//////////////////////////////////////////////////////////////////////

vec3 damage_visual(vec3 color){
        #ifdef DAMAGE_EFFECT
            return color + (vec3(0.7, 0.0, 0.0) *pow(distance(texCoord.st,vec2(.5)),2.) * touchmybody);
        #else
            return color;
        #endif
    }
	
////////////////////////////////////////////////////////////////////////
/////////////////////////////////MAIN//////////////////////////////////
//////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////MAIN///////////////////////////////
///////////////////////////////////////////////////////////////////

//Program//
void main(){
	
	vec2 newtex=texCoord.st;
	#ifdef DISTORTION
	vec3 distort=dot(vUVDot,vUVDot)*vec3(-.7,-.7,-1.)+vUV;
	newtex=distort.xy/distort.z;
	#endif

	vec2 newtexcoord=raindropRefraction(underwaterRefraction(newtex));
	newtexcoord=biomeRefraction(newtexcoord);

	////////////////////////////////////////////////////////////////////////////////////////////////
	//////////////////////////////////MAIN_HYPER_SPEED/////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////////////////////////

	#ifdef HYPER_SPEED
	
	float z=texture2D(depthtex1,newtex.st).x;
	float hand=float(z<0.56);
	
	vec4 color=vec4(0.0);
	float dither=texture2D(colortex4,newtex.xy*0.0625).r;
	
	if(hand<.5){
		
		for(int i=0;i<16;i++){
			float f=float(i)+dither;
			float weight=1.-abs(f*0.125-1.0);
			vec3 sample=texture2D(colortex1,mix(newtexcoord,vec2(0.5),f*0.03125*effectStrength*HYPERSPEED_MULTIPLIER)).rgb;
			color.rgb+=sample*sample*weight;
			color.a+=weight;
		}
		
		color.rgb*=(effectStrength*1.0+1.0);
		color.rgb/=8.0;
		color.rgb=sqrt(color.rgb);
	}
	else
	{
		color=texture2D(colortex1,newtexcoord).rgba;
	}
	#else
	
	vec4 color=texture2D(colortex1,newtexcoord).rgba;
	
	#endif
	
	////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////BLINDNESS_EFFECT//////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////////////////////////
	
	color.rgb=blindnessEffect(color.rgb);
	
	////////////////////////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////MAIN_POSTERIZATION//////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////////////////////////
	
	#ifdef POSTERIZATION
	color.rgb=pow(color.rgb,vec3(1./2.2));
	if(length(color.rgb)<.5)color.rgb=floor(normalize(color.rgb)*POSTERIZATION_LIMIT*2.)/POSTERIZATION_LIMIT/2.*floor(length(color.rgb*POSTERIZATION_LIMIT))/POSTERIZATION_LIMIT;
	if(length(color.rgb)>.5)color.rgb=ceil(normalize(color.rgb)*POSTERIZATION_LIMIT*2.)/POSTERIZATION_LIMIT/2.*ceil(length(color.rgb*POSTERIZATION_LIMIT))/POSTERIZATION_LIMIT;
	color.rgb=pow(color.rgb,vec3(2.2));
	#endif
	
	////////////////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////MAIN_DITHERING/////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////////////////////////
	
	#ifdef DITHERING_SCREEN
	float dither2=lexClosest(newtex.xy);
	color.rgb=pow(color.rgb,vec3(1./2.2));
	color.r=floor(color.r*DITHERING_SAMPLES+dither2)/DITHERING_SAMPLES;
	color.g=floor(color.g*DITHERING_SAMPLES+dither2)/DITHERING_SAMPLES;
	color.b=floor(color.b*DITHERING_SAMPLES+dither2)/DITHERING_SAMPLES;
	color.rgb=pow(color.rgb,vec3(2.2));
	#endif
	
	////////////////////////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////MAIN_ARC_EN_CIEL////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////////////////////////
	
	#if defined (OVERWORLD) && defined ARC_EN_CIEL

	vec4 fragposition=gbufferProjectionInverse*(vec4(newtex.st,texture2D(depthtex0,newtex.st).x,1.)*2.-1.);
	fragposition/=fragposition.w;

	float sunDot = dot(sunPosNorm,normalize(fragposition.xyz)) * 0.5 + 0.5;

	if(length(fragposition.xyz) > DISTANCE_ARC_EN_CIEL && isEyeInWater == 0 && (worldTime > 2000 && worldTime < 12000))
	{
		float rainbowStrength=(wetness - rainStrength) * 0.10;
		float rainbowHue=(sunDot - 0.05 * DIAMETRE_ARC_EN_CIEL) * -50.0 / EPAISSEUR_ARC_EN_CIEL;
		if(rainbowStrength > 0.01 && rainbowHue > 0.0 && rainbowHue < 1.0){
			rainbowHue *= 6.0;
			color.r += clamp(1.5-abs(rainbowHue-1.5),0.0,1.0) * rainbowStrength * RAINBOW_INTENSITY;
			color.g += clamp(2.0-abs(rainbowHue-3.0),0.0,1.0) * rainbowStrength * RAINBOW_INTENSITY;
			color.b += clamp(1.5-abs(rainbowHue-4.5),0.0,1.0) * rainbowStrength * RAINBOW_INTENSITY;

		}
	}

	#endif
	
	////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////MAIN_DAMAGE///////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////////////////////////

	#ifdef DAMAGE_EFFECT
	color.rgb = damage_visual(color.rgb);
	#endif
	
	////////////////////////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////MAIN_SCANLINE///////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////////////////////////
	
	float scanline=0.0;
	float frameTimeCounter=frameTimeCounter*1;
		
	#if CRT == 0
	#endif

	#if CRT == 1
	float scanlineY=0.0;
	float scanlineX=0.0;

	scanlineY=sin(newtex.y * viewHeight * 2.0 / EPAISSEUR_CRT);
	scanlineX=sin(newtex.x * viewWidth * 2.0 /EPAISSEUR_CRT);
	color.rgb*=1.0 + scanlineY * FORCE_CRT * 0.1 + scanlineX * FORCE_CRT * 0.1;
	
	#endif
	
	#if CRT == 2 
	
			float modPixLock = mod(gl_FragCoord.x, 4);
			if(mod(gl_FragCoord.y, 4) > 1)
			{
				#ifdef CRT2_HONEYCOMB_EFFECT
				if(mod(gl_FragCoord.y, 8)<4) modPixLock = mod(modPixLock+2,4);
				#endif
				if(modPixLock > 0 && modPixLock < 1)
				{
					color.rgb = vec3(color.r, 0.0, 0.0);
				}
				if(modPixLock > 1 && modPixLock < 2)
				{
					color.rgb = vec3(0.0, color.g, 0.0);
				}
				if(modPixLock > 2 && modPixLock < 3)
				{
					color.rgb = vec3(0.0, 0.0, color.b);
				}
				if(modPixLock > 3 && modPixLock < 4)
				{
					color.rgb = vec3(0.1);
				}

			}
			else
			{
				color.rgb = vec3(0.1);
			}
			color.rgb *= 1.0 + FORCE_CRT2;
	#endif

	#ifdef SCANLINE
	
	scanline=sin(newtex.y*viewHeight*2./EPAISSEUR_SCANLINE+frameTimeCounter*VITESSE_SCANLINE);
	color.rgb*=1.0 + scanline * FORCE_SCANLINE * 0.1;
	#endif
	
	#ifdef SCANLINE_BAND
	
	scanline=sinEsp(newtex.y*viewHeight*2./EPAISSEUR_BAND+frameTimeCounter*VITESSE_BAND,INTERVAL_BAND);
	color.rgb/=1.0 + scanline * FORCE_BAND * 0.5;
	#endif

	////////////////////////////////////////////////////////////////////////////////////////////////
	//////////////////////////////////////MAIN_CRT_BORDER//////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////////////////////////
	
	#ifdef CRT_BORDER
	calculateBorder(color.rgb);
	#endif

	////////////////////////////////////////////////////////////////////////////////////////////////
	//////////////////////////////////////MAIN_LEX_AMBIANT/////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////////////////////////
	
	#if defined (OVERWORLD) && defined LEX_AMBIANT
	color.rgba*=getAmbient(color.rgba);
	#endif
	
	////////////////////////////////////////////////////////////////////////////////////////////////
	//////////////////////////////////////MAIN_HDR/////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////////////////////////
	
	#ifdef HDR
	color.rgb=LexHDR(color.rgb);
	#endif
	
	////////////////////////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////MAIN_BRUIT_CAM//////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////////////////////////
	
	#ifdef BRUIT_CAMERA
	color.rgb=doBruitCam(color.rgb);
	#endif
	
	////////////////////////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////MAIN_FILM_GRAIN/////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////////////////////////
	#ifdef FILM_GRAINS
	#if FILM_GRAINS_STYLE==1
	color.rgba=clamp01(color.rgba);
	color.rgba=calcgrain(vec4(color.rgba));
	#endif
	
	#if FILM_GRAINS_STYLE==2
	color.rgb=filmgrain(color.rgb);
	#endif
	#endif
	
	////////////////////////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////MAIN_VISEUR/////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////////////////////////
	
	#ifdef VISEUR
	if(heldItemId==10261||heldItemId==10262||heldItemId==10344||heldItemId==10332||heldItemId==19999)aim(color.rgba);
	#endif
	
	////////////////////////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////MAIN_RAGE///////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////////////////////////
	
	#ifdef MODE_RAGE
	if(heldItemId==10267||heldItemId==10268||heldItemId==10276||heldItemId==10278||heldItemId==10283)killingVignette(color.rgba);
	#endif
	
	////////////////////////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////MAIN_ULTRA_VIGNETTE/////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////////////////////////
	
	#ifdef ULTRA_VIGNETTE
	color.rgb=getVignette(color.rgb,newtex);
	#endif
	
	////////////////////////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////MAIN_BANDES/////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////////////////////////
	
	#ifdef BANDES

	float bottombandfade = clamp((newtex.t - BOTTOMBAND)/0.004,0.0,1.0);
	float topbandfade = clamp((1.0 - newtex.t - TOPBAND)/0.004,0.0,1.0);

	color.rgb = mix(vec3(0.0),color.rgb,bottombandfade*topbandfade);

	#endif
	
	////////////////////////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////MAIN_BOTW_TONEMAP///////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////////////////////////
	
	#if defined (OVERWORLD) && defined BOTW
	color.rgb=BOTWTonemap(color.rgb);
	#endif

	////////////////////////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////END_MAIN/////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////////////////
	gl_FragColor=clamp(color.rgba, 0.01, 1.0);
}

#endif

//Vertex Shader/////////////////////////////////////////////////////////////////////////////////////
#ifdef VSH


////////////////////////////////////////////////////////////////////////
//////////////////////////////DISTORTIONVSH////////////////////////////
//////////////////////////////////////////////////////////////////////

//Uniforms//

#ifdef DISTORTION
uniform int isEyeInWater;
uniform float aspectRatio;
uniform mat4 gbufferProjection;
#endif

uniform float timeAngle;
uniform mat4 gbufferModelView;

//Common Variables//

#ifdef DISTORTION
const float strength=FOV_DISTORTION_STRENGTH;
const float cylindricalRatio=1.0;
#endif

//Program//
void main(){
	gl_Position=ftransform();
	texCoord=gl_MultiTexCoord0.xy;
	
	////////////////////////////////////////////////////////////////////////
	//////////////////////////////MAIN_DISTORTIONVSH///////////////////////
	//////////////////////////////////////////////////////////////////////
	
	#ifdef DISTORTION
	float fov=atan(1.0/gbufferProjection[1][1]);
	if(float(isEyeInWater)>0.9)fov*=0.85;
	float height=tan(fov/aspectRatio*0.5);
	
	float scaledHeight=strength*height;
	float cylAspectRatio=aspectRatio*cylindricalRatio;
	float aspectDiagSq=aspectRatio*aspectRatio+1.0;
	float diagSq=scaledHeight*scaledHeight*aspectDiagSq;
	vec2 signedUV=(2.0*texCoord.st+vec2(-1.0,-1.0));
	
	float z=0.5*sqrt(diagSq+1.0)+0.5;
	float ny=(z-1.0)/(cylAspectRatio*cylAspectRatio+1.0);
	
	vUVDot=sqrt(ny)*vec2(cylAspectRatio,1.0)*signedUV;
	vUV=vec3(0.5,0.5,1.0)*z+vec3(-0.5,-0.5,0.0);
	vUV.xy+=texCoord.st;
	#endif
	
	const vec2 sunRotationData=vec2(cos(sunPathRotation*.01745329251994),-sin(sunPathRotation*.01745329251994));
	float ang=fract(timeAngle-.25);
	ang=(ang+(cos(ang*3.14159265358979)*-.5+.5-ang)/3.)*6.28318530717959;
	sunVec=normalize((gbufferModelView*vec4(vec3(-sin(ang),cos(ang)*sunRotationData)*2000.,1.)).xyz);
	
	upVec=normalize(gbufferModelView[1].xyz);

}

#endif