Files
stk-code/data/shaders/sp_displace_ssr.frag
T

80 lines
2.2 KiB
GLSL

in vec2 uv;
in vec3 normal;
in vec4 world_position;
layout(location = 0) out float o_displace_mask;
layout(location = 1) out vec4 o_displace_ssr;
#stk_include "utils/sp_texture_sampling.frag"
#stk_include "utils/screen_space_reflection.frag"
uniform samplerCube u_skybox_texture;
uniform sampler2D u_displace_color;
uniform sampler2DShadow u_depth;
uniform int u_ssr;
void main()
{
o_displace_mask = 1.0;
if (u_ssr == 0)
return;
float alpha = sampleTextureLayer0(uv).a;
if (alpha == 0.0)
{
o_displace_ssr = vec4(0.0);
return;
}
// eye-space position
vec3 xpos = (u_view_matrix * world_position).xyz;
// eye-space view direction (points from surface toward eye at origin)
vec3 eyedir = -normalize(xpos);
// eye-space normal
vec3 normal = (u_view_matrix * vec4(normalize(normal), 0)).xyz;
// bail out immediately if normal is facing away from the camera,
// dot(normal, eyedir) <= 0 means back-facing
float NdotV = dot(normal, eyedir);
if (NdotV <= 0.0)
{
o_displace_ssr = vec4(0.0);
return;
}
// compute reflection in eye-space
vec3 reflected = reflect(-eyedir, normal);
// bring it back into world-space
vec3 world_reflection = (u_inverse_view_matrix * vec4(reflected, 0.0)).xyz;
// fallback to skybox
vec4 fallback = texture(u_skybox_texture, world_reflection);
// early exit if normal is facing camera too directly (no meaningful reflection)
if (normal.z < -0.75)
{
o_displace_ssr = fallback;
return;
}
vec4 result;
vec2 viewport_scale = vec2(1.0);
vec2 viewport_offset = vec2(0.0);
vec2 coords = RayCast(reflected, xpos, u_projection_matrix, viewport_scale,
viewport_offset, u_depth);
if (coords.x < 0. || coords.x > 1. || coords.y < 0. || coords.y > 1.)
{
result = fallback;
}
else
{
result = texture(u_displace_color, coords);
float edge = GetEdgeFade(coords, viewport_scale, viewport_offset);
//float fresnel = pow(1.0 - NdotV, 2.0);
float fresnel = (1.0 - NdotV) * (1.0 - NdotV);
float blend_weight = edge * fresnel;
result = mix(fallback, result, blend_weight);
}
o_displace_ssr = result;
}