[Bf-blender-cvs] [fbc884d2a82] master: Ensure BSDF evals and pdfs are zero on invalid samples

Sebastian Herholz noreply at git.blender.org
Thu Apr 28 18:14:16 CEST 2022


Commit: fbc884d2a82951c3a8c0f92993de3a0eb9907d86
Author: Sebastian Herholz
Date:   Thu Apr 28 18:03:24 2022 +0200
Branches: master
https://developer.blender.org/rBfbc884d2a82951c3a8c0f92993de3a0eb9907d86

Ensure BSDF evals and pdfs are zero on invalid samples

Currently, the `eval` and `pdf` are not explicitly set to zero when a BSDF sample is invalid (e.g., below the upper hemisphere), when calling
`bsdf_sample` or `bsdf_eval`. It is assumed that `eval` and `pdf` are set to zero before these functions are called, which can cause problems if not.

This patch fixes this potential problem by explicitly setting `eval` and `pdf` to zero when the sampled direction is invalid.

I also added a sanity check if `eval` and `pdf` are valid (i.e., >= 0.f).
The check is activated when build in debug mode and with the `WITH_CYCLES_DEBUG` set to `ON`.

Reviewed By: brecht, sergey

Differential Revision: https://developer.blender.org/D14776

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

M	intern/cycles/kernel/closure/bsdf.h
M	intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h
M	intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h
M	intern/cycles/kernel/closure/bsdf_diffuse.h
M	intern/cycles/kernel/closure/bsdf_diffuse_ramp.h
M	intern/cycles/kernel/closure/bsdf_hair.h
M	intern/cycles/kernel/closure/bsdf_microfacet.h
M	intern/cycles/kernel/closure/bsdf_microfacet_multi.h
M	intern/cycles/kernel/closure/bsdf_oren_nayar.h
M	intern/cycles/kernel/closure/bsdf_phong_ramp.h
M	intern/cycles/kernel/closure/bsdf_principled_diffuse.h
M	intern/cycles/kernel/closure/bsdf_principled_sheen.h
M	intern/cycles/kernel/closure/bsdf_reflection.h
M	intern/cycles/kernel/closure/bsdf_refraction.h
M	intern/cycles/kernel/closure/bsdf_toon.h
M	intern/cycles/kernel/closure/bsdf_transparent.h

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

diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h
index 50a047b3992..011155cdf5f 100644
--- a/intern/cycles/kernel/closure/bsdf.h
+++ b/intern/cycles/kernel/closure/bsdf.h
@@ -445,6 +445,11 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg,
     }
   }
 
+#ifdef WITH_CYCLES_DEBUG
+  kernel_assert(*pdf >= 0.0f);
+  kernel_assert(eval->x >= 0.0f && eval->y >= 0.0f && eval->z >= 0.0f);
+#endif
+
   return label;
 }
 
@@ -635,7 +640,10 @@ ccl_device_inline
       }
     }
   }
-
+#ifdef WITH_CYCLES_DEBUG
+  kernel_assert(*pdf >= 0.0f);
+  kernel_assert(eval.x >= 0.0f && eval.y >= 0.0f && eval.z >= 0.0f);
+#endif
   return eval;
 }
 
