1
0
Fork 0
fgdata/Shaders/HDR/water_shading.frag
Fernando García Liñán f53a170539 HDR: Better bloom effect
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.
2023-04-13 00:30:02 +02:00

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;
}