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. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs