[Bf-blender-cvs] [f0529cfabc7] microfacet_hair: Add support for OSL shader to microfacet hair model

Weizhen Huang noreply at git.blender.org
Mon Jan 16 16:17:28 CET 2023


Commit: f0529cfabc759712dfe19a575f914aa1aca9c277
Author: Weizhen Huang
Date:   Mon Jan 16 16:16:58 2023 +0100
Branches: microfacet_hair
https://developer.blender.org/rBf0529cfabc759712dfe19a575f914aa1aca9c277

Add support for OSL shader to microfacet hair model

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

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/scene/shader_nodes.cpp

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

diff --git a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h
index ff372ab947b..be3d7d7e105 100644
--- a/intern/cycles/kernel/closure/bsdf_hair_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_hair_microfacet.h
@@ -17,8 +17,6 @@ typedef struct MicrofacetHairExtra {
   float TT;
   float TRT;
 
-  float aspect_ratio;
-
   /* Geometry data. */
   float4 geom;
 } MicrofacetHairExtra;
@@ -41,6 +39,9 @@ typedef struct MicrofacetHairBSDF {
   /* Circular/Elliptical */
   int cross_section;
 
+  /* The ratio of the minor axis to the major axis. */
+  float aspect_ratio;
+
   /* Extra closure. */
   ccl_private MicrofacetHairExtra *extra;
 } MicrofacetHairBSDF;
