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

float CloudNoise(vec2 coord,vec2 wind){
float noise=texture2D(noisetex,coord*1+wind*.55).x;
noise+=texture2D(noisetex,coord*.5+wind*.45).x  * -4.0;
noise+=texture2D(noisetex,coord*.25+wind*.34).x * 6.0;
noise+=texture2D(noisetex,coord*.125+wind*.25).x * 8.0;
noise+=texture2D(noisetex,coord*.0625+wind*.15).x * 10.0;
noise+=texture2D(noisetex,coord*.03125+wind*.10).x * 8.0;
noise+=texture2D(noisetex,coord*.012500+wind*.5).x * 8.0;
noise+=texture2D(noisetex,coord*.025000+wind*.5).x * -12.0;
return noise;
}

float CloudCoverage(float noise, float coverage, float NdotU, float cosS) {
		float noiseCoverageCosS = abs(cosS);
		noiseCoverageCosS *= noiseCoverageCosS;
		noiseCoverageCosS *= noiseCoverageCosS;
		float NdotUmult = 0.365;

		float noiseCoverage = coverage * coverage + CLOUD_AMOUNT
								* (1.0 + noiseCoverageCosS * 0.175) 
								* (1.0 + NdotU * NdotUmult * (1.0-rainStrengthS*3.0))
								- 2.5;

		return max(noise - noiseCoverage, 0.0);
	}

vec4 DrawCloud(vec3 viewPos,float dither,vec3 lightCol,vec3 ambientCol, float NdotU){
	float cosS=dot(normalize(viewPos),sunVec);
	
	#if AA > 0
	dither=fract(16.*frameTimeCounter+dither);
	#endif
	
	float cloud=0.;
	float cloudGradient=0.;
	float gradientMix=dither*0.1667;
	float colorMultiplier=CLOUD_BRIGHTNESS*(.7-.25*clamp((1.-sunVisibility*DAY_CLOUD_VISIBILITY),0.0,1.0)*(1.-moonVisibility*NIGHT_CLOUD_VISIBILITY)*clamp((1.-rainStrengthS*RAIN_CLOUD_VISIBILITY),0.0,1.0));
	float noiseMultiplier=CLOUD_THICKNESS*0.9;
	float scattering=clamp(pow(cosS*0.5*(1.0*sunVisibility-1.)+1.5,8.0),0.0,1.0);
	
	vec2 wind=vec2(frameTimeCounter*(CLOUD_SPEED)*0.0005);
		
	vec3 cloudcolor=vec3(0.0);
		
	if(NdotU>0.0){
		vec3 wpos=normalize((gbufferModelViewInverse*vec4(viewPos,1.)).xyz);
		for(int i=0;i<CLOUD_QUALITY;i++){
			if(cloud>0.99)break;
			vec3 planeCoord=wpos*((CLOUD_HEIGHT+(i+dither))/wpos.y)*0.004;
			vec2 coord=cameraPosition.xz*0.00025+planeCoord.xz;
			float coverage=float(i-3.0+dither)*0.5;
			
			float noise=CloudNoise(coord,wind);
			noise=CloudCoverage(noise,coverage,NdotU,cosS)*(noiseMultiplier/6);
			noise = noise / sqrt(noise * noise + 1.0);
			
			cloudGradient=mix(cloudGradient,
				mix(gradientMix*gradientMix,1.-noise,.25),
				noise*(1.-cloud*cloud));
				cloud=mix(cloud,1.,noise);
				gradientMix+=.1;
			}
			cloudcolor=mix(ambientCol*(.5*sunVisibility+.5),
			lightCol*(1.+scattering),
			cloudGradient*cloud);
		
		cloudcolor.r*=(1.0 + sunVisibility*(0.25-timeBrightness*0.25)*(1-.4*rainStrengthS));
		cloudcolor+=lightNight*lightNight*lightNight*lightNight*2;
		cloud *= 1.0 - exp(- (10.0 - 9.5 * rainStrengthS) * NdotU);
		
	}
	
	return vec4(cloudcolor*colorMultiplier,pow(cloud,2)*CLOUD_OPACITY);
}