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

//Settings//

#include "/lib/util/fastMath.glsl"

#include "/settings/globalSettings.glsl"

//Varyings//
varying vec2 texCoord;
varying vec3 sunVec, upVec;

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

	//Uniforms//
	uniform int frameCounter;
	uniform int isEyeInWater;
	uniform float frameTimeCounter;
	uniform float blindFactor;
	uniform float rainStrengthS;
	uniform float screenBrightness;
	uniform float viewWidth, viewHeight;
	uniform float far;

	#ifdef ENABLE_DARKNESS_EFFECT
		#if MC_VERSION >= 11900
			uniform float darknessFactor;
		#endif
	#endif

	uniform ivec2 eyeBrightnessSmooth;

	uniform vec3 skyColor;
	uniform vec3 cameraPosition;

	uniform sampler2D colortex0;
	uniform sampler2D colortex1;

	uniform mat4 gbufferProjectionInverse;

	//Optifine Constants//
	const bool colortex1MipmapEnabled = true;

	//Common Variables//

	float eBS               = eyeBrightnessSmooth.y / 240.0;
	float eBS2              = clamp((eyeBrightnessSmooth.y-220)/15.0, 1.0, 1.0);
	float sunVisibility     = clamp00125(dot( sunVec,upVec) + 0.0625) * 8.0;
	float screenBrightness2 = clamp01(screenBrightness);
	float rainStrengthSp2   = rainStrengthS * rainStrengthS;
	float lightShaftTime    = pow(abs(sunVisibility - 0.5) * 2.0, 10.0);

	//Common Functions//
	float GetLuminance(vec3 color) {
		return dot(color,vec3(0.299, 0.587, 0.114));
	}

	//Includes//
	#include "/lib/color/dimensionColor.glsl"

	//Program//
	void main(){
		vec4 color = texture2DLod(colortex0, texCoord.xy, 0.0);

		#if (defined OVERWORLD && defined LIGHT_SHAFT) || (defined END && defined LIGHT_SHAFT_END)

			float lod = 0.0;

				#ifndef MC_GL_RENDERER_GEFORCE
					if (fract(viewHeight / 2.0) > 0.25 || fract(viewWidth / 2.0) > 0.25)
						lod = 0.0;
				#endif

			float offset = 1.0;

			vec3 vl1     = texture2DLod(colortex1, texCoord.xy + vec2( 0.0,  offset / viewHeight), lod).rgb;
			vec3 vl2     = texture2DLod(colortex1, texCoord.xy + vec2( 0.0, -offset / viewHeight), lod).rgb;
			vec3 vl3     = texture2DLod(colortex1, texCoord.xy + vec2( offset / viewWidth,   0.0), lod).rgb;
			vec3 vl4     = texture2DLod(colortex1, texCoord.xy + vec2(-offset / viewWidth,   0.0), lod).rgb;
			vec3 finalVl = (vl1 + vl2 + vl3 + vl4) * 0.25;
			vec3 vl      = finalVl;

			vl *= vl;

			#ifdef ENABLE_DARKNESS_EFFECT
				#if MC_VERSION >= 11900
					vl *= 1.0 - darknessFactor;
				#endif
			#endif

		#endif

		#if defined (OVERWORLD) && defined LIGHT_SHAFT

			if (isEyeInWater == 0) {

					vec4 screenPos  = vec4(gl_FragCoord.xy / vec2(viewWidth, viewHeight), gl_FragCoord.z, 1.0);
					vec4 viewPos    = gbufferProjectionInverse * (screenPos * 2.0 - 1.0);
					     viewPos   /= viewPos.w;
					vec3 nViewPos   = normalize(viewPos.xyz);

					float NdotU               = dot(nViewPos, upVec);
					      NdotU               = max(NdotU, 0.0);
					      NdotU               = 1.0 - NdotU;
					if    (NdotU > 0.5) NdotU = smoothstep(0.0, 1.0, NdotU);

					#if DIRECTION_LIGHTSHAFT == 3
					#endif
					#if DIRECTION_LIGHTSHAFT == 2
					NdotU *= NdotU;
					#endif
					#if DIRECTION_LIGHTSHAFT == 1
					NdotU *= NdotU;
					NdotU *= NdotU;
					#endif
					#if DIRECTION_LIGHTSHAFT == 0
					NdotU *= NdotU;
					NdotU *= NdotU;
					NdotU *= NdotU;
					#endif

					NdotU = mix(NdotU, 1.0, rainStrengthSp2 * 0.75);

					vl *= pow2(NdotU);

				#if defined OVERWORLD && defined LIGHT_SHAFT && defined SHINY_SUNRISE
				vec3 dayLightCol = lightCol2 * lightCol2 * lightCol2 ;
				#else
				vec3 dayLightCol = lightCol * lightCol * lightCol;
				#endif

				vec3 nightLightCol =lightCol * lightCol * 20.0;
				vec3 vlColor = mix(nightLightCol, dayLightCol, sunVisibility);

					vec3 weatherSky =weatherCol.rgb * weatherCol.rgb;
					     weatherSky*=GetLuminance(ambientCol / (weatherSky)) * 1.4;
					     weatherSky*=mix(SKY_RAIN_NIGHT, SKY_RAIN_DAY, sunVisibility);
					     weatherSky =max(weatherSky, skyColor * skyColor * 0.75);
					     weatherSky*=rainStrengthS;
					     vlColor    =mix(vlColor, weatherSky * 1.0, rainStrengthSp2);

				#if MC_VERSION >= 11800
				vl *= vlColor * clamp01(exp(2.0 * cameraPosition.y + 126.0));
				#else
				vl *= vlColor * clamp01(exp(2.0 * cameraPosition.y - 2.0));
				#endif

				float rainMult = mix(LIGHT_SHAFT_NIGHT_RAIN_MULTIPLIER* (0.25 + 0.2 * screenBrightness2),
											LIGHT_SHAFT_DAY_RAIN_MULTIPLIER * (0.65 + 0.2 * screenBrightness2),
											sunVisibility);

				float timeBrightnessSqrt = sqrt1(timeBrightness);

				vl*=mix(1.0, LIGHT_SHAFT_NOON_MULTIPLIER * 0.75, timeBrightnessSqrt * (1.0 - rainStrengthS * 0.8));
				vl*=mix((LIGHT_SHAFT_NIGHT_MULTIPLIER * 10) * (0.91 - moonBrightness * 0.39), 2.0, sunVisibility);
				vl*=mix(1.0, rainMult, rainStrengthSp2);

			} else

				vl *= length(lightCol) * 0.2 * LIGHT_SHAFT_UNDERWATER_MULTIPLIER / 10.0 * (1.0 - rainStrengthS * 0.85);

		#endif

		#if defined (END) && defined LIGHT_SHAFT_END
			vl *= endCol3.rgb * 0.1 * LIGHT_SHAFT_STRENGTH_END;
			vl *= LIGHT_SHAFT_STRENGTH * (1.0 - rainStrengthS * eBS * 0.875) * shadowFade * (1.0 + isEyeInWater * 1.5) * (1.0 - blindFactor);
		#endif

		#if defined (OVERWORLD) && defined LIGHT_SHAFT
			vl *= LIGHT_SHAFT_STRENGTH * shadowFade * (1.0 - blindFactor);

			float vlFactor = (1.0 - min((timeBrightness) * 2.0, 0.75));
			vlFactor = mix(vlFactor, 0.05, rainStrengthS);
			if (isEyeInWater == 1) vlFactor = 3.0;
			vl *= vlFactor * 1.15;
		#endif

		#if (defined OVERWORLD && defined LIGHT_SHAFT) || (defined END && defined LIGHT_SHAFT_END)
			color.rgb += vl * lightShaftTime;
		#endif

		/*DRAWBUFFERS:0*/
		gl_FragData[0] = vec4(color);
	}

#endif

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

	//Uniforms//
	uniform mat4 gbufferModelView;

	//Common Variables//
	#ifdef OVERWORLD
		float timeAngleM = timeAngle;
	#else
		float timeAngleM = 0.25;
	#endif

	//Program//
	void main(){
		texCoord=gl_MultiTexCoord0.xy;

		gl_Position=ftransform();

		const vec2 sunRotationData=vec2(cos(sunPathRotation * 0.01745329251994), -sin(sunPathRotation * 0.01745329251994));
		float ang                 =fract(timeAngleM - 0.25);
		      ang                 =(ang+(cos(ang * 3.14159265358979) * -0.5 + 0.5 - ang) / 3.0) * 6.28318530717959;
		      sunVec              =normalize((gbufferModelView * vec4(vec3(-sin(ang), cos(ang) * sunRotationData) * 2000.0, 1.0)).xyz);

		upVec=normalize(gbufferModelView[1].xyz);
	}

#endif