[Bf-blender-cvs] [49ed792a789] principled-v2: Clean up existing fresnel handling

Lukas Stockner noreply at git.blender.org
Mon Jul 4 23:56:11 CEST 2022


Commit: 49ed792a7890cd473d42ba33d94bc4a773e99e77
Author: Lukas Stockner
Date:   Mon Jul 4 23:31:47 2022 +0200
Branches: principled-v2
https://developer.blender.org/rB49ed792a7890cd473d42ba33d94bc4a773e99e77

Clean up existing fresnel handling

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

M	intern/cycles/kernel/closure/bsdf_microfacet.h
M	intern/cycles/kernel/closure/bsdf_microfacet_multi_impl.h
M	intern/cycles/kernel/closure/bsdf_util.h

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

diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h
index 29b0e4b3046..42ea71f62a9 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet.h
@@ -39,16 +39,16 @@ ccl_device_forceinline float3 reflection_color(ccl_private const MicrofacetBsdf
                                                float3 L,
                                                float3 H)
 {
-  float3 F = make_float3(1.0f, 1.0f, 1.0f);
-  bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID ||
-                      bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID);
-  if (use_fresnel) {
-    float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
-
-    F = interpolate_fresnel_color(L, H, bsdf->ior, F0, bsdf->extra->cspec0);
+  if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID) {
+    return interpolate_fresnel_color(L, H, bsdf->ior, bsdf->extra->cspec0);
+  }
+  else if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
+    return 0.25f * interpolate_fresnel_color(L, H, bsdf->ior, bsdf->extra->cspec0) *
+           bsdf->extra->clearcoat;
+  }
+  else {
+    return one_float3();
   }
