// MinecraftPT — Volumetric_FS // Volumetric fog + volumetric clouds ray marched per-pixel and composited. #include "/Lib/Settings.glsl" #include "/Lib/Utilities.glsl" #include "/Lib/BasicFunctions/LightingConstants.glsl" #include "/Lib/BasicFunctions/TemporalNoise.glsl" #include "/Lib/IndividualFunctions/VolumetricFog.glsl" #include "/Lib/IndividualFunctions/WaterFog.glsl" #include "/Lib/IndividualFunctions/PlanarClouds.glsl" #include "/Lib/IndividualFunctions/CloudShadow.glsl" uniform sampler2D colortex12; // HDR scene layout(location = 0) out vec4 colorOut; void main(){ vec2 texelCoord = gl_FragCoord.xy; vec3 sceneColor = texelFetch(colortex12, ivec2(texelCoord), 0).rgb; float depth = texelFetch(depthtex0, ivec2(texelCoord), 0).r; // Reconstruct view position vec4 viewPos = gbufferProjectionInverse * vec4(texelCoord / screenSize * 2.0 - 1.0, depth * 2.0 - 1.0, 1.0); viewPos.xyz /= viewPos.w; vec3 worldPos = gbufferModelViewInverse[3].xyz + viewPos.xyz; // Dithering for the ray march float dither = BlueNoiseTemporal(); // Volumetric fog accumulation vec3 fogColor = vec3(0.0); float transmittance = 1.0; // Ray march toward the surface int steps = VFOG_QUALITY; float dist = length(viewPos.xyz); float stepSize = dist / float(steps); vec3 rayDir = normalize(viewPos.xyz); vec3 marchPos = worldPos; float time = frameTimeCounter * 0.05; for (int i = 0; i < steps; i++){ float t = (float(i) + dither) * stepSize; vec3 samplePos = marchPos - rayDir * t; float density = GetVolumetricFogDensity(samplePos, time); density *= stepSize; // Sun scattering float phase = 0.5 + 0.5 * dot(normalize(GetSunDirWorld()), -rayDir); vec3 inscatter = GetFogColor(samplePos, GetSunDirWorld()) * density * phase; fogColor += transmittance * inscatter; transmittance *= exp(-density); } // Cloud shadow on fog #ifdef VFOG_CLOUD_SHADOW float cloudShadow = GetCloudShadow(worldPos); fogColor *= cloudShadow; #endif // Combine vec3 finalColor = sceneColor * transmittance + fogColor; // Water fog (underwater) #ifdef UNDERWATER_VFOG if (isEyeInWater > 0){ vec3 waterColor = GetWaterFogColor(worldPos); float waterFog = 1.0 - exp(-dist * GetWaterFogDensity(worldPos) * UNDERWATER_VFOG_DENSITY); finalColor = mix(finalColor, waterColor * 3.0, waterFog); } #endif colorOut = vec4(finalColor, 1.0); }