f53a170539
We also now pre-expose our lighting before writing to the HDR buffers. This solves some precision issues and prevents the Sun from producing infinite values.
83 lines
2.2 KiB
GLSL
83 lines
2.2 KiB
GLSL
#version 330 core
|
|
|
|
layout(location = 0) out vec3 fragColor;
|
|
|
|
in vec2 texcoord;
|
|
|
|
uniform sampler2D gbuffer0_tex;
|
|
uniform sampler2D gbuffer1_tex;
|
|
uniform samplerCube prefiltered_envmap_tex;
|
|
|
|
uniform mat4 fg_ViewMatrixInverse;
|
|
uniform vec3 fg_SunDirection;
|
|
|
|
const float MAX_PREFILTERED_LOD = 4.0;
|
|
|
|
// math.glsl
|
|
float M_PI();
|
|
float M_1_PI();
|
|
// normal_encoding.glsl
|
|
vec3 decode_normal(vec2 f);
|
|
// pos_from_depth.glsl
|
|
vec3 get_view_space_from_depth(vec2 uv);
|
|
// aerial_perspective.glsl
|
|
vec3 add_aerial_perspective(vec3 color, vec2 coord, float depth);
|
|
vec3 get_sun_radiance_sea_level();
|
|
// exposure.glsl
|
|
vec3 apply_exposure(vec3 color);
|
|
|
|
float F_Schlick(float VdotH, float F0)
|
|
{
|
|
return F0 + (1.0 - F0) * pow(clamp(1.0 - VdotH, 0.0, 1.0), 5.0);
|
|
}
|
|
|
|
float D_GGX(float NdotH, float a2)
|
|
{
|
|
float f = (NdotH * a2 - NdotH) * NdotH + 1.0;
|
|
return a2 / (M_PI() * f * f);
|
|
}
|
|
|
|
void main()
|
|
{
|
|
vec4 gbuffer0 = texture(gbuffer0_tex, texcoord);
|
|
vec4 gbuffer1 = texture(gbuffer1_tex, texcoord);
|
|
|
|
// Unpack G-Buffer
|
|
vec3 N = decode_normal(gbuffer0.rg);
|
|
vec3 sea_color = gbuffer1.rgb;
|
|
|
|
vec3 P = get_view_space_from_depth(texcoord);
|
|
vec3 V = normalize(-P);
|
|
vec3 L = fg_SunDirection;
|
|
|
|
vec3 refl = reflect(-V, N);
|
|
vec3 ws_N = (fg_ViewMatrixInverse * vec4(N, 0.0)).xyz;
|
|
vec3 ws_refl = (fg_ViewMatrixInverse * vec4(refl, 0.0)).xyz;
|
|
|
|
vec3 H = normalize(L + V);
|
|
float NdotL = clamp(dot(N, L), 0.0, 1.0);
|
|
float NdotV = clamp(abs(dot(N, V)), 0.001, 1.0);
|
|
float NdotH = clamp(dot(N, H), 0.0, 1.0);
|
|
|
|
const float f0 = 0.02; // For IOR=1.33
|
|
float fresnel = F_Schlick(NdotV, f0);
|
|
|
|
// Refracted light
|
|
vec3 Esky = textureLod(prefiltered_envmap_tex, ws_N, MAX_PREFILTERED_LOD).rgb;
|
|
vec3 refracted = sea_color * Esky * M_1_PI();
|
|
// Reflected sky light
|
|
vec3 reflected = textureLod(prefiltered_envmap_tex, ws_refl, 1.0).rgb;
|
|
|
|
vec3 color = mix(refracted, reflected, fresnel);
|
|
|
|
// Add reflected Sun light
|
|
vec3 sun_intensity = get_sun_radiance_sea_level();
|
|
color += M_1_PI() * fresnel * D_GGX(NdotH, 0.001) * sun_intensity * NdotL;
|
|
|
|
color = add_aerial_perspective(color, texcoord, length(P));
|
|
|
|
// Pre-expose
|
|
color = apply_exposure(color);
|
|
|
|
fragColor = color;
|
|
}
|