float distx(float dist){
	return(far*(dist-near))/(dist*(far-near));
}

float getDepth(float depth){
	return 2.*near*far/(far+near-(2.*depth-1.)*(far-near));
}

vec4 distortShadow(vec4 shadowpos,float distortFactor){
	shadowpos.xy*=1./distortFactor;
	shadowpos.z=shadowpos.z*.2;
	shadowpos=shadowpos*.5+.5;
	
	return shadowpos;
}

vec4 getShadowSpace(float shadowdepth,vec2 texCoord){
	vec4 viewPos=gbufferProjectionInverse*(vec4(texCoord,shadowdepth,1.)*2.-1.);
	viewPos/=viewPos.w;
	
	vec4 wpos=gbufferModelViewInverse*viewPos;
	wpos=shadowModelView*wpos;
	wpos=shadowProjection*wpos;
	wpos/=wpos.w;
	
	float distb=sqrt(wpos.x*wpos.x+wpos.y*wpos.y);
	float distortFactor=1.-shadowMapBias+distb*shadowMapBias;
	wpos=distortShadow(wpos,distortFactor);
	
	return wpos;
}

//Volumetric light from Robobo1221 (modified)
vec3 getVolumetricRays(float pixeldepth0,float pixeldepth1,vec3 color,float dither){
	vec3 vl=vec3(0.);
	
	#if AA==2
	dither=fract(dither+frameCounter/32.);
	#endif
	
	vec4 viewPos=gbufferProjectionInverse*(vec4(texCoord.x,texCoord.y,pixeldepth0,1.)*2.-1.);
	viewPos/=viewPos.w;
	
	#ifdef OVERWORLD
	vec3 lightVec=sunVec*(1.-2.*float(timeAngle>.5325&&timeAngle<.9675));
	float cosS=dot(normalize(viewPos.xyz),lightVec);
	float visfactor=.05*(-.8*timeBrightness+1.)*(3.*rainStrength+1.);
	float invvisfactor=1.-visfactor;
	
	float visibility=clamp(cosS*.5+.5,0.,1.);
	visibility=clamp((visfactor/(1.-invvisfactor*visibility)-visfactor)*
1.015/invvisfactor-.015,0.,1.);
visibility=mix(1.,visibility,.25*eBS+.75)*.14285;
#endif

#ifdef END
float visibility=.14285;
#endif

if(visibility>0.){
	float maxDist=128.;
	
	float depth0=getDepth(pixeldepth0);
	float depth1=getDepth(pixeldepth1);
	vec4 worldposition=vec4(0.);
	
	vec3 watercol=waterColor.rgb*sqrt(waterColor.a/waterAlpha);
	
	for(int i=0;i<7;i++){
		float minDist=pow(2.,i+dither)-.9;
		if(minDist>=maxDist)break;
		
		if(depth1<minDist||(depth0<minDist&&color==vec3(0.))){
			break;
		}
		
		worldposition=getShadowSpace(distx(minDist),texCoord.st);
		worldposition.z+=.00002;
		
		if(length(worldposition.xy*2.-1.)<1.){
			vec3 sample=vec3(shadow2D(shadowtex0,worldposition.xyz).z);
			
			vec3 colsample=vec3(0.);
			#ifdef SHADOW_COLOR
			if(sample.r<.9){
				float testsample=shadow2D(shadowtex1,worldposition.xyz).z;
				if(testsample>.9){
					colsample=texture2D(shadowcolor0,worldposition.xy).rgb;
					colsample*=colsample;
					sample=colsample*(1.-sample)+sample;
				}
			}
			#endif
			if(depth0<minDist)sample*=color;
			else if(isEyeInWater==1.)sample*=watercol;
			
			vl+=sample;
		}
		else{
			vl+=1.;
		}
	}
	vl=sqrt(vl*visibility);
}

return vl;
}