diff --git a/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h b/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h
index a7694062935..47066542122 100644
--- a/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h
+++ b/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h
@@ -53,9 +53,10 @@ bsdf_ashikhmin_shirley_eval_reflect(ccl_private const ShaderClosure *sc,
 
   float out = 0.0f;
 
-  if (fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f)
+  if (fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f) {
+    *pdf = 0.0f;
     return make_float3(0.0f, 0.0f, 0.0f);
-
+  }
   if (NdotI > 0.0f && NdotO > 0.0f) {
     NdotI = fmaxf(NdotI, 1e-6f);
     NdotO = fmaxf(NdotO, 1e-6f);
@@ -112,6 +113,7 @@ ccl_device float3 bsdf_ashikhmin_shirley_eval_transmit(ccl_private const ShaderC
                                                        const float3 omega_in,
                                                        ccl_private float *pdf)
 {
+  *pdf = 0.0f;
   return make_float3(0.0f, 0.0f, 0.0f);
 }
 
diff --git a/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h b/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h
index d396e601338..3d7906eef7d 100644
--- a/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h
+++ b/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h
@@ -48,9 +48,10 @@ ccl_device float3 bsdf_ashikhmin_velvet_eval_reflect(ccl_private const ShaderClo
     float cosNH = dot(N, H);
     float cosHO = fabsf(dot(I, H));
 
-    if (!(fabsf(cosNH) < 1.0f - 1e-5f && cosHO > 1e-5f))
+    if (!(fabsf(cosNH) < 1.0f - 1e-5f && cosHO > 1e-5f)) {
+      *pdf = 0.0f;
       return make_float3(0.0f, 0.0f, 0.0f);
-
+    }
     float cosNHdivHO = cosNH / cosHO;
     cosNHdivHO = fmaxf(cosNHdivHO, 1e-5f);
 
@@ -62,7 +63,7 @@ ccl_device float3 bsdf_ashikhmin_velvet_eval_reflect(ccl_private const ShaderClo
     float cotangent2 = (cosNH * cosNH) / sinNH2;
 
     float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * M_1_PI_F / sinNH4;
-    float G = min(1.0f, min(fac1, fac2));  // TODO: derive G from D analytically
+    float G = fminf(1.0f, fminf(fac1, fac2));  // TODO: derive G from D analytically
 
     float out = 0.25f * (D * G) / cosNO;
 
@@ -70,6 +71,7 @@ ccl_device float3 bsdf_ashikhmin_velvet_eval_reflect(ccl_private const ShaderClo
     return make_float3(out, out, out);
   }
 
+  *pdf = 0.0f;
   return make_float3(0.0f, 0.0f, 0.0f);
 }
 
@@ -78,6 +80,7 @@ ccl_device float3 bsdf_ashikhmin_velvet_eval_transmit(ccl_private const ShaderCl
                                                       const float3 omega_in,
                                                       ccl_private float *pdf)
 {
+  *pdf = 0.0f;
   return make_float3(0.0f, 0.0f, 0.0f);
 }
 
@@ -122,7 +125,7 @@ ccl_device int bsdf_ashikhmin_velvet_sample(ccl_private const ShaderClosure *sc,
       float cotangent2 = (cosNH * cosNH) / sinNH2;
 
       float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * M_1_PI_F / sinNH4;
-      float G = min(1.0f, min(fac1, fac2));  // TODO: derive G from D analytically
+      float G = fminf(1.0f, fminf(fac1, fac2));  // TODO: derive G from D analytically
 
       float power = 0.25f * (D * G) / cosNO;
 
@@ -134,12 +137,15 @@ ccl_device int bsdf_ashikhmin_velvet_sample(ccl_private const ShaderClosure *sc,
       *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
 #endif
     }
-    else
+    else {
       *pdf = 0.0f;
+      *eval = make_float3(0.0f, 0.0f, 0.0f);
+    }
   }
-  else
+  else {
     *pdf = 0.0f;
-
+    *eval = make_float3(0.0f, 0.0f, 0.0f);
+  }
   return LABEL_REFLECT | LABEL_DIFFUSE;
 }
 
diff --git a/intern/cycles/kernel/closure/bsdf_diffuse.h b/intern/cycles/kernel/closure/bsdf_diffuse.h
index 18abdac8128..759ad03f8e8 100644
--- a/intern/cycles/kernel/closure/bsdf_diffuse.h
+++ b/intern/cycles/kernel/closure/bsdf_diffuse.h
@@ -44,6 +44,7 @@ ccl_device float3 bsdf_diffuse_eval_transmit(ccl_private const ShaderClosure *sc
                                              const float3 omega_in,
                                              ccl_private float *pdf)
 {
+  *pdf = 0.0f;
   return make_float3(0.0f, 0.0f, 0.0f);
 }
 
@@ -74,9 +75,10 @@ ccl_device int bsdf_diffuse_sample(ccl_private const ShaderClosure *sc,
     *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
 #endif
   }
-  else
+  else {
     *pdf = 0.0f;
-
+    *eval = make_float3(0.0f, 0.0f, 0.0f);
+  }
   return LABEL_REFLECT | LABEL_DIFFUSE;
 }
 
@@ -93,6 +95,7 @@ ccl_device float3 bsdf_translucent_eval_reflect(ccl_private const ShaderClosure
                                                 const float3 omega_in,
                                                 ccl_private float *pdf)
 {
+  *pdf = 0.0f;
   return make_float3(0.0f, 0.0f, 0.0f);
 }
 
@@ -138,6 +141,7 @@ ccl_device int bsdf_translucent_sample(ccl_private const ShaderClosure *sc,
   }
   else {
     *pdf = 0;
+    *eval = make_float3(0.0f, 0.0f, 0.0f);
   }
   return LABEL_TRANSMIT | LABEL_DIFFUSE;
 }
diff --git a/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h b/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h
index d1e31641431..aa4c091f587 100644
--- a/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h
+++ b/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h
@@ -93,9 +93,10 @@ ccl_device int bsdf_diffuse_ramp_sample(ccl_private const ShaderClosure *sc,
     *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
 #  endif
   }
-  else
+  else {
     *pdf = 0.0f;
-
+    *eval = make_float3(0.0f, 0.0f, 0.0f);
+  }
   return LABEL_REFLECT | LABEL_DIFFUSE;
 }
 
