Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2021-05-27 18:10:17 +0300
committerClément Foucault <foucault.clem@gmail.com>2021-05-27 18:12:23 +0300
commitba4228bcf77e50368a7c84affd5e380bd45789a7 (patch)
tree2d914f66b60c32139f0e68a71eb6d1dbbe35c92e
parentc07c7957c6b4780b643e0e056a78a56b3e08f51b (diff)
Revert "EEVEE: Ensure Reflection: Use new implementation"
Both before and after can have artifacts with some normal maps, but this seems to give worse artifacts on average which are not worth the minor performance increase. This reverts commit 5c4d24e1fd752a8a89d44d05e8e3f9b31f2d7db0. Ref T88368, D10084
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl65
1 files changed, 45 insertions, 20 deletions
diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
index fdbb70e917d..c8eaa06094e 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
@@ -138,30 +138,55 @@ void accumulate_light(vec3 light, float fac, inout vec4 accum)
/* Same thing as Cycles without the comments to make it shorter. */
vec3 ensure_valid_reflection(vec3 Ng, vec3 I, vec3 N)
{
- vec3 R;
- float NI = dot(N, I);
- float NgR, threshold;
- /* Check if the incident ray is coming from behind normal N. */
- if (NI > 0.0) {
- /* Normal reflection. */
- R = (2.0 * NI) * N - I;
- NgR = dot(Ng, R);
- /* Reflection rays may always be at least as shallow as the incoming ray. */
- threshold = min(0.9 * dot(Ng, I), 0.01);
- if (NgR >= threshold) {
- return N;
+ vec3 R = -reflect(I, N);
+
+ /* Reflection rays may always be at least as shallow as the incoming ray. */
+ float threshold = min(0.9 * dot(Ng, I), 0.025);
+ if (dot(Ng, R) >= threshold) {
+ return N;
+ }
+
+ float NdotNg = dot(N, Ng);
+ vec3 X = normalize(N - NdotNg * Ng);
+
+ float Ix = dot(I, X), Iz = dot(I, Ng);
+ float Ix2 = sqr(Ix), Iz2 = sqr(Iz);
+ float a = Ix2 + Iz2;
+
+ float b = sqrt(Ix2 * (a - sqr(threshold)));
+ float c = Iz * threshold + a;
+
+ float fac = 0.5 / a;
+ float N1_z2 = fac * (b + c), N2_z2 = fac * (-b + c);
+ bool valid1 = (N1_z2 > 1e-5) && (N1_z2 <= (1.0 + 1e-5));
+ bool valid2 = (N2_z2 > 1e-5) && (N2_z2 <= (1.0 + 1e-5));
+
+ vec2 N_new;
+ if (valid1 && valid2) {
+ /* If both are possible, do the expensive reflection-based check. */
+ vec2 N1 = vec2(sqrt(1.0 - N1_z2), sqrt(N1_z2));
+ vec2 N2 = vec2(sqrt(1.0 - N2_z2), sqrt(N2_z2));
+
+ float R1 = 2.0 * (N1.x * Ix + N1.y * Iz) * N1.y - Iz;
+ float R2 = 2.0 * (N2.x * Ix + N2.y * Iz) * N2.y - Iz;
+
+ valid1 = (R1 >= 1e-5);
+ valid2 = (R2 >= 1e-5);
+ if (valid1 && valid2) {
+ N_new = (R1 < R2) ? N1 : N2;
}
+ else {
+ N_new = (R1 > R2) ? N1 : N2;
+ }
+ }
+ else if (valid1 || valid2) {
+ float Nz2 = valid1 ? N1_z2 : N2_z2;
+ N_new = vec2(sqrt(1.0 - Nz2), sqrt(Nz2));
}
else {
- /* Bad incident. */
- R = -I;
- NgR = dot(Ng, R);
- threshold = 0.01;
+ return Ng;
}
- /* Lift the reflection above the threshold. */
- R = R + Ng * (threshold - NgR);
- /* Find a bisector. */
- return safe_normalize(I * length(R) + R * length(I));
+ return N_new.x * X + N_new.y * Ng;
}
/* ----------- Cone angle Approximation --------- */