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
88 lines
2.6 KiB
GLSL
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);
|
|
}
|