diff --git a/intern/cycles/kernel/closure/bsdf_hair.h b/intern/cycles/kernel/closure/bsdf_hair.h
index 0554d6e92fc..a136ed05800 100644
--- a/intern/cycles/kernel/closure/bsdf_hair.h
+++ b/intern/cycles/kernel/closure/bsdf_hair.h
@@ -89,6 +89,7 @@ ccl_device float3 bsdf_hair_transmission_eval_reflect(ccl_private const ShaderCl
                                                       const float3 omega_in,
                                                       ccl_private float *pdf)
 {
+  *pdf = 0.0f;
   return make_float3(0.0f, 0.0f, 0.0f);
 }
 
@@ -97,6 +98,7 @@ ccl_device float3 bsdf_hair_reflection_eval_transmit(ccl_private const ShaderClo
                                                      const float3 omega_in,
                                                      ccl_private float *pdf)
 {
+  *pdf = 0.0f;
   return make_float3(0.0f, 0.0f, 0.0f);
 }
 
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h
index d4c3c3509db..db50712f9f0 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet.h
@@ -368,8 +368,10 @@ ccl_device float3 bsdf_microfacet_ggx_eval_reflect(ccl_private const ShaderClosu
   bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
   float3 N = bsdf->N;
 
-  if (m_refractive || alpha_x * alpha_y <= 1e-7f)
+  if (m_refractive || alpha_x * alpha_y <= 1e-7f) {
+    *pdf = 0.0f;
     return make_float3(0.0f, 0.0f, 0.0f);
+  }
 
   float cosNO = dot(N, I);
   float cosNI = dot(N, omega_in);
@@ -482,15 +484,18 @@ ccl_device float3 bsdf_microfacet_ggx_eval_transmit(ccl_private const ShaderClos
   bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
   float3 N = bsdf->N;
 
-  if (!m_refractive || alpha_x * alpha_y <= 1e-7f)
+  if (!m_refractive || alpha_x * alpha_y <= 1e-7f) {
+    *pdf = 0.0f;
     return make_float3(0.0f, 0.0f, 0.0f);
+  }
 
   float cosNO = dot(N, I);
   float cosNI = dot(N, omega_in);
 
-  if (cosNO <= 0 || cosNI >= 0)
+  if (cosNO <= 0 || cosNI >= 0) {
+    *pdf = 0.0f;
     return make_float3(0.0f, 0.0f, 0.0f); /* vectors on same side -- not possible */
-
+  }
   /* compute half-vector of the refraction (eq. 16) */
   float3 ht = -(m_eta * omega_in + I);
   float3 Ht = normalize(ht);
@@ -673,6 +678,10 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg,
           *domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy;
 #endif
         }
+        else {
+          *eval = make_float3(0.0f, 0.0f, 0.0f);
+          *pdf = 0.0f;
+        }
       }
     }
     else {
@@ -744,6 +753,10 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg,
           *eval = make_float3(out, out, out);
         }
       }
+      else {
+        *eval = make_float3(0.0f, 0.0f, 0.0f);
+        *pdf = 0.0f;
+      }
     }
   }
   else {
@@ -833,8 +846,10 @@ ccl_device float3 bsdf_microfacet_beckmann_eval_reflect(ccl_private const Shader
   bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
   float3 N = bsdf->N;
 
-  if (m_refractive || alpha_x * alpha_y <= 1e-7f)
+  if (m_refractive || alpha_x * alpha_y <= 1e-7f) {
+    *pdf = 0.0f;
     return make_float3(0.0f, 0.0f, 0.0f);
+  }
 
   float cosNO = dot(N, I);
   float cosNI = dot(N, omega_in);
@@ -913,15 +928,18 @@ ccl_device float3 bsdf_microfacet_beckmann_eval_transmit(ccl_private const Shade
   bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
   float3 N = bsdf->N;
 
-  if (!m_refractive || alpha_x * alpha_y <= 1e-7f)
+  if (!m_refractive || alpha_x * alpha_y <= 1e-7f) {
+    *pdf = 0.0f;
     return make_float3(0.0f, 0.0f, 0.0f);
+  }
 
   float cosNO = dot(N, I);
   float cosNI = dot(N, omega_in);
 
-  if (cosNO <= 0 || cosNI >= 0)
+  if (cosNO <= 0 || cosNI >= 0) {
+    *pdf = 0.0f;
     return make_float3(0.0f, 0.0f, 0.0f);
-
+  }
   /* compute half-vector of the refraction (eq. 16) */
   float3 ht = -(m_eta * omega_in + I);
   float3 Ht = normalize(ht);
@@ -1064,6 +1082,10 @@ ccl_device int bsdf_mic

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list