[Bf-blender-cvs] [33ff1ce7b25] microfacet_hair: Merge code for circular and elliptical cross-sections

Weizhen Huang noreply at git.blender.org
Fri Jan 20 20:11:59 CET 2023


Commit: 33ff1ce7b25f2429c0b6c5769268733880cfab1f
Author: Weizhen Huang
Date:   Fri Jan 20 20:11:30 2023 +0100
Branches: microfacet_hair
https://developer.blender.org/rB33ff1ce7b25f2429c0b6c5769268733880cfab1f

Merge code for circular and elliptical cross-sections

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

M	intern/cycles/blender/shader.cpp
M	intern/cycles/kernel/closure/bsdf_hair_microfacet.h
M	intern/cycles/kernel/osl/closures_setup.h
M	intern/cycles/kernel/osl/closures_template.h
M	intern/cycles/kernel/osl/shaders/node_microfacet_hair_bsdf.osl
M	intern/cycles/kernel/osl/shaders/stdcycles.h
M	intern/cycles/kernel/svm/closure.h
M	intern/cycles/kernel/svm/types.h
M	intern/cycles/scene/shader_nodes.cpp
M	intern/cycles/scene/shader_nodes.h
M	source/blender/makesdna/DNA_node_types.h
M	source/blender/makesrna/intern/rna_nodetree.c
M	source/blender/nodes/shader/nodes/node_shader_bsdf_hair_microfacet.cc

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

diff --git a/intern/cycles/blender/shader.cpp b/intern/cycles/blender/shader.cpp
index 266a5900837..015bdee59fb 100644
--- a/intern/cycles/blender/shader.cpp
+++ b/intern/cycles/blender/shader.cpp
@@ -668,11 +668,7 @@ static ShaderNode *add_node(Scene *scene,
                                                     "parametrization",
                                                     NODE_MICROFACET_HAIR_NUM,
                                                     NODE_MICROFACET_HAIR_REFLECTANCE));
