[Bf-blender-cvs] [eac66768b71] principled-v2: Make clearcoat energy-conserving

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


Commit: eac66768b717419b723652232f1cd90526142680
Author: Lukas Stockner
Date:   Mon Jul 4 23:31:48 2022 +0200
Branches: principled-v2
https://developer.blender.org/rBeac66768b717419b723652232f1cd90526142680

Make clearcoat energy-conserving

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

M	intern/cycles/app/cycles_precompute.cpp
M	intern/cycles/kernel/closure/bsdf_microfacet_util.h
M	intern/cycles/kernel/svm/closure_principled.h
M	intern/cycles/kernel/tables.h

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

diff --git a/intern/cycles/app/cycles_precompute.cpp b/intern/cycles/app/cycles_precompute.cpp
index acc8d0d9fbf..6c744d952e0 100644
--- a/intern/cycles/app/cycles_precompute.cpp
+++ b/intern/cycles/app/cycles_precompute.cpp
@@ -67,6 +67,47 @@ static float precompute_sheen_E(float rough, float mu, float u1, float u2)
   return 0.0f;
 }
 
+static float precompute_clearcoat_E(float rough, float mu, float u1, float u2)
+{
+  MicrofacetBsdf bsdf;
+  bsdf.weight = one_float3();
+  bsdf.type = CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_V2_ID;
+  bsdf.sample_weight = 1.0f;
+  bsdf.N = make_float3(0.0f, 0.0f, 1.0f);
+  bsdf.alpha_x = bsdf.alpha_y = sqr(rough);
+  bsdf.ior = 1.5f;
+  bsdf.extra = nullptr;
+  bsdf.T = make_float3(1.0f, 0.0f, 0.0f);
+
+  /* Account for the albedo scaling that the closure performs.
+   * Dependency warning - this relies on the ggx_E and ggx_E_avg lookup tables! */
+  float E = microfacet_ggx_E(mu, rough), E_avg = microfacet_ggx_E_avg(rough);
+  float Fss = dielectric_fresnel_Fss(1.5f);
+  float Fms = Fss * E_avg / (1.0f - Fss * (1.0f - E_avg));
+  float albedo_scale = 1.0f + Fms * ((1.0f - E) / E);
+
+  float3 eval, omega_in, domega_in_dx, domega_in_dy;
+  float pdf = 0.0f;
+  bsdf_microfacet_ggx_sample((ShaderClosure *)&bsdf,
+                             make_float3(0.0f, 0.0f, 1.0f),
+                             make_float3(sqrtf(1.0f - sqr(mu)), 0.0f, mu),
+                             zero_float3(),
+                             zero_float3(),
+                             u1,
+                             u2,
+                             &eval,
+                             &omega_in,
+                             &domega_in_dx,
+                             &domega_in_dy,
+                             &pdf);
+  if (pdf != 0.0f) {
+    /* Encode relative to macrosurface Fresnel, saves resolution.
+     * TODO: Worth the extra evaluation? */
+    return albedo_scale * (average(eval) / pdf) / fresnel_dielectric_cos(mu, 1.5f);
+  }
+  return 0.0f;
+}
+
 static float precompute_ggx_E(float rough, float mu, float u1, float u2)
 {
   MicrofacetBsdf bsdf;
@@ -244,6 +285,10 @@ bool cycles_precompute(std::string name)
       2, 1 << 23, 32, [](float rough, float mu, float ior, float u1, float u2, uint *rng) {
         return precompute_sheen_E(rough, mu, u1, u2);
       }};
+  precompute_terms["clearcoat_E"] = {
+      2, 1 << 23, 16, [](float rough, float mu, float ior, float u1, float u2, uint *rng) {
+        return precompute_clearcoat_E(rough, mu, u1, u2);
+      }};
   precompute_terms["ggx_E"] = {
       2, 1 << 23, 32, [](float rough, float mu, float ior, float u1, float u2, uint *rng) {
         return precompute_ggx_E(rough, mu, u1, u2);
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet_util.h b/intern/cycles/kernel/closure/bsdf_microfacet_util.h
index 46ebe1539b4..a2695d00ad5 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet_util.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet_util.h
@@ -172,6 +172,25 @@ ccl_device_forceinline float microfacet_ggx_E_avg(float rough)
   return saturatef(lerp(table_ggx_E_avg[rough_i], table_ggx_E_avg[rough_i1], rough));
 }
 
+ccl_device_forceinline float clearcoat_E(float mu, float rough)
+{
+  float macro_fresnel = fresnel_dielectric_cos(mu, 1.5f);
+  rough = saturatef(1 - rough - 1.0f / 32.0f) * 16.0f;
+  mu = saturatef(mu - 1.0f / 32.0f) * 16.0f;
+
+  int rough_i = min(15, (int)rough);
+  int rough_i1 = min(15, rough_i + 1);
+  int mu_i = min(15, (int)mu);
+  int mu_i1 = min(15, mu_i + 1);
+
+  rough -= rough_i;
+  mu -= mu_i;
+
+  float a = lerp(table_clearcoat_E[rough_i][mu_i], table_clearcoat_E[rough_i][mu_i1], mu);
+  float b = lerp(table_clearcoat_E[rough_i1][mu_i], table_clearcoat_E[rough_i1][mu_i1], mu);
+  return saturatef(lerp(a, b, rough)) * macro_fresnel;
+}
+
 ccl_device_inline float3 metallic_Fss(float3 F0, float3 F90, float falloff)
 {
   /* Fss for lerp(F0, F90, (1-cosNI)^falloff) */
diff --git a/intern/cycles/kernel/svm/closure_principled.h b/intern/cycles/kernel/svm/closure_principled.h
index 0d50f396e80..7066d72d533 100644
--- a/intern/cycles/kernel/svm/closure_principled.h
+++ b/intern/cycles/kernel/svm/closure_principled.h
@@ -508,7 +508,7 @@ ccl_device_inline float principled_v2_clearcoat(KernelGlobals kg,
   /* setup bsdf */
   sd->flag |= bsdf_microfacet_ggx_clearcoat_v2_setup(bsdf, sd);
 
-  return 0.04f * clearcoat;  // TODO better approx
+  return clearcoat_E(dot(sd->I, N), roughness) * clearcoat;
 }
 
 ccl_device_inline float principled_v2_sheen(KernelGlobals kg,
diff --git a/intern/cycles/kernel/tables.h b/intern/cycles/kernel/tables.h
index 733affec6c7..39ad62d34f5 100644
--- a/intern/cycles/kernel/tables.h
+++ b/intern/cycles/kernel/tables.h
@@ -1302,4 +1302,23 @@ static const float table_ggx_dielectric_inv_E[16][16][16] = {
   }
 };
 
+static const float table_clearcoat_E[16][16] = {
+    {0.0957937f, 0.107269f, 0.124314f, 0.145841f, 0.171902f, 0.202507f, 0.237239f, 0.274857f, 0.313117f, 0.348864f, 0.378594f, 0.399369f, 0.409696f, 0.409948f, 0.401807f, 0.387712f},
+    {0.103913f, 0.118336f, 0.138516f, 0.163634f, 0.193917f, 0.229433f, 0.269794f, 0.313709f, 0.358702f, 0.40124f, 0.437384f, 0.463666f, 0.478306f, 0.481542f, 0.475314f, 0.462174f},
+    {0.114001f, 0.131792f, 0.155509f, 0.184656f, 0.219564f, 0.260417f, 0.30679f, 0.357311f, 0.409259f, 0.458766f, 0.501395f, 0.533305f, 0.552494f, 0.559133f, 0.55525f, 0.543762f},
+    {0.126718f, 0.148352f, 0.17616f, 0.209868f, 0.24991f, 0.296499f, 0.349183f, 0.406439f, 0.465305f, 0.521516f, 0.570303f, 0.607454f, 0.630828f, 0.640633f, 0.639167f, 0.629563f},
+    {0.142942f, 0.169096f, 0.201677f, 0.240591f, 0.28632f, 0.339067f, 0.398261f, 0.462106f, 0.527417f, 0.589522f, 0.643291f, 0.684462f, 0.710811f, 0.722861f, 0.72308f, 0.715033f},
+    {0.163824f, 0.195379f, 0.233628f, 0.278595f, 0.330697f, 0.390005f, 0.455709f, 0.525685f, 0.596293f, 0.662552f, 0.719195f, 0.762062f, 0.789222f, 0.801605f, 0.802171f, 0.794678f},
+    {0.190934f, 0.22908f, 0.274143f, 0.326182f, 0.385488f, 0.451664f, 0.523495f, 0.598289f, 0.671959f, 0.739469f, 0.795561f, 0.836672f, 0.86164f, 0.872011f, 0.871178f, 0.863261f},
+    {0.226325f, 0.272583f, 0.325986f, 0.38642f, 0.453616f, 0.526553f, 0.603038f, 0.679948f, 0.75296f, 0.81709f, 0.868099f, 0.903421f, 0.923006f, 0.929287f, 0.925963f, 0.917004f},
+    {0.272522f, 0.328901f, 0.392562f, 0.462815f, 0.538096f, 0.61602f, 0.69377f, 0.767744f, 0.834187f, 0.889376f, 0.930485f, 0.95656f, 0.968832f, 0.970247f, 0.964471f, 0.954985f},
+    {0.332556f, 0.401548f, 0.477887f, 0.55866f, 0.639798f, 0.717851f, 0.789919f, 0.853651f, 0.906877f, 0.947986f, 0.976068f, 0.991628f, 0.996712f, 0.994261f, 0.987344f, 0.978504f},
+    {0.409615f, 0.494384f, 0.585635f, 0.674102f, 0.753563f, 0.82181f, 0.878802f, 0.925017f, 0.960756f, 0.986191f, 1.0019f, 1.00903f, 1.00942f, 1.00538f, 0.99908f, 0.992107f},
+    {0.506354f, 0.611394f, 0.715256f, 0.799046f, 0.86226f, 0.909737f, 0.945706f, 0.97248f, 0.99164f, 1.00413f, 1.01079f, 1.01265f, 1.01105f, 1.00732f, 1.00272f, 0.998148f},
+    {0.623822f, 0.753034f, 0.849494f, 0.907052f, 0.942889f, 0.966663f, 0.983133f, 0.994624f, 1.00237f, 1.00692f, 1.00888f, 1.00874f, 1.00721f, 1.00488f, 1.00236f, 0.999994f},
+    {0.762026f, 0.895731f, 0.949127f, 0.971914f, 0.984199f, 0.991853f, 0.996957f, 1.00045f, 1.00264f, 1.00378f, 1.0041f, 1.00375f, 1.00303f, 1.00205f, 1.00108f, 1.00021f},
+    {0.905247f, 0.980365f, 0.991431f, 0.995528f, 0.997658f, 0.999011f, 0.999864f, 1.00045f, 1.00079f, 1.00093f, 1.00094f, 1.00083f, 1.00064f, 1.00045f, 1.00025f, 1.00006f},
+    {0.989008f, 0.999275f, 0.999681f, 0.999839f, 0.999929f, 0.99998f, 1.00001f, 1.00003f, 1.00004f, 1.00005f, 1.00005f, 1.00004f, 1.00003f, 1.00002f, 1.00002f, 1.0f}
+};
+
 /* clang-format on */



More information about the Bf-blender-cvs mailing list