[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