[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