81 lines
2.3 KiB
GLSL
81 lines
2.3 KiB
GLSL
// 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);
|
|
} |