#ifdef OVERWORLD
	vec3 GetFogColor(vec3 viewPos) {
		vec3 nViewPos = normalize(viewPos);
		float lViewPos = length(viewPos) / 64.0;
		lViewPos = 1.0 - exp(- lViewPos * lViewPos);

		float VoU = clampInv11(dot(nViewPos, upVec));
		float VoL = clampInv11(dot(nViewPos, sunVec));

		float density = 0.3;
		float nightDensity = 1.0;
		float weatherDensity = 1.5;

		float exposure = exp2(timeBrightness * 0.75 - 0.75);
		float nightExposure = exp2(- 3.5);

		float baseGradient = exp(- (VoU * 0.5 + 0.5) * 0.5 / density);

		vec3 fog = fogCol * baseGradient / pow2(SKY_I);
		fog = fog / sqrt(fog * fog + 1.0) * exposure * sunVisibility * pow2(SKY_I);

		float sunMix = (VoL * 0.5 + 0.5) * pow(clamp01(1.0 - VoU), 2.0 - sunVisibility) * pow(1.0 - exposure * 0.6, 3.0);
		float horizonMix = pow(1.0 - abs(VoU), 2.5) * 0.125;
		float lightMix = (1.0 - (1.0 - sunMix) * (1.0 - horizonMix)) * lViewPos;

		vec3 lightFog = pow(lightSun, vec3(4.0 - sunVisibility)) * baseGradient;
		lightFog = lightFog / (1.0 + lightFog * rainStrengthS);

		fog = mix(sqrt(fog * (1.0 - lightMix)), sqrt(lightFog), lightMix);
		fog *= fog;

		float nightGradient = exp(- (VoU * 0.5 + 0.5) * 0.35 / nightDensity);
		vec3 nightFog = pow2(lightNight) * nightGradient * nightExposure;
		nightFog *= mix(SKY_NIGHT, 1.0, sunVisibility);
		fog = mix(nightFog, fog, pow2(sunVisibility));

		float rainGradient = exp(- (VoU * 0.5 + 0.5) * 0.125 / weatherDensity);
		vec3 weatherFog = pow2(weatherCol.rgb);
		weatherFog *= GetLuminance(ambientCol / (weatherFog)) * (0.2 * sunVisibility + 0.2);
		fog = mix(fog, weatherFog * rainGradient, rainStrengthS);

		#ifdef UNDERGROUND_FOG
			fog = mix(minLightCol * 0.1, fog * eBS, eBS);
		#endif

		#if MC_VERSION >=11800
			fog *= clamp01((cameraPosition.y + 70.0) * 0.125);
		#else
			fog *= clamp01((cameraPosition.y + 6.0) * 0.125);
		#endif

		return fog;
	}
#endif

