[Bf-blender-cvs] [c574ddc1044] microfacet_hair: Fix wrong interval numbers in composite Simpson's method

Weizhen Huang noreply at git.blender.org
Wed Dec 28 12:41:54 CET 2022


Commit: c574ddc10445d2dc5bc3984b3f356c501464bda3
Author: Weizhen Huang
Date:   Wed Dec 28 12:41:33 2022 +0100
Branches: microfacet_hair
https://developer.blender.org/rBc574ddc10445d2dc5bc3984b3f356c501464bda3

Fix wrong interval numbers in composite Simpson's method

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

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

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

diff --git a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h
index 2392d03cbac..3216511a26d 100644
--- a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h
@@ -398,23 +398,23 @@ ccl_device float3 bsdf_microfacet_hair_eval_r_circular(ccl_private const ShaderC
 
     integral = roughness_squared * M_1_PI_F * 0.5f * (temp1 + temp2 + temp3 + temp4);
   }
-  else { /* falls back to numerical integration */
-    /* initial sample resolution */
+  else { /* Falls back to numerical integration. */
+    /* Maximal sample resolution. */
     float res = roughness * 0.7f;
-    const float scale = (phi_m_max - phi_m_min) * 0.5f;
-    size_t intervals = 2 * (size_t)ceilf(scale / res) + 1;
+    /* Number of intervals should be even. */
+    const size_t intervals = 2 * (size_t)ceilf((phi_m_max - phi_m_min) / res * 0.5f);
 
-    /* modified resolution based on integral domain */
+    /* Modified resolution based on numbers of intervals. */
     res = (phi_m_max - phi_m_min) / float(intervals);
 
-    /* integrate using Simpson's rule */
-    for (size_t i = 0; i < intervals; i++) {
+    /* Integrate using Simpson's rule. */
+    for (size_t i = 0; i <= intervals; i++) {
 
       const float phi_m = phi_m_min + i * res;
       const float3 wm = sph_dir(tilt, phi_m);
 
       if (microfacet_visible(wi, wo, make_float3(wm.x, 0.0f, wm.z), wh)) {
-        const float weight = (i == 0 || i == intervals - 1) ? 0.5f : (i % 2 + 1);
+        const float weight = (i == 0 || i == intervals) ? 0.5f : (i % 2 + 1);
         integral += weight * D(beckmann, roughness, wm, wh) *
                     G(beckmann, roughness, wi, wo, wm, wh);
       }
@@ -458,14 +458,13 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_circular(KernelGlobals kg,
   const float3 mu_a = bsdf->sigma;
   const float inv_eta = 1.0f / eta;
 
-  float res = roughness * .8f;
-  const float scale = (phi_m_max - phi_m_min) * 0.5f;
-  size_t intervals = 2 * (size_t)ceilf(scale / res) + 1;
+  float res = roughness * 0.8f;
+  const size_t intervals = 2 * (size_t)ceilf((phi_m_max - phi_m_min) / res * 0.5f);
   res = (phi_m_max - phi_m_min) / intervals;
 
   float3 S_tt = zero_float3();
   float3 S_trt = zero_float3();
-  for (size_t i = 0; i < intervals; i++) {
+  for (size_t i = 0; i <= intervals; i++) {
 
     const float phi_mi = phi_m_min + i * res;
     const float3 wmi = sph_dir(tilt, phi_mi);
@@ -495,7 +494,7 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_circular(KernelGlobals kg,
     }
 
     /* Simpson's rule weight */
-    float weight = (i == 0 || i == intervals - 1) ? 0.5f : (i % 2 + 1);
+    float weight = (i == 0 || i == intervals) ? 0.5f : (i % 2 + 1);
 
     float3 A_t = exp(mu_a * 2.0f * cosf(phi_t - phi_mi) / cos_theta(wt));
 
@@ -891,23 +890,23 @@ ccl_device float3 bsdf_microfacet_hair_eval_r_elliptic(ccl_private const ShaderC
     gamma_m_max += M_2PI_F;
   }
 
-  /* initial sample resolution */
+  /* Maximal sample resolution. */
   float res = roughness * .7f;
-  const float scale = (gamma_m_max - gamma_m_min) * 0.5f;
-  size_t intervals = 2 * (size_t)ceilf(scale / res) + 1;
+  /* Number of intervals should be even. */
+  const size_t intervals = 2 * (size_t)ceilf((gamma_m_max - gamma_m_min) / res * 0.5f);
 
-  /* modified resolution based on integral domain */
+  /* Modified resolution based on numbers of intervals. */
   res = (gamma_m_max - gamma_m_min) / float(intervals);
 
-  /* integrate using Simpson's rule */
+  /* Integrate using Simpson's rule. */
   float integral = 0.0f;
-  for (size_t i = 0; i < intervals; i++) {
+  for (size_t i = 0; i <= intervals; i++) {
 
     const float gamma_m = gamma_m_min + i * res;
     const float3 wm = sphg_dir(tilt, gamma_m, a, b);
 
     if (microfacet_visible(wi, wo, make_float3(wm.x, 0.0f, wm.z), wh)) {
-      const float weight = (i == 0 || i == intervals - 1) ? 0.5f : (i % 2 + 1);
+      const float weight = (i == 0 || i == intervals) ? 0.5f : (i % 2 + 1);
       const float arc_length = sqrtf(1.0f - e2 * sqr(sinf(gamma_m)));
 
       integral += weight * D(beckmann, roughness, wm, wh) *
@@ -976,13 +975,12 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_elliptic(KernelGlobals kg,
   }
 
   float res = roughness * 0.8f;
-  const float scale = (gamma_m_max - gamma_m_min) * 0.5f;
-  size_t intervals = 2 * (size_t)ceilf(scale / res) + 1;
+  const size_t intervals = 2 * (size_t)ceilf((gamma_m_max - gamma_m_min) / res * 0.5f);
   res = (gamma_m_max - gamma_m_min) / intervals;
 
   float3 S_tt = zero_float3();
   float3 S_trt = zero_float3();
-  for (size_t i = 0; i < intervals; i++) {
+  for (size_t i = 0; i <= intervals; i++) {
 
     const float gamma_mi = gamma_m_min + i * res;
 
@@ -1015,7 +1013,7 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_elliptic(KernelGlobals kg,
     }
 
     /* Simpson's rule weight */
-    const float weight = (i == 0 || i == intervals - 1) ? 0.5f : (i % 2 + 1);
+    const float weight = (i == 0 || i == intervals) ? 0.5f : (i % 2 + 1);
 
     const float2 pi = to_point(gamma_mi, a, b);
     const float2 pt = to_point(gamma_mt + M_PI_F, a, b);



More information about the Bf-blender-cvs mailing list