[Bf-blender-cvs] [ac88123e29d] master: Fix T96576: Light leaking when using normal maps with Multiscatter GGX

Lukas Stockner noreply at git.blender.org
Sat Apr 30 13:56:20 CEST 2022


Commit: ac88123e29d4e07101a4fb33de28429d5e033367
Author: Lukas Stockner
Date:   Sat Apr 30 13:49:45 2022 +0200
Branches: master
https://developer.blender.org/rBac88123e29d4e07101a4fb33de28429d5e033367

Fix T96576: Light leaking when using normal maps with Multiscatter GGX

The Multiscatter GGX code was missing the same-side checks for incoming and
outgoing directions w.r.t. to shading and geometry normal.

Should not be needed for the Glass variant since it intentionally has both
reflection and transmission.

===================================================================

M	intern/cycles/kernel/closure/bsdf_microfacet_multi.h

===================================================================

diff --git a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h
index c646c9ef01d..10027ae9f77 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h
@@ -438,11 +438,18 @@ ccl_device float3 bsdf_microfacet_multi_ggx_eval_reflect(ccl_private const Shade
     return make_float3(0.0f, 0.0f, 0.0f);
   }
 
+  float3 X, Y, Z;
+  Z = bsdf->N;
+
+  /* Ensure that the both directions are on the outside w.r.t. the shading normal. */
+  if (dot(Z, I) <= 0.0f || dot(Z, omega_in) <= 0.0f) {
+    *pdf = 0.0f;
+    return make_float3(0.0f, 0.0f, 0.0f);
+  }
+
   bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID);
 
   bool is_aniso = (bsdf->alpha_x != bsdf->alpha_y);
-  float3 X, Y, Z;
-  Z = bsdf->N;
   if (is_aniso)
     make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
   else
@@ -487,8 +494,20 @@ ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals kg,
   float3 X, Y, Z;
   Z = bsdf->N;
 
+  /* Ensure that the view direction is on the outside w.r.t. the shading normal. */
+  if (dot(Z, I) <= 0.0f) {
+    *pdf = 0.0f;
+    return LABEL_NONE;
+  }
+
+  /* Special case: Extremely low roughness.
+   * Don't bother with microfacets, just do specular reflection. */
   if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) {
     *omega_in = 2 * dot(Z, I) * Z - I;
+    if (dot(Ng, *omega_in) <= 0.0f) {
+      *pdf = 0.0f;
+      return LABEL_NONE;
+    }
     *pdf = 1e6f;
     *eval = make_float3(1e6f, 1e6f, 1e6f);
 #ifdef __RAY_DIFFERENTIALS__
@@ -518,14 +537,20 @@ ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals kg,
                            bsdf->ior,
                            use_fresnel,
                            bsdf->extra->cspec0);
+  *omega_in = X * localO.x + Y * localO.y + Z * localO.z;
+
+  /* Ensure that the light direction is on the outside w.r.t. the geometry normal. */
+  if (dot(Ng, *omega_in) <= 0.0f) {
+    *pdf = 0.0f;
+    return LABEL_NONE;
+  }
+
   if (is_aniso)
     *pdf = mf_ggx_aniso_pdf(localI, localO, make_float2(bsdf->alpha_x, bsdf->alpha_y));
   else
     *pdf = mf_ggx_pdf(localI, localO, bsdf->alpha_x);
   *eval *= *pdf;
 
-  *omega_in = X * localO.x + Y * localO.y + Z * localO.z;
-
 #ifdef __RAY_DIFFERENTIALS__
   *domega_in_dx = (2 * dot(Z, dIdx)) * Z - dIdx;
   *domega_in_dy = (2 * dot(Z, dIdy)) * Z - dIdy;



More information about the Bf-blender-cvs mailing list