@@ -74,8 +75,20 @@ ccl_device int bsdf_microfacet_hair_setup(ccl_private ShaderData *sd,
   kernel_assert(isfinite_safe(h));
 
   if (bsdf->cross_section == NODE_MICROFACET_HAIR_ELLIPTIC) {
-    /* Local frame is independent of the ray direction for elliptical hairs. */
-    bsdf->extra->geom.w = h;
+    if (bsdf->aspect_ratio > 1.0f) {
+      bsdf->aspect_ratio = 1.0f / bsdf->aspect_ratio;
+
+      /* Switch major and minor axis. */
+      const float3 minor_axis = safe_normalize(cross(
+          sd->dPdu, make_float3(bsdf->extra->geom.x, bsdf->extra->geom.y, bsdf->extra->geom.z)));
+      const float3 major_axis = safe_normalize(cross(minor_axis, sd->dPdu));
+
+      /* Local frame is independent of the ray direction for elliptical hairs. */
+      bsdf->extra->geom = make_float4(major_axis.x, major_axis.y, major_axis.z, h);
+    }
+    else {
+      bsdf->extra->geom.w = h;
+    }
   }
   else {
     bsdf->extra->geom = make_float4(X.x, X.y, X.z, h);
@@ -802,7 +815,7 @@ ccl_device float3 bsdf_microfacet_hair_eval_r_elliptic(ccl_private const ShaderC
   /* get elliptical cross section characteristic */
   const float a = 1.0f;
   /* TODO: rename this as aspect ratio? e is in [0, 0.85], b is in [0.52, 1]. */
-  const float b = bsdf->extra->aspect_ratio;
+  const float b = bsdf->aspect_ratio;
   const float e2 = 1.0f - sqr(b / a);
 
   /* this follows blender's convention (unlike the circular case?) */
@@ -898,7 +911,7 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_elliptic(KernelGlobals kg,
     return zero_float3();
   }
 
-  /* this follows blender's convention (unlike the circular case?) */
+  /* TODO: switch wi and wo? */
   const float3 wo = wi_;
   const float3 wi = wo_;
 
@@ -923,7 +936,7 @@ ccl_device float3 bsdf_microfacet_hair_eval_tt_trt_elliptic(KernelGlobals kg,
 
   /* get elliptical cross section characteristic */
   const float a = 1.0f;
-  const float b = bsdf->extra->aspect_ratio;
+  const float b = bsdf->aspect_ratio;
   const float e2 = 1.0f - sqr(b / a); /* Squared Eccentricity. */
 
   const float gamma_m_min = to_gamma(phi_m_min, a, b) + 1e-3f;
@@ -1094,7 +1107,7 @@ ccl_device Spectrum bsdf_microfacet_hair_eval_elliptic(KernelGlobals kg,
   const float3 wo = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z));
 
   /* Treat as transparent material if intersection lies outside of the projected radius. */
-  const float e2 = 1.0f - sqr(bsdf->extra->aspect_ratio);
+  const float e2 = 1.0f - sqr(bsdf->aspect_ratio);
   const float radius = sqrtf(1.0f - e2 * sqr(sin_phi(wi)));
   if (fabsf(bsdf->extra->geom.w) > radius) {
     *pdf = 0.0f;
@@ -1136,7 +1149,7 @@ ccl_device int bsdf_microfacet_hair_sample_elliptic(const KernelGlobals kg,
 
   /* get elliptical cross section characteristic */
   const float a = 1.0f;
-  const float b = bsdf->extra->aspect_ratio;
+  const float b = bsdf->aspect_ratio;
   const float e2 = 1.0f - sqr(b / a);
 
   /* macronormal */
@@ -1345,7 +1358,7 @@ ccl_device Spectrum bsdf_microfacet_hair_eval(KernelGlobals kg,
 {
   ccl_private MicrofacetHairBSDF *bsdf = (ccl_private MicrofacetHairBSDF *)sc;
 
-  if (bsdf->cross_section == NODE_MICROFACET_HAIR_CIRCULAR || bsdf->extra->aspect_ratio == 1.0f) {
+  if (bsdf->cross_section == NODE_MICROFACET_HAIR_CIRCULAR || bsdf->aspect_ratio == 1.0f) {
     return bsdf_microfacet_hair_eval_circular(kg, sd, sc, omega_in, pdf);
   }
 
@@ -1365,7 +1378,7 @@ ccl_device int bsdf_microfacet_hair_sample(KernelGlobals kg,
 {
   ccl_private MicrofacetHairBSDF *bsdf = (ccl_private MicrofacetHairBSDF *)sc;
 
-  if (bsdf->cross_section == NODE_MICROFACET_HAIR_CIRCULAR || bsdf->extra->aspect_ratio == 1.0f) {
+  if (bsdf->cross_section == NODE_MICROFACET_HAIR_CIRCULAR || bsdf->aspect_ratio == 1.0f) {
     return bsdf_microfacet_hair_sample_circular(
         kg, sc, sd, randu, randv, eval, omega_in, pdf, sampled_roughness, eta);
   }
diff --git a/intern/cycles/kernel/osl/closures_setup.h b/intern/cycles/kernel/osl/closures_setup.h
index ceaf56ccba6..a419589880e 100644
--- a/intern/cycles/kernel/osl/closures_setup.h
+++ b/intern/cycles/kernel/osl/closures_setup.h
@@ -23,6 +23,7 @@
 #include "kernel/closure/bsdf_toon.h"
 #include "kernel/closure/bsdf_hair.h"
 #include "kernel/closure/bsdf_hair_principled.h"
+#include "kernel/closure/bsdf_hair_microfacet.h"
 #include "kernel/closure/bsdf_principled_diffuse.h"
 #include "kernel/closure/bsdf_principled_sheen.h"
 #include "kernel/closure/volume.h"
@@ -1121,6 +1122,49 @@ ccl_device void osl_closure_principled_hair_setup(KernelGlobals kg,
 #endif
 }
 
+ccl_device void osl_closure_microfacet_hair_setup(KernelGlobals kg,
+                                                  ccl_private ShaderData *sd,
+                                                  uint32_t path_flag,
+                                                  float3 weight,
+                                                  ccl_private const MicrofacetHairClosure *closure)
+{
+#ifdef __HAIR__
+  if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY)) {
+    return;
+  }
+
+  ccl_private MicrofacetHairBSDF *bsdf = (ccl_private MicrofacetHairBSDF *)bsdf_alloc(
+      sd, sizeof(MicrofacetHairBSDF), rgb_to_spectrum(weight));
+  if (!bsdf) {
+    return;
+  }
+
+  ccl_private MicrofacetHairExtra *extra = (ccl_private MicrofacetHairExtra *)closure_alloc_extra(
+      sd, sizeof(MicrofacetHairExtra));
+  if (!extra) {
+    return;
+  }
+
+  bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N);
+  bsdf->sigma = closure->sigma;
+  bsdf->roughness = closure->roughness;
+  bsdf->tilt = closure->tilt;
+  bsdf->eta = closure->eta;
+  bsdf->cross_section = closure->cross_section;
+  bsdf->distribution_type = closure->distribution_type;
+  bsdf->aspect_ratio = closure->aspect_ratio;
+
+  bsdf->extra = extra;
+  bsdf->extra->R = closure->reflection;
+  bsdf->extra->TT = closure->transmission;
+  bsdf->extra->TRT = closure->secondary_reflection;
+  bsdf->extra->geom = make_float4(
+      closure->major_axis.x, closure->major_axis.y, closure->major_axis.z, 0.0f);
+
+  sd->flag |= bsdf_microfacet_hair_setup(sd, bsdf);
+#endif
+}
+
 /* Volume */
 
 ccl_device void osl_closure_absorption_setup(KernelGlobals kg,
diff --git a/intern/cycles/kernel/osl/closures_template.h b/intern/cycles/kernel/osl/closures_template.h
index b9e9b52dcf8..f799010534d 100644
--- a/intern/cycles/kernel/osl/closures_template.h
+++ b/intern/cycles/kernel/osl/closures_template.h
@@ -245,6 +245,21 @@ OSL_CLOSURE_STRUCT_BEGIN(PrincipledHair, principled_hair)
   OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, FLOAT, float, eta, NULL)
 OSL_CLOSURE_STRUCT_END(PrincipledHair, principled_hair)
 
+OSL_CLOSURE_STRUCT_BEGIN(MicrofacetHair, microfacet_hair)
+  OSL_CLOSURE_STRUCT_MEMBER(MicrofacetHair, VECTOR, packed_float3, N, NULL)
+  OSL_CLOSURE_STRUCT_MEMBER(MicrofacetHair, VECTOR, packed_float3, sigma, NULL)
+  OSL_CLOSURE_STRUCT_MEMBER(MicrofacetHair, FLOAT, float, roughness, NULL)
+  OSL_CLOSURE_STRUCT_MEMBER(MicrofacetHair, FLOAT, float, tilt, NULL)
+  OSL_CLOSURE_STRUCT_MEMBER(MicrofacetHair, FLOAT, float, eta, NULL)
+  OSL_CLOSURE_STRUCT_MEMBER(MicrofacetHair, INT, int, distribution_type, NULL)
+  OSL_CLOSURE_STRUCT_MEMBER(MicrofacetHair, INT, int, cross_section, NULL)
+  OSL_CLOSURE_STRUCT_MEMBER(MicrofacetHair, FLOAT, float, aspect_ratio, NULL)
+  OSL_CLOSURE_STRUCT_MEMBER(MicrofacetHair, FLOAT, float, reflection, NULL)
+  OSL_CLOSURE_STRUCT_MEMBER(MicrofacetHair, FLOAT, float, transmission, NULL)
+  OSL_CLOSURE_STRUCT_MEMBER(MicrofacetHair, FLOAT, float, secondary_reflection, NULL)
+  OSL_CLOSURE_STRUCT_MEMBER(MicrofacetHair, VECTOR, packed_float3, major_axis, NULL)
+OSL_CLOSURE_STRUCT_END(MicrofacetHair, microfacet_hair)
+
 OSL_CLOSURE_STRUCT_BEGIN(VolumeAbsorption, absorption)
 OSL_CLOSURE_STRUCT_END(VolumeAbsorption, absorption)
 
diff --git a/intern/cycles/kernel/osl/shaders/node_microfacet_hair_bsdf.osl b/intern/cycles/kernel/osl/shaders/node_microfacet_hair_bsdf.osl
index 162b3b682f1..4f0a7f129ed 100644
--- a/intern/cycles/kernel/osl/shaders/node_microfacet_hair_bsdf.osl
+++ b/intern/cycles/kernel/osl/shaders/node_microfacet_hair_bsdf.osl
@@ -51,6 +51,10 @@ shader node_microfacet_hair_bsdf(color Color = color(0.017513, 0.005763, 0.00205
                                  float IOR = 1.55,
                                  string AttrRandom = "geom:curve_random",
                                  float Random = 0.0,
+                                 float AspectRatio = 0.85,
+                                 float Reflection = 1.0,
+                                 float Transmission = 1.0,
+                                 float SecondaryReflection = 1.0,
 
                                  output closure color BSDF = 0)
 {
@@ -99,5 +103,26 @@ shader node_microfacet_hair_bsdf(color Color = color(0.017513, 0.005763, 0.00205
     sigma = m_sigma_from_concentration(0.0, 0.8054375);
   }
 
-  BSDF = microfacet_hair(Normal, sigma, roughness, Offset, IOR);
+  int distribution_type_enum = (distribution_type == "GGX") ? 0 : 1;
+  int cross_section_enum = 0;
+  normal major_axis = 0.0;
+
+  if (cross_section == "Elliptical") {
+    cross_section_enum = 1;
+    major_axis = 1.0;
+    getattribute("geom:N", major_axis);
+  }
+
+  BSDF = microfacet_hair(Normal,
+                         sigma,
+                         roughness,
+                         Offset,
+                         IOR,
+                         distribution_type_enum,
+                         cross_section_enum,
+         

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list