83 lines
2.3 KiB
GLSL
83 lines
2.3 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;
|
||
|
|
||
|
// math.glsl
|
||
|
float M_PI();
|
||
|
float M_1_PI();
|
||
|
float pow5(float x);
|
||
|
// 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) * pow5(clamp(1.0 - VdotH, 0.0, 1.0));
|
||
|
}
|
||
|
|
||
|
float D_GGX(float NdotH, float a2)
|
||
|
{
|
||
|
float f = (NdotH * a2 - NdotH) * NdotH + 1.0;
|
||
|
return a2 / (M_PI() * f * f);
|
||
|
}
|
||
|
|
||
|
void main()
|
||
|
{
|
||
|
// Unpack G-Buffer
|
||
|
vec4 gbuffer0 = texture(gbuffer0_tex, texcoord);
|
||
|
vec4 gbuffer1 = texture(gbuffer1_tex, texcoord);
|
||
|
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 VdotH = max(dot(V, H), 1e-4);
|
||
|
float NdotL = max(dot(N, L), 1e-4);
|
||
|
float NdotV = max(dot(N, V), 1e-4);
|
||
|
float NdotH = max(dot(N, H), 1e-4);
|
||
|
|
||
|
const float f0 = 0.02; // For IOR = 1.33
|
||
|
float fresnel = F_Schlick(NdotV, f0);
|
||
|
|
||
|
// Refracted light, diffuse light coming from the sea floor
|
||
|
vec3 sky_color = textureLod(prefiltered_envmap_tex, ws_N, 4.0).rgb;
|
||
|
vec3 refracted = (1.0 - f0) * sea_color * sky_color * M_1_PI();
|
||
|
// Reflected light, specular light coming from the sky
|
||
|
vec3 reflected = textureLod(prefiltered_envmap_tex, ws_refl, 0.0).rgb * M_1_PI();
|
||
|
|
||
|
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;
|
||
|
}
|