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


float CloudNoiseEnd(vec2 coord, vec2 wind){
	float noise = texture2D(noisetex, coord*1        + wind * 0.55).x;
		  noise+= texture2D(noisetex, coord*0.5      + wind * 0.45).x * -4.0;
		  noise+= texture2D(noisetex, coord*0.25     + wind * 0.35).x * 8.0;
		  noise+= texture2D(noisetex, coord*0.125    + wind * 0.25).x * -7.0;
		  noise+= texture2D(noisetex, coord*0.0625   + wind * 0.15).x * 25.0;
		  noise+= texture2D(noisetex, coord*0.03125  + wind * 0.05).x * 25.0;
		  noise+= texture2D(noisetex, coord*0.015625 + wind * 0.05).x * -10.0;
	return noise;
}

float CloudCoverageEnd(float noise,float cosT,float coverage){
	float noiseMix=mix(noise,21.,.33*rainStrengthS);
	float noiseFade=clamp(sqrt(cosT*10.),0.,1.);
	float noiseCoverage=((coverage*coverage)+ CLOUD_AMOUNT_END);
	float multiplier=1.-.5*rainStrengthS;
	
	return max(noiseMix*noiseFade-noiseCoverage,0.)*multiplier;
}

vec4 DrawEndCloud(vec3 viewPos,float dither,vec3 lightCol){
	float cosT=dot(normalize(viewPos),upVec);
	float cosS=dot(normalize(viewPos),sunVec);
	
	#if AA>1
	dither=fract(16.*frameTimeCounter+dither);
	#endif
	
	float cloud=0.;
	float cloudGradient=0.;
	float gradientMix=dither*.5;
	float colorMultiplier=CLOUD_BRIGHTNESS_END*(.5-.25*(1.-sunVisibility)*(1.-rainStrengthS));
	float noiseMultiplier=CLOUD_THICKNESS_END*.15;
	float scattering=pow(cosS*.5+.5,6.);
	
	vec2 wind=vec2(frameTimeCounter*CLOUD_SPEED_END*.005,
		sin(frameTimeCounter*CLOUD_SPEED_END*.05)*.002)*CLOUD_HEIGHT_END/25.;
		
		vec3 cloudcolor=vec3(0.);
		
	if(cosT>.1){
		vec3 wpos=normalize((gbufferModelViewInverse*vec4(viewPos,1.)).xyz);
		for(int i=0;i<24;i++){
			if(cloud>.99)break;
			vec3 planeCoord=wpos*((CLOUD_HEIGHT_END+(i+dither))/wpos.y)*.005*pow(cosT,-.1);
			vec2 coord=cameraPosition.xz*.00025+planeCoord.xz;
			float coverage=float(i-3.+dither)*.667;
			
			float noise=CloudNoiseEnd(coord,wind);
			noise=CloudCoverageEnd(noise,cosT,coverage)*noiseMultiplier;
			noise=noise/pow(pow(noise,2.5)+1.,.4);
			
			cloudGradient=mix(cloudGradient,
				mix(gradientMix*gradientMix,1.-noise,.25),
				noise*(1.-cloud*cloud));
				cloud=mix(cloud,1.,noise);
				gradientMix+=.6;
			}
			cloudcolor=lightCol*vec3(6.4,6.8,5.)*(1.+scattering)*pow(cloudGradient,.75);
			cloudcolor=pow(cloudcolor,vec3(2))*2*vec3(1.4,1.8,1.);
			cloud*=min(pow(cosT*2,2.),.42);
		}
		
		return vec4(cloudcolor*colorMultiplier*(.6+(pow(sunVisibility,.1))*.4),pow(cloud,2)*.1*CLOUD_OPACITY_END*(2-(pow(sunVisibility,.1))));
}