Fix T74345: missing albedo for Cycles principled hair BSDF
authorBrecht Van Lommel <brechtvanlommel@gmail.com>
Fri, 20 Mar 2020 14:22:29 +0000 (15:22 +0100)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Fri, 20 Mar 2020 14:23:39 +0000 (15:23 +0100)
intern/cycles/kernel/closure/bsdf_hair_principled.h
intern/cycles/kernel/kernel_passes.h
intern/cycles/kernel/svm/svm_closure.h

index 4db5a6cc8309a080161f7388c32f08994819e643..f78bbeb5d9d1c598ba067e906de67eb40f5c1875 100644 (file)
@@ -493,6 +493,36 @@ ccl_device void bsdf_principled_hair_blur(ShaderClosure *sc, float roughness)
   bsdf->m0_roughness = fmaxf(roughness, bsdf->m0_roughness);
 }
 
+/* Hair Albedo */
+
+ccl_device_inline float bsdf_principled_hair_albedo_roughness_scale(
+    const float azimuthal_roughness)
+{
+  const float x = azimuthal_roughness;
+  return (((((0.245f * x) + 5.574f) * x - 10.73f) * x + 2.532f) * x - 0.215f) * x + 5.969f;
+}
+
+ccl_device float3 bsdf_principled_hair_albedo(ShaderClosure *sc)
+{
+  PrincipledHairBSDF *bsdf = (PrincipledHairBSDF *)sc;
+  return exp3(-sqrt(bsdf->sigma) * bsdf_principled_hair_albedo_roughness_scale(bsdf->v));
+}
+
+ccl_device_inline float3
+bsdf_principled_hair_sigma_from_reflectance(const float3 color, const float azimuthal_roughness)
+{
+  const float3 sigma = log3(color) /
+                       bsdf_principled_hair_albedo_roughness_scale(azimuthal_roughness);
+  return sigma * sigma;
+}
+
+ccl_device_inline float3 bsdf_principled_hair_sigma_from_concentration(const float eumelanin,
+                                                                       const float pheomelanin)
+{
+  return eumelanin * make_float3(0.506f, 0.841f, 1.653f) +
+         pheomelanin * make_float3(0.343f, 0.733f, 1.924f);
+}
+
 CCL_NAMESPACE_END
 
 #endif /* __BSDF_HAIR_PRINCIPLED_H__ */
index 33ec05c6048631f250f99e6ad31be52495decb74..98136bc7047f9df3a6e9ac25263fd1fd747cd964 100644 (file)
@@ -87,6 +87,9 @@ ccl_device_inline void kernel_update_denoising_features(KernelGlobals *kg,
       PrincipledSheenBsdf *bsdf = (PrincipledSheenBsdf *)sc;
       closure_albedo *= bsdf->avg_value;
     }
+    else if (sc->type == CLOSURE_BSDF_HAIR_PRINCIPLED_ID) {
+      closure_albedo *= bsdf_principled_hair_albedo(sc);
+    }
 
     if (bsdf_get_specular_roughness_squared(sc) > sqr(0.075f)) {
       diffuse_albedo += closure_albedo;
index bf2d3f4fbffe0e8b6aa34edda19480463c09f517..cb1b521c585a4fcbca47184190059e7410a33181 100644 (file)
 
 CCL_NAMESPACE_BEGIN
 
-/* Hair Melanin */
-
-ccl_device_inline float3 sigma_from_concentration(float eumelanin, float pheomelanin)
-{
-  return eumelanin * make_float3(0.506f, 0.841f, 1.653f) +
-         pheomelanin * make_float3(0.343f, 0.733f, 1.924f);
-}
-
-ccl_device_inline float3 sigma_from_reflectance(float3 color, float azimuthal_roughness)
-{
-  float x = azimuthal_roughness;
-  float roughness_fac = (((((0.245f * x) + 5.574f) * x - 10.73f) * x + 2.532f) * x - 0.215f) * x +
-                        5.969f;
-  float3 sigma = log3(color) / roughness_fac;
-  return sigma * sigma;
-}
-
 /* Closure Nodes */
 
 ccl_device void svm_node_glass_setup(
@@ -868,24 +851,26 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg,
             /* Benedikt Bitterli's melanin ratio remapping. */
             float eumelanin = melanin * (1.0f - melanin_redness);
             float pheomelanin = melanin * melanin_redness;
-            float3 melanin_sigma = sigma_from_concentration(eumelanin, pheomelanin);
+            float3 melanin_sigma = bsdf_principled_hair_sigma_from_concentration(eumelanin,
+                                                                                 pheomelanin);
 
             /* Optional tint. */
             float3 tint = stack_load_float3(stack, tint_ofs);
-            float3 tint_sigma = sigma_from_reflectance(tint, radial_roughness);
+            float3 tint_sigma = bsdf_principled_hair_sigma_from_reflectance(tint,
+                                                                            radial_roughness);
 
             bsdf->sigma = melanin_sigma + tint_sigma;
             break;
           }
           case NODE_PRINCIPLED_HAIR_REFLECTANCE: {
             float3 color = stack_load_float3(stack, color_ofs);
-            bsdf->sigma = sigma_from_reflectance(color, radial_roughness);
+            bsdf->sigma = bsdf_principled_hair_sigma_from_reflectance(color, radial_roughness);
             break;
           }
           default: {
             /* Fallback to brownish hair, same as defaults for melanin. */
             kernel_assert(!"Invalid Principled Hair parametrization!");
-            bsdf->sigma = sigma_from_concentration(0.0f, 0.8054375f);
+            bsdf->sigma = bsdf_principled_hair_sigma_from_concentration(0.0f, 0.8054375f);
             break;
           }
         }