-    microfacet_hair->set_cross_section(
-        (NodeMicrofacetHairCrossSectionType)get_enum(b_microfacet_hair_node.ptr,
-                                                     "cross_section",
-                                                     NODE_MICROFACET_HAIR_CROSS_SECTION_NUM,
-                                                     NODE_MICROFACET_HAIR_CIRCULAR));
+
     microfacet_hair->set_distribution_type(
         (NodeMicrofacetHairDistributionType)get_enum(b_microfacet_hair_node.ptr,
                                                      "distribution_type",
diff --git a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h
index d9d9df942e6..d8e79739ffb 100644
--- a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h
@@ -36,9 +36,6 @@ typedef struct MicrofacetHairBSDF {
   /* GGX/Beckmann. */
   int distribution_type;
 
-  /* Circular/Elliptical */
-  int cross_section;
-
   /* The ratio of the minor axis to the major axis. */
   float aspect_ratio;
 
@@ -74,7 +71,7 @@ ccl_device int bsdf_microfacet_hair_setup(ccl_private ShaderData *sd,
   kernel_assert(isfinite_safe(X));
   kernel_assert(isfinite_safe(h));
 
-  if (bsdf->cross_section == NODE_MICROFACET_HAIR_ELLIPTIC) {
+  if (bsdf->aspect_ratio != 1.0f) {
     if (bsdf->aspect_ratio > 1.0f) {
       bsdf->aspect_ratio = 1.0f / bsdf->aspect_ratio;
 
@@ -154,53 +151,67 @@ ccl_device_inline float2 dir_sph(const float3 w)
   return make_float2(dir_theta(w), dir_phi(w));
 }
 
-/* Compute the vector direction given spherical coordinates. */
-ccl_device_inline float3 sph_dir(float theta, float phi)
-{
-  float sin_theta, cos_theta, sin_phi, cos_phi;
-  fast_sincosf(theta, &sin_theta, &cos_theta);
-  fast_sincosf(phi, &sin_phi, &cos_phi);
-  return make_float3(sin_phi * cos_theta, sin_theta, cos_phi * cos_theta);
-}
-
-/* Utility functions for elliptical cross-sections. */
-
 /* Conversion between gamma and phi. Notations see Figure 5 in the paper. */
-ccl_device float to_phi(float gamma, float a, float b)
+ccl_device_inline float to_phi(float gamma, float b)
 {
+  if (b == 1.0f) {
+    return gamma;
+  }
   float sin_gamma, cos_gamma;
   fast_sincosf(gamma, &sin_gamma, &cos_gamma);
-  return atan2f(b * sin_gamma, a * cos_gamma);
+  return atan2f(b * sin_gamma, cos_gamma);
 }
 
-ccl_device float to_gamma(float phi, float a, float b)
+ccl_device_inline float to_gamma(float phi, float b)
 {
+  if (b == 1.0f) {
+    return phi;
+  }
   float sin_phi, cos_phi;
   fast_sincosf(phi, &sin_phi, &cos_phi);
-  return atan2f(a * sin_phi, b * cos_phi);
+  return atan2f(sin_phi, b * cos_phi);
 }
 
-/* Compute the coordinate on the ellipse, given gamma, the semi-major and semi-minor axes. */
-ccl_device float2 to_point(float gamma, float a, float b)
+/* Compute the coordinate on the ellipse, given gamma and the aspect ratio between the minor axis
+ * and the major axis. */
+ccl_device_inline float2 to_point(float gamma, float b)
 {
   float sin_gamma, cos_gamma;
   fast_sincosf(gamma, &sin_gamma, &cos_gamma);
-  return make_float2(a * sin_gamma, b * cos_gamma);
+  return make_float2(sin_gamma, b * cos_gamma);
 }
 
 /* Compute the vector direction given by theta and gamma. */
-ccl_device float3 sphg_dir(float theta, float gamma, float a, float b)
+ccl_device_inline float3 sphg_dir(float theta, float gamma, float b)
 {
-  float sin_theta, cos_theta, sin_gamma, cos_gamma;
+  float sin_theta, cos_theta, sin_gamma, cos_gamma, sin_phi, cos_phi;
+
   fast_sincosf(theta, &sin_theta, &cos_theta);
   fast_sincosf(gamma, &sin_gamma, &cos_gamma);
-  float tan_gamma = sin_gamma / cos_gamma;
-  float tan_phi = b / a * tan_gamma;
-  float cos_phi = signf(cos_gamma) / sqrtf(sqr(tan_phi) + 1.0f);
-  float sin_phi = cos_phi * tan_phi;
+
+  if (b == 1.0f) {
+    sin_phi = sin_gamma;
+    cos_phi = cos_gamma;
+  }
+  else {
+    float tan_gamma = sin_gamma / cos_gamma;
+    float tan_phi = b * tan_gamma;
+    cos_phi = signf(cos_gamma) / sqrtf(sqr(tan_phi) + 1.0f);
+    sin_phi = cos_phi * tan_phi;
+  }
   return make_float3(sin_phi * cos_theta, sin_theta, cos_phi * cos_theta);
 }
 
+ccl_device_inline float arc_length(float e2, float gamma)
+{
+  return e2 == 0 ? 1.0f : sqrtf(1.0f - e2 * sqr(sinf(gamma)));
+}
+
+ccl_device_inline float projected_radius(float e2, float phi)
+{
+  return e2 == 0 ? 1.0f : sqrtf(1.0f - e2 * sqr(sinf(phi)));
+}
+
 /** \} */
 
 /* Sample microfacets from a tilted mesonormal. */
@@ -327,488 +338,9 @@ ccl_device_inline float3 refract_angle(const float3 incident,
 }
 
 template<MicrofacetType m_type>
-ccl_device float3 bsdf_microfacet_hair_eval_r_circular(ccl_private const ShaderClosure *sc,
-                                                       const float3 wi,
-                                                       const float3 wo)
-{
-  ccl_private MicrofacetHairBSDF *bsdf = (ccl_private MicrofacetHairBSDF *)sc;
-  const float tilt = -bsdf->tilt;
-  const float roughness = bsdf->roughness;
-  const float eta = bsdf->eta;
-  const bool beckmann = (bsdf->distribution_type == NODE_MICROFACET_HAIR_BECKMANN);
-
-  float3 R = zero_float3();
-  if (bsdf->extra->R <= 0.0f) {
-    return R;
-  }
-
-  const float3 wh = normalize(wi + wo);
-  const float phi_o = dir_phi(wo);
-
-  /* dot(wi, wmi) > 0 */
-  const float tan_tilt = tanf(tilt);
-  const float phi_m_max1 = acosf(fmaxf(-tan_tilt * tan_theta(wi), 0.0f));
-  if (isnan_safe(phi_m_max1)) {
-    return R;
-  }
-  const float phi_m_min1 = -phi_m_max1;
-
-  /* dot(wo, wmi) > 0 */
-  const float phi_m_max2 = acosf(fmaxf(-tan_tilt * tan_theta(wo), 0.0f)) + phi_o;
-  if (isnan_safe(phi_m_max2)) {
-    return R;
-  }
-  const float phi_m_min2 = -phi_m_max2 + 2.0f * phi_o;
-
-  const float phi_m_min = fmaxf(phi_m_min1, phi_m_min2) + 1e-5f;
-  const float phi_m_max = fminf(phi_m_max1, phi_m_max2) - 1e-5f;
-  if (phi_m_min > phi_m_max) {
-    return R;
-  }
-
-  float integral = 0.0f;
-
-  /* Maximal sample resolution. */
-  float res = roughness * 0.7f;
-  /* 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 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++) {
-
-    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) ? 0.5f : (i % 2 + 1);
-      integral += weight * D(beckmann, roughness, wm, wh) * G(beckmann, roughness, wi, wo, wm, wh);
-    }
-  }
-  integral *= (2.0f / 3.0f * res);
-
-  const float F = fresnel_dielectric_cos(dot(wi, wh), eta);
-
-  R = make_float3(bsdf->extra->R * 0.125f * F * fmaxf(0.0f, integral));
-  return R;
-}
-
-template<MicrofacetType m_type>
-ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_circular(KernelGlobals kg,
-                                                            ccl_private const ShaderClosure *sc,
-                                                            const float3 wi,
-                                                            const float3 wo,
-                                                            uint rng_quadrature)
-{
-  ccl_private MicrofacetHairBSDF *bsdf = (ccl_private MicrofacetHairBSDF *)sc;
-  const float tilt = -bsdf->tilt;
-  const float roughness = bsdf->roughness;
-  const float eta = bsdf->eta;
-  const bool beckmann = (bsdf->distribution_type == NODE_MICROFACET_HAIR_BECKMANN);
-
-  if (bsdf->extra->TT <= 0.0f && bsdf->extra->TRT <= 0.0f) {
-    return zero_float3();
-  }
-
-  const float tan_tilt = tanf(tilt);
-  const float phi_m_max = acosf(fmaxf(-tan_tilt * tan_theta(wi), 0.0f)) - 1e-3f;
-  if (isnan_safe(phi_m_max)) {
-    /* Early detection of dot(wi, wmi) < 0. */
-    return zero_float3();
-  }
-  const float phi_m_min = -phi_m_max;
-
-  if (tan_tilt * tan_theta(wo) < -1.0f) {
-    /* Early detection of dot(wo, wmo) < 0. */
-    return zero_float3();
-  }
-
-  const float3 mu_a = bsdf->sigma;
-  const float inv_eta = 1.0f / eta;
-
-  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++) {
-
-    const float phi_mi = phi_m_min + i * res;
-    const float3 wmi = sph_dir(tilt, phi_mi);
-
-    /* Sample wh1. */
-    const float2 sample1 = make_float2(lcg_step_float(&rng_quadrature),
-                                       lcg_step_float(&rng_quadrature));
-
-    const float3 wh1 = sample_wh<m_type>(kg, roughness, wi, wmi, sample1);
-    const float dot_wi_wh1 = dot(wi, wh1);
-    if (!(dot_wi_wh1 > 0)) {
-      continue;
-    }
-
-    float cos_theta_t1;
-    const float T1 = 1.0f - fresnel(dot_wi_wh1, eta, &cos_theta_t1);
-
-    /* Refract at the first interface. */
-    const float3 wt = -refract_angle(wi, wh1, cos_theta_t1, inv_eta);
-    const float phi_t = dir_phi(wt);
-    const float phi_mt = 2.0f * phi_t - phi_mi;
-    const float3 wmt = sph_dir(-tilt, phi_mt);
-
-    const float G1 = G(beckmann, roughness, wi, -wt, wmi, wh1);
-    if (G1 == 0.0f || !microfacet_visible(wi, -wt, make_float3(wmi.x, 0.0f, wmi.z), wh1)) {
-      continue;
-    }
-
-    /* Simpson's rule weight. */
-    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));
-
-    /* TT */
-    if (bsdf->extra->TT > 0.0f) {
-
-   

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list