float fovmult=gbufferProjection[1][1]/1.37373871;

float BaseLens(vec2 lightPos,float size,float dist,float hardness){
	vec2 lensCoord=(texCoord+(lightPos*dist-.5))*vec2(aspectRatio,1.);
	float lens=clamp(1.-length(lensCoord)/(size*fovmult),0.,1./hardness)*hardness;
	lens*=lens;lens*=lens;
	return lens;
}

float OverlapLens(vec2 lightPos,float size,float dista,float distb){
	return BaseLens(lightPos,size,dista,2.)*BaseLens(lightPos,size,distb,2.);
}

float PointLens(vec2 lightPos,float size,float dist){
	return BaseLens(lightPos,size,dist,1.5)+BaseLens(lightPos,size*4.,dist,1.)*.5;
}

float RingLensTransform(float lensFlare){
	return pow(1.-pow(1.-pow(lensFlare,.25),10.),5.);
}
float RingLens(vec2 lightPos,float size,float distA,float distB){
	float lensFlare1=RingLensTransform(BaseLens(lightPos,size,distA,1.));
	float lensFlare2=RingLensTransform(BaseLens(lightPos,size,distB,1.));
	
	float lensFlare=clamp(lensFlare2-lensFlare1,0.,1.);
	lensFlare*=sqrt(lensFlare);
	return lensFlare;
}

float AnamorphicLens(vec2 lightPos){
	vec2 lensCoord=abs(texCoord-lightPos.xy-.5)*vec2(aspectRatio*.1,2.);
	float lens=clamp(1.-length(pow(lensCoord,vec2(.85)))*4./fovmult,0.,1.);
	lens*=lens*lens;
	return lens;
}

vec3 AddLens(float lens,vec3 color,float truePos){
	float isMoon=truePos*.5+.5;
	
	vec3 lensColor=mix(color,GetLuminance(color)*lightNight*.80,isMoon*.98);
	float visibility=mix(sunVisibility,moonVisibility,isMoon);
	return lens*lensColor*visibility;
}

float getLensVisibilityA(vec2 lightPos){
	float str=length(lightPos*vec2(aspectRatio,1.));
	return pow(clamp(str*8.,0.,1.),2.)-clamp(str*3.-1.5,0.,1.);
}

float getLensVisibilityB(vec2 lightPos){
	float str=length(lightPos*vec2(aspectRatio,1.));
	return(1.-clamp(str*3.-1.5,0.,1.));
}

void LensFlare(inout vec3 color,vec2 lightPos,float truePos,float multiplier){
	float visibilityA=getLensVisibilityA(lightPos);
	float visibilityB=getLensVisibilityB(lightPos);
	multiplier*=multiplier;
	
	if(visibilityB>.001){
		vec3 lensFlare=(
			AddLens(BaseLens(lightPos,.4,-.45,1.),vec3(2.2,1.2,.1),truePos)*.08+
			AddLens(BaseLens(lightPos,.4,.10,1.),vec3(2.2,.4,.1),truePos)*.04+
			AddLens(BaseLens(lightPos,.4,.30,1.),vec3(2.2,.2,.1),truePos)*.05+
			AddLens(BaseLens(lightPos,.4,.50,1.),vec3(2.2,.4,2.5),truePos)*.06+
			AddLens(BaseLens(lightPos,.4,.70,1.),vec3(1.8,.4,2.5),truePos)*.07+
			AddLens(BaseLens(lightPos,.4,.90,1.),vec3(.1,.2,2.5),truePos)*.08+
			
			AddLens(OverlapLens(lightPos,.09,-.28,-.39),vec3(2.5,1.2,.1),truePos)*.016+
			AddLens(OverlapLens(lightPos,.09,-.20,-.31),vec3(2.5,.5,.1),truePos)*.011+
			AddLens(OverlapLens(lightPos,.13,.06,.19),vec3(2.5,.2,.1),truePos)*.021+
			AddLens(OverlapLens(lightPos,.13,.15,.28),vec3(1.8,.1,1.2),truePos)*.016+
			AddLens(OverlapLens(lightPos,.13,.24,.37),vec3(1.,.1,2.5),truePos)*.011+
			
			AddLens(PointLens(lightPos,.04,-.55),vec3(2.5,1.6,0.),truePos)*.21+
			AddLens(PointLens(lightPos,.03,-.40),vec3(2.5,1.,0.),truePos)*.16+
			AddLens(PointLens(lightPos,.05,.43),vec3(2.5,.6,.6),truePos)*.21+
			AddLens(PointLens(lightPos,.03,.60),vec3(.2,.6,2.5),truePos)*.16+
			AddLens(PointLens(lightPos,.04,.67),vec3(.7,1.1,3.),truePos)*.26+
			
			AddLens(RingLens(lightPos,.22,.44,.46),vec3(.10,.35,2.50),truePos)+
			AddLens(RingLens(lightPos,.15,.98,.99),vec3(.15,.40,2.55),truePos)*2.5
		)*visibilityA+(
			AddLens(AnamorphicLens(lightPos),vec3(.3,.7,1.),truePos)*.5
		)*visibilityB;
		
		color=mix(color,vec3(1.),lensFlare*multiplier);
	}
}