[Bf-blender-cvs] [cc7317af539] microfacet_hair: Cleanup: adjust the usage and naming of a few utility functions

Weizhen Huang noreply at git.blender.org
Wed Dec 7 17:21:37 CET 2022


Commit: cc7317af539206db8152128806141f4ec9fbf0c8
Author: Weizhen Huang
Date:   Wed Dec 7 17:20:15 2022 +0100
Branches: microfacet_hair
https://developer.blender.org/rBcc7317af539206db8152128806141f4ec9fbf0c8

Cleanup: adjust the usage and naming of a few utility functions

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

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

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

diff --git a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h
index 6095ebcac41..cd75d54d42b 100644
--- a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h
@@ -88,125 +88,109 @@ ccl_device int bsdf_microfacet_hair_setup(ccl_private ShaderData *sd,
 
 #endif /* __HAIR__ */
 
-ccl_device_inline float3 make_float3_from_float(const float f)
+/* -------------------------------------------------------------------- */
+/** \name Hair coordinate system utils.
+ * \{ */
+
+/* Returns sin(theta) of the given direction. */
+ccl_device_inline float sin_theta(const float3 w)
 {
-  return make_float3(f, f, f);
+  return w.y;
 }
 
-ccl_device_inline float3 reflect_vector(const float3 w, const float3 n)
+/* Returns cos(theta) of the given direction. */
+ccl_device_inline float cos_theta(const float3 w)
 {
-  return 2.f * dot(w, n) * n - w;
+  return safe_sqrtf(sqr(w.x) + sqr(w.z));
 }
 
-ccl_device float3 refract_vector(const float3 w,
-                                 const float3 n,
-                                 const float cos_theta_t,
-                                 const float eta_ti)
+/* Returns tan(theta) of the given direction. */
+ccl_device_inline float tan_theta(const float3 w)
 {
-  return n * (dot(w, n) * eta_ti + cos_theta_t) - w * eta_ti;
+  return sin_theta(w) / cos_theta(w);
 }
 
-ccl_device_inline float3 microfacet_visible_normal_sample(KernelGlobals kg,
-                                                          const bool beckmann,
-                                                          const float roughness,
-                                                          const float3 wi,
-                                                          const float randu,
-                                                          const float randv,
-                                                          ccl_private float *G1i)
+/* Returns sin(phi) and cos(phi) of the given direction. */
+ccl_device float2 sincos_phi(const float3 w)
 {
-  /* Step 1 : stretch wi */
-  float3 omega_i_ = normalize(make_float3(roughness * wi.x, roughness * wi.y, wi.z));
-
-  /* get polar coordinates of omega_i_ */
-  float costheta_ = 1.f;
-  float sintheta_ = 0.f;
-  float cosphi_ = 1.f;
-  float sinphi_ = 0.f;
-
-  if (omega_i_.z < 0.99999f) {
-    costheta_ = omega_i_.z;
-    sintheta_ = safe_sqrtf(1.f - costheta_ * costheta_);
-
-    float invlen = 1.f / sintheta_;
-    cosphi_ = omega_i_.x * invlen;
-    sinphi_ = omega_i_.y * invlen;
-  }
-
-  /* 2. sample P22_{omega_i}(x_slope, y_slope, 1, 1) */
-  float slope_x, slope_y;
-
-  if (beckmann) {
-    microfacet_beckmann_sample_slopes(
-        kg, costheta_, sintheta_, randu, randv, &slope_x, &slope_y, G1i);
-  }
-  else {
-    microfacet_ggx_sample_slopes(costheta_, sintheta_, randu, randv, &slope_x, &slope_y, G1i);
-  }
-
-  /* 3. rotate */
-  float tmp = cosphi_ * slope_x - sinphi_ * slope_y;
-  slope_y = sinphi_ * slope_x + cosphi_ * slope_y;
-  slope_x = tmp;
-
-  /* 4. unstretch */
-  slope_x = roughness * slope_x;
-  slope_y = roughness * slope_y;
+  float c = cos_theta(w);
+  return make_float2(w.x / c, w.z / c);
+}
 
-  /* 5. compute normal */
-  return normalize(make_float3(-slope_x, -slope_y, 1.f));
+/* Extract the theta coordinate from the given direction.
+ * -pi < theta < pi */
+ccl_device_inline float dir_theta(const float3 w)
+{
+  return atan2f(sin_theta(w), cos_theta(w));
 }
 
-/* returns sin_theta */
-ccl_device_inline float sintheta(const float3 w)
+/* Extract the phi coordinate from the given direction, assuming phi(wi) = 0.
+ * -pi < phi < pi */
+ccl_device_inline float dir_phi(const float3 w)
 {
-  return w.y;
+  return atan2f(w.x, w.z);
 }
 
-/* returns cos_theta */
-ccl_device_inline float costheta(const float3 w)
+/* Extract theta and phi coordinates from the given direction, assuming phi(wi) = 0.
+ * -pi/2 < theta < pi/2, -pi < phi < pi */
+ccl_device_inline float2 dir_sph(const float3 w)
 {
-  return safe_sqrtf(sqr(w.x) + sqr(w.z));
+  return make_float2(dir_theta(w), dir_phi(w));
 }
 
-/* returns tan_theta */
-ccl_device_inline float tantheta(const float3 w)
+/* Compute the vector direction given spherical coordinates */
+ccl_device_inline float3 sph_dir(float theta, float gamma)
 {
-  return sintheta(w) / costheta(w);
+  float sin_theta = sinf(theta);
+  float cos_theta = cosf(theta);
+  float sin_gamma = sinf(gamma);
+  float cos_gamma = cosf(gamma);
+  return make_float3(sin_gamma * cos_theta, sin_theta, cos_gamma * cos_theta);
 }
 
-/* extract theta coordinate from 3D direction
- * -pi < theta < pi */
-ccl_device_inline float dir_theta(const float3 w)
+/* 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)
 {
-  return atan2f(sintheta(w), costheta(w));
+  float sin_gamma = sinf(gamma);
+  float cos_gamma = cosf(gamma);
+  return atan2f(b * sin_gamma, a * cos_gamma);
 }
 
-/* extract phi coordinate from 3D direction.
- * -pi < phi < pi
- * Assuming phi(wi) = 0 */
-ccl_device_inline float dir_phi(const float3 w)
+ccl_device float to_gamma(float phi, float a, float b)
 {
-  return atan2f(w.x, w.z);
+  float sin_phi = sinf(phi);
+  float cos_phi = cosf(phi);
+  return atan2f(a * sin_phi, b * cos_phi);
 }
 
-/* extract theta and phi coordinate from 3D direction
- * -pi/2 < theta < pi/2, -pi < phi < pi
- * Assuming phi(wi) = 0 */
-ccl_device_inline float2 dir_sph(const float3 w)
+/* 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)
 {
-  return make_float2(dir_theta(w), dir_phi(w));
+  float sin_gamma = sinf(gamma);
+  float cos_gamma = cosf(gamma);
+  return make_float2(a * sin_gamma, b * cos_gamma);
 }
 
-/* compute the vector direction given spherical coordinates */
-ccl_device_inline float3 sph_dir(float theta, float gamma)
+/* Compute the vector direction given by theta and gamma. */
+ccl_device float3 sphg_dir(float theta, float gamma, float a, float b)
 {
   float sin_theta = sinf(theta);
   float cos_theta = cosf(theta);
   float sin_gamma = sinf(gamma);
   float cos_gamma = cosf(gamma);
-  return make_float3(sin_gamma * cos_theta, sin_theta, cos_gamma * cos_theta);
+  float tan_gamma = sin_gamma / cos_gamma;
+  float tan_phi = b / a * tan_gamma;
+  float cos_phi = 1.f / sqrtf(sqr(tan_phi) + 1.f);
+  if (cos_gamma < 0.f)
+    cos_phi = -cos_phi;
+  float sin_phi = cos_phi * tan_phi;
+  return make_float3(sin_phi * cos_theta, sin_theta, cos_phi * cos_theta);
 }
 
+/** \} */
+
 /* sample microfacets from a tilted mesonormal */
 ccl_device_inline float3 sample_wh(KernelGlobals kg,
                                    const bool beckmann,
@@ -224,8 +208,8 @@ ccl_device_inline float3 sample_wh(KernelGlobals kg,
   const float3 wi_wm = make_float3(dot(wi, s), dot(wi, t), dot(wi, n));
 
   float G1o;
-  const float3 wh_wm = microfacet_visible_normal_sample(
-      kg, beckmann, roughness, wi_wm, randu, randv, &G1o);
+  const float3 wh_wm = microfacet_sample_stretched(
+      kg, wi_wm, roughness, roughness, randu, randv, beckmann, &G1o);
 
   const float3 wh = wh_wm.x * s + wh_wm.y * t + wh_wm.z * n;
   return wh;
@@ -305,14 +289,14 @@ ccl_device float D(const bool beckmann, const float roughness, const float3 m, c
 }
 
 /* Fresnel */
+/* TODO: cleanup or refer to mitsuba */
 ccl_device float fresnel(float cos_theta_i,
                          float eta,
                          ccl_private float &cos_theta_t,
-                         ccl_private float &eta_it,
                          ccl_private float &eta_ti)
 {
   const float rcp_eta = 1.f / eta;
-  float cos_theta_i_abs;
+  float cos_theta_i_abs, eta_it;
   if (cos_theta_i >= 0.f) {
     eta_it = eta;
     eta_ti = rcp_eta;
@@ -348,42 +332,6 @@ ccl_device float fresnel(float cos_theta_i,
   return r;
 }
 
-ccl_device float fresnel0(float cos_theta_i, float eta)
-{
-  if (eta == 1.f)
-    return 0.f;
-  if (cos_theta_i == 0.f)
-    return 1.f;
-
-  const float rcp_eta = 1.f / eta;
-  float eta_it, eta_ti, cos_theta_i_abs;
-  if (cos_theta_i >= 0.f) {
-    eta_it = eta;
-    eta_ti = rcp_eta;
-    cos_theta_i_abs = cos_theta_i;
-  }
-  else {
-    eta_it = rcp_eta;
-    eta_ti = eta;
-    cos_theta_i_abs = -cos_theta_i;
-  }
-
-  /* Using Snell's law, calculate the squared sine of the angle between the surface normal and the
-   * transmitted ray */
-  float cos_theta_t_sqr = 1.f - eta_ti * eta_ti * (1.f - cos_theta_i * cos_theta_i);
-  float cos_theta_t_abs = safe_sqrtf(cos_theta_t_sqr);
-
-  /* Amplitudes of reflected waves */
-  float a_s = (cos_theta_i_abs - eta_it * cos_theta_t_abs) /
-              (cos_theta_i_abs + eta_it * cos_theta_t_abs);
-
-  float a_p = (cos_theta_t_abs - eta_it * cos_theta_i_abs) /
-              (cos_theta_t_abs + eta_it * cos_theta_i_abs);
-
-  float r = .5f * (sqr(a_s) + sqr(a_p));
-  return r;
-}
-
 ccl_device float3 bsdf_microfacet_hair_eval_r_circular(ccl_private const ShaderClosure *sc,
                                                        const float3 wi,
                                                        const float3 wo)
@@ -404,13 +352,13 @@ ccl_device float3 bsdf_microfacet_hair_eval_r_circular(ccl_private const ShaderC
 
   /* dot(wi, wmi) > 0 */
   const float tan_tilt = tanf(tilt);
-  float phi_m_max1 = acosf(fmaxf(-tan_tilt * tantheta(wi), 0.f));
+  float phi_m_max1 = acosf(fmaxf(-tan_tilt * tan_theta(wi), 0.f));
   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 * tantheta(wo), 0.f)) + phi_o;
+  const float phi_m_max2 = acosf(fmaxf(-tan_tilt * tan_theta(wo), 0.f)) + phi_o;
   if (isnan_safe(phi_m_max2))
     return R;
   const float phi_m_min2 = -phi_m_max2 + 2.f * phi_o;
@@ -434,8 +382,8 @@ ccl_device float3 bsdf_microfacet_hair_eval_r_circular(ccl_private const ShaderC
     const float cm = cosf(tilt);
 
     const float C = sqrtf(1.f - roughness_squared);
-    const float A = cm * costheta(wh) * C;
-    const fl

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list