[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