// Volumetric Light From Windom Shaders, highly modified

//#define LightShaft

#ifdef LightShaft

#define WaterSmoky
#define WaterSmokyType 1 //[1 2] WARNING ONLY WORK ON ShaftMode 1. Mode 1 Manual Waving. Mode 2 Water Waving

#define LightShaftSamples 4 //[1 2 3 4 5 6 7 8 9 10 11 12]
#define Strength 1.0 //[2.0 1.8 1.6 1.4 1.2 1.0 0.8 0.6 0.4 0.2]
#define ShaftMode 1 //[1 2]
#define ColorFormat 2 //[1 2]
#define RaysLength 1.0 //[-1.0 -0.9 -0.8 -0.7 -0.6 -0.5 -0.4 -0.3 -0.2 -0.1 0.0 0.1 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0]
#define Sunrise 0.4 //[0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 2.2 2.4 2.6 2.8 3.0 3.2 3.4 3.6 3.8 4.0]
#define Noon 1.0 //[0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 2.2 2.4 2.6 2.8 3.0 3.2 3.4 3.6 3.8 4.0]
#define Sunset 0.4 //[0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 2.2 2.4 2.6 2.8 3.0 3.2 3.4 3.6 3.8 4.0]
#define Night 1.0 //[0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 2.2 2.4 2.6 2.8 3.0 3.2 3.4 3.6 3.8 4.0]

// struck time {

float lowsun = (tSunrise + tSunset);
float highsun = tNoon;
float highmoon = tNight;

#if (ColorFormat == 1)

	vec3 cLowS = (vec3(0.83)/inc)*Sunrise;
	vec3 cHighS = (vec3(0.5)/ref)*Noon;
	vec3 cHighM = (vec3(0.79)/ref)*Night;
	
#elif (ColorFormat == 2)

	vec3 cLowS = (vec3(0.9,0.4,0.1)/inc)*Sunrise;
	vec3 cHighS = (vec3(0.5)/ref)*Noon;
	vec3 cHighM = (vec3(0.9,0.4,0.1)/ref)*Night;

#endif

vec3 color = vec3((cLowS*lowsun)+(cHighS*highsun)+(cHighM*highmoon));

#if (ShaftMode == 1) //Detail

vec3 getSSGR(vec2 coord) {
	vec3 vL = vec3(0.0);
	float sample = LightShaftSamples;
	vec4 projectedSun = gbufferProjection*vec4(sunPosition, 1.0);
	vec2 screenSun = (projectedSun.xy / projectedSun.w) * 0.5 + 0.5;
	vec2 screenDepth = screenSun;
	vec2 sunDirection = coord-screenDepth;
	float bayers = bayer16(gl_FragCoord.xy);
	float z0 = texture2D(depthtex0, texcoord).r;
	float z1 = texture2D(depthtex1, texcoord * -10.0).r * RaysLength;
	
for (int i = 0; i < sample; ++i) {
	float comBine = (z1 + bayers);
	float currentDist = (i + comBine);
    vec2 steppedPos = sunDirection * ((currentDist) / 8) + screenDepth;
    float depth = texture2D(depthtex0, steppedPos).r;
    if (depth == 1.0)
    vL += texture2DLod(colortex1, steppedPos, 0.0).rgb*color/Strength;
#ifdef WaterSmoky
if (isEyeInWater == 1) {
 #if (WaterSmokyType == 1)
    vec3 WaterDepth = vec3(0.25,0.45,0.9)*1.5;
    vec3 sL = texture2D(noisetex, steppedPos + frameTimeCounter * 0.07).r*WaterDepth/Strength;
    vec3 aL = texture2D(noisetex, steppedPos - frameTimeCounter * 0.07).r*WaterDepth/Strength;
    vL += mix(sL, aL, vL);
 #elif (WaterSmokyType == 2)
    vec3 WaterDepth = vec3(0.4,0.8,1.0)*3.5;
    if (i < 8) vL += texture2D(colortex1, steppedPos, 1.0).r*WaterDepth/Strength;
 #endif
}
#endif
}

if (visibility != 1.0) {
	if (z0 == z1) {
	  vL += 0.5;
    }
}

vL *= (9.0, caveFactor);;

return vL / 23.3;

}

#elif (ShaftMode == 2) //Optimized
vec3 getSSGR(vec2 coord) { vec3 ssgr = vec3(0.0); vec4 projectedSun = gbufferProjection*vec4(sunPosition, 1.0); vec2 screenSun = ((projectedSun.xyz/projectedSun.w)*0.5+0.5).xy; vec2 sunDirection = coord-screenSun; for (int i = 0; i < LightShaftSamples; ++i) { vec2 steppedPos = sunDirection * ((i+bayer8(gl_FragCoord.xy)) / LightShaftSamples) + screenSun; float depth = texture2D(depthtex0, steppedPos).r; if (depth == 1.0) ssgr += texture2DLod(colortex1, steppedPos, 1.0).rgb*color/Strength; } return ssgr / 28.0; }
#endif

#endif