-
-  return F;
 }
 
 ccl_device_forceinline void bsdf_microfacet_fresnel_color(ccl_private const ShaderData *sd,
@@ -56,9 +56,8 @@ ccl_device_forceinline void bsdf_microfacet_fresnel_color(ccl_private const Shad
 {
   kernel_assert(CLOSURE_IS_BSDF_MICROFACET_FRESNEL(bsdf->type));
 
-  float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
   bsdf->extra->fresnel_color = interpolate_fresnel_color(
-      sd->I, bsdf->N, bsdf->ior, F0, bsdf->extra->cspec0);
+      sd->I, bsdf->N, bsdf->ior, bsdf->extra->cspec0);
 
   if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
     bsdf->extra->fresnel_color *= 0.25f * bsdf->extra->clearcoat;
@@ -295,9 +294,6 @@ ccl_device float3 bsdf_microfacet_ggx_eval_reflect(ccl_private const ShaderClosu
     float common = D * 0.25f / cosNO;
 
     float3 F = reflection_color(bsdf, omega_in, m);
-    if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
-      F *= 0.25f * bsdf->extra->clearcoat;
-    }
 
     float3 out = F * common / (1 + lambdaO + lambdaI);
     *pdf = common / (1 + lambdaO);
@@ -409,18 +405,11 @@ ccl_device int bsdf_microfacet_ggx_sample(ccl_private const ShaderClosure *sc,
         *omega_in = 2 * cosMO * m - I;
 
         if (dot(Ng, *omega_in) > 0) {
+          float3 F = reflection_color(bsdf, *omega_in, m);
           if (alpha_x * alpha_y <= 1e-7f) {
             /* Specular case, just return some high number for MIS */
             *pdf = 1e6f;
-            *eval = make_float3(1e6f, 1e6f, 1e6f);
-
-            bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID ||
-                                bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID);
-
-            /* if fresnel is used, calculate the color with reflection_color(...) */
-            if (use_fresnel) {
-              *eval *= reflection_color(bsdf, *omega_in, m);
-            }
+            *eval = make_float3(1e6f, 1e6f, 1e6f) * F;
 
             label = LABEL_REFLECT | LABEL_SINGULAR;
           }
@@ -465,15 +454,9 @@ ccl_device int bsdf_microfacet_ggx_sample(ccl_private const ShaderClosure *sc,
             float common = D * 0.25f / cosNO;
             *pdf = common / (1 + lambdaO);
 
-            float3 F = reflection_color(bsdf, *omega_in, m);
-
             *eval = common * F / (1 + lambdaO + lambdaI);
           }
 
-          if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
-            *eval *= 0.25f * bsdf->extra->clearcoat;
-          }
-
 #ifdef __RAY_DIFFERENTIALS__
           *domega_in_dx = (2 * dot(m, dIdx)) * m - dIdx;
           *domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy;
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet_multi_impl.h b/intern/cycles/kernel/closure/bsdf_microfacet_multi_impl.h
index e4fcf0e6ba3..539853aab16 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet_multi_impl.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet_multi_impl.h
@@ -73,9 +73,8 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_eval)(float3 wi,
   eval = make_float3(val, val, val);
 #endif
 
-  float F0 = fresnel_dielectric_cos(1.0f, eta);
   if (use_fresnel) {
-    throughput = interpolate_fresnel_color(wi, wh, eta, F0, cspec0);
+    throughput = interpolate_fresnel_color(wi, wh, eta, cspec0);
 
     eval *= throughput;
   }
@@ -144,11 +143,11 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_eval)(float3 wi,
         throughput *= color;
       }
       else if (use_fresnel && order > 0) {
-        throughput *= interpolate_fresnel_color(wi_prev, wm, eta, F0, cspec0);
+        throughput *= interpolate_fresnel_color(wi_prev, wm, eta, cspec0);
       }
 #else /* MF_MULTI_GLOSSY */
       if (use_fresnel && order > 0) {
-        throughput *= interpolate_fresnel_color(-wr, wm, eta, F0, cspec0);
+        throughput *= interpolate_fresnel_color(-wr, wm, eta, cspec0);
       }
       wr = mf_sample_phase_glossy(-wr, &throughput, wm);
 #endif
@@ -192,8 +191,6 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_sample)(float3 wi,
   float G1_r = 0.0f;
   bool outside = true;
 
-  float F0 = fresnel_dielectric_cos(1.0f, eta);
-
   int order;
   for (order = 0; order < 10; order++) {
     /* Sample microfacet height. */
@@ -229,7 +226,7 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_sample)(float3 wi,
         throughput *= color;
       }
       else {
-        float3 t_color = interpolate_fresnel_color(wi_prev, wm, eta, F0, cspec0);
+        float3 t_color = interpolate_fresnel_color(wi_prev, wm, eta, cspec0);
 
         if (order == 0)
           throughput = t_color;
@@ -239,7 +236,7 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_sample)(float3 wi,
     }
 #else /* MF_MULTI_GLOSSY */
     if (use_fresnel) {
-      float3 t_color = interpolate_fresnel_color(-wr, wm, eta, F0, cspec0);
+      float3 t_color = interpolate_fresnel_color(-wr, wm, eta, cspec0);
 
       if (order == 0)
         throughput = t_color;
diff --git a/intern/cycles/kernel/closure/bsdf_util.h b/intern/cycles/kernel/closure/bsdf_util.h
index e3b24d487f1..a1541a01cd5 100644
--- a/intern/cycles/kernel/closure/bsdf_util.h
+++ b/intern/cycles/kernel/closure/bsdf_util.h
@@ -109,19 +109,17 @@ ccl_device float schlick_fresnel(float u)
   return m2 * m2 * m;  // pow(m, 5)
 }
 
-/* Calculate the fresnel color which is a blend between white and the F0 color (cspec0) */
+/* Calculate the fresnel color which is a blend between white and the F0 color */
 ccl_device_forceinline float3
-interpolate_fresnel_color(float3 L, float3 H, float ior, float F0, float3 cspec0)
+interpolate_fresnel_color(float3 L, float3 H, float ior, float3 F0)
 {
-  /* Calculate the fresnel interpolation factor
-   * The value from fresnel_dielectric_cos(...) has to be normalized because
-   * the cspec0 keeps the F0 color
-   */
-  float F0_norm = 1.0f / (1.0f - F0);
-  float FH = (fresnel_dielectric_cos(dot(L, H), ior) - F0) * F0_norm;
+  /* Compute the real Fresnel term and remap it from real_F0...1 to F0...1.
+   * We could also just use actual Schlick fresnel (lerp(F0, 1, (1-cosI)^5)) here. */
+  float real_F0 = fresnel_dielectric_cos(1.0f, ior);
+  float F0_norm = 1.0f / (1.0f - real_F0);
+  float FH = (fresnel_dielectric_cos(dot(L, H), ior) - real_F0) * F0_norm;
 
-  /* Blend between white and a specular color with respect to the fresnel */
-  return cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH;
+  return lerp(F0, one_float3(), FH);
 }
 
 ccl_device float3 ensure_valid_reflection(float3 Ng, float3 I, float3 N)



More information about the Bf-blender-cvs mailing list