This repository has been archived on 2023-10-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
blender-archive/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl
Thomas Dinges 6b8bb26c45 EEVEE: Port existing EEVEE shaders and generated materials to use GPUShaderCreateInfo.
Required by Metal backend for efficient shader compilation. EEVEE material
resource binding permutations now controlled via CreateInfo and selected
based on material options. Other existing CreateInfo's also modified to
ensure explicitness for depth-writing mode. Other missing bindings also
addressed to ensure full compliance with the Metal backend.

Authored by Apple: Michael Parkin-White

Ref T96261

Reviewed By: fclem

Differential Revision: https://developer.blender.org/D16243
2022-12-08 21:12:19 +01:00

88 lines
2.6 KiB
GLSL

#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
#pragma BLENDER_REQUIRE(bsdf_common_lib.glsl)
#pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl)
#pragma BLENDER_REQUIRE(raytrace_lib.glsl)
#pragma BLENDER_REQUIRE(surface_lib.glsl)
/* ------------ Refraction ------------ */
#define BTDF_BIAS 0.85
vec4 screen_space_refraction(vec3 vP, vec3 N, vec3 V, float ior, float roughnessSquared, vec4 rand)
{
float alpha = max(0.002, roughnessSquared);
/* Importance sampling bias */
rand.x = mix(rand.x, 0.0, BTDF_BIAS);
vec3 T, B;
make_orthonormal_basis(N, T, B);
float pdf;
/* Microfacet normal */
vec3 H = sample_ggx(rand.xzw, alpha, V, N, T, B, pdf);
/* If ray is bad (i.e. going below the plane) regenerate. */
if (F_eta(ior, dot(H, V)) < 1.0) {
H = sample_ggx(rand.xzw * vec3(1.0, -1.0, -1.0), alpha, V, N, T, B, pdf);
}
vec3 vV = viewCameraVec(vP);
float eta = 1.0 / ior;
if (dot(H, V) < 0.0) {
H = -H;
eta = ior;
}
vec3 R = refract(-V, H, 1.0 / ior);
R = transform_direction(ViewMatrix, R);
Ray ray;
ray.origin = vP;
ray.direction = R * 1e16;
RayTraceParameters params;
params.thickness = ssrThickness;
params.jitter = rand.y;
params.trace_quality = ssrQuality;
params.roughness = roughnessSquared;
vec3 hit_pos;
bool hit = raytrace(ray, params, false, true, hit_pos);
if (hit && (F_eta(ior, dot(H, V)) < 1.0)) {
hit_pos = get_view_space_from_depth(hit_pos.xy, hit_pos.z);
float hit_dist = distance(hit_pos, vP);
float cone_cos = cone_cosine(roughnessSquared);
float cone_tan = sqrt(1 - cone_cos * cone_cos) / cone_cos;
/* Empirical fit for refraction. */
/* TODO: find a better fit or precompute inside the LUT. */
cone_tan *= 0.5 * fast_sqrt(f0_from_ior((ior < 1.0) ? 1.0 / ior : ior));
float cone_footprint = hit_dist * cone_tan;
/* find the offset in screen space by multiplying a point
* in camera space at the depth of the point by the projection matrix. */
float homcoord = ProjectionMatrix[2][3] * hit_pos.z + ProjectionMatrix[3][3];
/* UV space footprint */
cone_footprint = BTDF_BIAS * 0.5 * max(ProjectionMatrix[0][0], ProjectionMatrix[1][1]) *
cone_footprint / homcoord;
vec2 hit_uvs = project_point(ProjectionMatrix, hit_pos).xy * 0.5 + 0.5;
/* Texel footprint */
vec2 texture_size = vec2(textureSize(refractColorBuffer, 0).xy) / hizUvScale.xy;
float mip = log2(cone_footprint * max(texture_size.x, texture_size.y));
vec3 spec = textureLod(refractColorBuffer, hit_uvs * hizUvScale.xy, mip).xyz;
float mask = screen_border_mask(hit_uvs);
return vec4(spec, mask);
}
return vec4(0.0);
}