vec3 NormalFog(vec3 color, vec3 viewPos) {
	float fogFactor = 0.0;
	float fog = 0.0;
	float viewLength = length(viewPos);
	vec3 fogColor = vec3(1.0);

	#if DISTANT_FADE > 0
		#if DISTANT_FADE_STYLE == 0
			fogFactor = length(viewPos);
		#else
			vec4 worldPos = gbufferModelViewInverse * vec4(viewPos, 1.0);
			worldPos.xyz /= worldPos.w;
			fogFactor = length(worldPos.xz);
		#endif
	#endif

#ifdef OVERWORLD
	float fogDensity = OVERWORLD_FOG_DENSITY;

			#if SUNVISIBILITY_FOG==1
				fogDensity *= 3.0 - sunVisibility * 2.0;

			#elif SUNVISIBILITY_FOG==2
				fogDensity *= 4.0 - sunVisibility * 3.0;

			#elif SUNVISIBILITY_FOG==3
				fogDensity *= 5.0 - sunVisibility * 4.0;

			#elif SUNVISIBILITY_FOG==4
				fogDensity *= 6.0 - sunVisibility * 5.0;
			#endif

	fog = length(viewPos) * fogDensity / 256.0;
	float clearDay = sunVisibility * (1.0 - rainStrengthS);

	if (isEyeInWater == 0) {
		#ifdef UNDERGROUND_FOG
			fog *= mix(1.0, (RAIN_FOG_DENSITY * rainStrengthS + 1.0) / (3.0 * clearDay + 1.0) * eBS, eBS);
			fog = 1.0 - exp(- 2.0 * pow(fog, 0.35 * clearDay * eBS + 0.95));
		#else
			fog *= (RAIN_FOG_DENSITY * rainStrengthS + 1.0) / (3.0 * clearDay + 1.0);
			fog = 1.0 - exp(- 2.0 * pow(fog, 0.35 * clearDay + 1.25) * eBS);
		#endif

		fogColor *= GetFogColor(viewPos);
	}
	if (isEyeInWater > 0) {
		fog *= (0.5 * rainStrengthS + 1.0) / (3.0 * clearDay + 3.0);
		fog = 1.0 - exp(- 2.0 * pow(fog, 0.35 * clearDay + 8.0) * eBS);
		fogColor *= GetFogColor(viewPos);
	}

	#if DISTANT_FADE == 1 || DISTANT_FADE == 3
		if (isEyeInWater == 0) {

			float fogOffset = 12.0;
			#if MC_VERSION >= 11800
				fogOffset = 0.0;

			#endif

			float vanillaFog = 1.0 - (far - (fogFactor + fogOffset)) * 5.0 / (OVERWORLD_FOG_DENSITY * far);

			vanillaFog = clamp01(vanillaFog);

			if (vanillaFog > 0.0) {
				vec3 vanillaFogColor = GetSkyColor(viewPos, false);
				vanillaFogColor *= 1.0 + nightVision;

				#ifdef CLASSIC_EXPOSURE
					vanillaFogColor *= 4.0 - 3.0 * eBS;
				#endif

				fogColor *= fog;

				fog = mix(fog, 1.0, vanillaFog);
				if (fog > 0.0)
					fogColor = mix(fogColor, vanillaFogColor, vanillaFog) / fog;
			}
		}
	#endif

#endif

#ifdef NETHER
	fog = 2.0 * pow(viewLength * NETHER_FOG_DENSITY / 256.0, 1.5);

	#if DISTANT_FADE == 2 || DISTANT_FADE == 3
		fog += 2.0 * pow(fogFactor / far, 6.0);
	#endif

	fog = 1.0 - exp(- fog);
	fogColor = netherCol.rgb * NETHER_FOG_COLOR_M;
#endif

#ifdef END
	fogColor = vec3(0.0);

	fog = 2.0 * pow(viewLength * END_FOG_DENSITY / 256.0, 1.5);

	#if DISTANT_FADE == 2 || DISTANT_FADE == 3
		fog += 6.0 * pow(fogFactor / far, 6.0);
	#endif

	fog = 1.0 - exp(- fog);

	if (isEyeInWater == 1) {
		fogColor = endCol.rgb * 0.009;
	} else {
		fogColor = endCol.rgb * 0.04;
	}

#endif

	color.rgb = mix(color.rgb, fogColor, fog);

	return color.rgb;
}

vec3 BlindFog(vec3 color, vec3 viewPos) {
	float viewLength = length(viewPos);
	float fog = viewLength * (blindFactor * 0.2);
	fog = (1.0 - exp(- 6.0 * pow3(fog))) * blindFactor;
	color.rgb = mix(color.rgb, vec3(0.0), fog);

	return color;
}

#ifdef ENABLE_DARKNESS_EFFECT
	#if MC_VERSION >= 11900
		vec3 DarknessFog(vec3 color, vec3 viewPos) {
			float viewLength = length(viewPos);
					#if DARKNESS_HARD_FOG == 0
						float fog = 2.0 * pow(viewLength * DARKNESS_FOG_DISTANCE / 256.0, 0.8);
					#else
						float fog = viewLength * 0.01 * DARKNESS_FOG_DISTANCE;
					#endif
			fog = (1.0 - exp(- 6.0 * pow3(fog))) * darknessFactor;
			color.rgb = mix(color.rgb, darknessColor, fog);

			return color;
		}
	#endif
#endif

vec3 LavaFog(vec3 color, vec3 viewPos) {
	float fog = length(viewPos) * LAVA_FOG_STRENGTH;
	fog = (1.0 - exp(- 4.0 * pow3(fog)));

		#if MC_VERSION >=11700
			if (gl_Fog.start / far < 0.0) {

				fog = min(length(viewPos) * 0.01, 1.0);
			}
		#endif

	color.rgb = mix(color.rgb, vec3(1.0, 0.3, 0.01), fog);

	return color;
}

vec3 SnowFog(vec3 color, vec3 viewPos) {
	float fog = length(viewPos) * POWDER_SNOW_FOG_STRENGTH;
	fog = (1.0 - exp(- 1.0 * pow3(fog)));
	color.rgb = mix(color.rgb, vec3(0.1, 0.15, 0.2), fog);

	return color;
}

vec3 Fog(vec3 color, vec3 viewPos) {

	color.rgb = NormalFog(color, viewPos);

	if (isEyeInWater == 2) {
		color.rgb = LavaFog(color.rgb, viewPos);
	}
	if (blindFactor > 0.0) {
		color.rgb = BlindFog(color.rgb, viewPos);
	}

	#if MC_VERSION >= 11701
		if (isEyeInWater == 3) {
			color.rgb = SnowFog(color.rgb, viewPos);
		}
	#endif

	#ifdef ENABLE_DARKNESS_EFFECT
		#if MC_VERSION >= 11900
			if (darknessFactor > 0.001) {
				color.rgb = DarknessFog(color.rgb, viewPos);
			}
		#endif
	#endif

	return color;
}