Commit: dbdd2bb454559a757b007cfddfa773326751fc2d Author: Lukas Stockner Date: Mon Jul 4 23:31:48 2022 +0200 Branches: principled-v2 https://developer.blender.org/rBdbdd2bb454559a757b007cfddfa773326751fc2d
Add energy compensation for specular component =================================================================== 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 5ca0ac0953e..1b399df3d01 100644 --- a/intern/cycles/app/cycles_precompute.cpp +++ b/intern/cycles/app/cycles_precompute.cpp @@ -165,6 +165,49 @@ static float precompute_ggx_glass_E( return 0.0f; } +static float precompute_ggx_dielectric_E(float rough, float mu, float eta, float u1, float u2) +{ + // TODO: Reparametrize based on fresnel_dielectric_cos(mu, eta) instead of mu to get more resolution? + // Probably need lerp(mu, fresnel_dielectric_cos(mu, eta), 0.9) or so because of flat IOR region. + MicrofacetExtrav2 extra; + MicrofacetBsdf bsdf; + bsdf.weight = one_float3(); + bsdf.type = CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_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 = eta; + bsdf.extra = (MicrofacetExtra *)&extra; + bsdf.T = make_float3(1.0f, 0.0f, 0.0f); + extra.metal_base = extra.metal_edge = zero_float3(); + extra.metal_falloff = 0.0f; + + /* 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(eta); + float Fms = Fss * E_avg / (1.0f - Fss * (1.0f - E_avg)); + extra.dielectric = 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) { + return average(eval) / pdf; + } + return 0.0f; +} + struct PrecomputeTerm { int dim, samples, res; std::function<float(float, float, float, float, float, uint *)> evaluation; @@ -202,6 +245,15 @@ bool cycles_precompute(std::string name) 3, 1 << 20, 16, [](float rough, float mu, float ior, float u1, float u2, uint *rng) { return precompute_ggx_refract_E(rough, mu, 1.0f / ior, u1, u2); }}; + precompute_terms["ggx_dielectric_E"] = { + 3, 1 << 20, 16, [](float rough, float mu, float ior, float u1, float u2, uint *rng) { + return precompute_ggx_dielectric_E(rough, mu, ior, u1, u2); + }}; + // TODO: Consider more X resolution for this table. + precompute_terms["ggx_dielectric_inv_E"] = { + 3, 1 << 20, 16, [](float rough, float mu, float ior, float u1, float u2, uint *rng) { + return precompute_ggx_dielectric_E(rough, mu, 1.0f / ior, u1, u2); + }}; if (precompute_terms.count(name) == 0) { return false; diff --git a/intern/cycles/kernel/closure/bsdf_microfacet_util.h b/intern/cycles/kernel/closure/bsdf_microfacet_util.h index d8a7b5f9a87..509cd6708ec 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet_util.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet_util.h @@ -110,6 +110,37 @@ ccl_device_forceinline float microfacet_ggx_glass_E(float mu, float rough, float return lerp(lerp(a, b, rough), lerp(c, d, rough), ior); } +ccl_device_forceinline float microfacet_ggx_dielectric_E(float mu, float rough, float ior) +{ + bool inv_table = (ior < 1.0f); + if (inv_table) { + ior = 1.0f / ior; + } + + rough = saturatef(1 - rough) * 16.0f; + mu = saturatef(mu) * 16.0f; + ior = saturatef(sqrtf(0.5f * (ior - 1.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); + int ior_i = min(15, (int)ior); + int ior_i1 = min(15, ior_i + 1); + + rough -= rough_i; + mu -= mu_i; + ior -= ior_i; + + auto &table = inv_table ? table_ggx_dielectric_inv_E : table_ggx_dielectric_E; + float a = lerp(table[ior_i][rough_i][mu_i], table[ior_i][rough_i][mu_i1], mu); + float b = lerp(table[ior_i][rough_i1][mu_i], table[ior_i][rough_i1][mu_i1], mu); + float c = lerp(table[ior_i1][rough_i][mu_i], table[ior_i1][rough_i][mu_i1], mu); + float d = lerp(table[ior_i1][rough_i1][mu_i], table[ior_i1][rough_i1][mu_i1], mu); + + return lerp(lerp(a, b, rough), lerp(c, d, rough), ior); +} + ccl_device_forceinline float microfacet_ggx_E(float mu, float rough) { rough = saturatef(1 - rough) * 32.0f; diff --git a/intern/cycles/kernel/svm/closure_principled.h b/intern/cycles/kernel/svm/closure_principled.h index c8d6f5211cb..8074646386d 100644 --- a/intern/cycles/kernel/svm/closure_principled.h +++ b/intern/cycles/kernel/svm/closure_principled.h @@ -604,7 +604,7 @@ ccl_device_inline float principled_v2_specular(ccl_private ShaderData *sd, float dielectric = (1.0f - metallic) * (1.0f - transmission); sd->flag |= bsdf_microfacet_ggx_fresnel_v2_setup(bsdf, sd, metallic, dielectric); - return 0.0f; // TODO energy conservation + return microfacet_ggx_dielectric_E(dot(sd->I, N), roughness, ior); } ccl_device void svm_node_closure_principled_v2(KernelGlobals kg, @@ -637,22 +637,22 @@ ccl_device void svm_node_closure_principled_v2(KernelGlobals kg, weight *= 1.0f - principled_v2_clearcoat(kg, sd, stack, weight, path_flag, node_2.w); weight *= 1.0f - principled_v2_sheen(kg, sd, stack, weight, N, node_2.z); - principled_v2_specular(sd, - stack, - weight, - base_color, - roughness, - metallic, - ior, - transmission, - N, - node_2.x, - node_2.y); + float dielectric_albedo = principled_v2_specular(sd, + stack, + weight, + base_color, + roughness, + metallic, + ior, + transmission, + N, + node_2.x, + node_2.y); weight *= 1.0f - metallic; // TODO Glass - weight *= 1.0f - transmission; + weight *= (1.0f - transmission) * (1.0f - dielectric_albedo); principled_v2_diffuse(sd, weight, base_color, 1.0f, N); } diff --git a/intern/cycles/kernel/tables.h b/intern/cycles/kernel/tables.h index 1ba1b7a9f9b..169ef40142a 100644 --- a/intern/cycles/kernel/tables.h +++ b/intern/cycles/kernel/tables.h @@ -720,4 +720,586 @@ static const float table_sheen_E[32][32] = { {0.591225f, 0.045818f, 0.00732363f, 0.00112657f, 0.000170285f, 2.07311e-05f, 2.37514e-06f, 1.86339e-07f, 1.1563e-08f, 7.84983e-10f, 2.46995e-11f, 1.01276e-12f, 2.0924e-14f, 2.83508e-16f, 7.15504e-18f, 2.95273e-20f, 8.42547e-23f, 2.83875e-25f, 9.54702e-28f, 5.32362e-31f, 4.20998e-34f, 1.43471e-37f, 3.92305e-40f, 1.4013e-45f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f} }; +static const float table_ggx_dielectric_E[16][16][16] = { + { + {0.000415471f, 0.000132454f, 6.02304e-05f, 3.2349e-05f, 1.89411e-05f, 1.21628e-05f, 8.25374e-06f, 5.85431e-06f, 4.37281e-06f, 3.34566e-06f, 2.63778e-06f, 2.15633e-06f, 1.80054e-06f, 1.53889e-06f, 1.35031e-06f, 1.20534e-06f}, + {0.000500569f, 0.000167997f, 7.57408e-05f, 4.05907e-05f, 2.42137e-05f, 1.5401e-05f, 1.04112e-05f, 7.33722e-06f, 5.39029e-06f, 4.09224e-06f, 3.22436e-06f, 2.60533e-06f, 2.16446e-06f, 1.84878e-06f, 1.62258e-06f, 1.45125e-06f}, + {0.000631643f, 0.000217958f, 0.000100288f, 5.3289e-05f, 3.109e-05f, 1.96765e-05f, 1.32621e-05f, 9.20107e-06f, 6.70118e-06f, 5.04004e-06f, 3.89982e-06f, 3.12116e-06f, 2.58227e-06f, 2.18829e-06f, 1.91778e-06f, 1.72415e-06f}, + {0.000807995f, 0.000285155f, 0.000131307f, 6.98269e-05f, 4.08318e-05f, 2.54499e-05f, 1.68666e-05f, 1.16319e-05f, 8.38762e-06f, 6.13532e-06f, 4.71284e-06f, 3.71552e-06f, 3.0378e-06f, 2.55783e-06f, 2.22496e-06f, 2.0118e-06f}, + {0.00106589f, 0.00038733f, 0.000176011f, 9.36545e-05f, 5.3984e-05f, 3.35446e-05f, 2.19039e-05f, 1.48318e-05f, 1.03839e-05f, 7.52919e-06f, 5.65876e-06f, 4.39196e-06f, 3.50482e-06f, 2.94163e-06f, 2.53876e-06f, 2.29142e-06f}, + {0.001453f, 0.00053215f, 0.000243545f, 0.000126661f, 7.22715e-05f, 4.4385e-05f, 2.8361e-05f, 1.87374e-05f, 1.29863e-05f, 9.20271e-06f, 6.69805e-06f, 5.08628e-06f, 3.99503e-06f, 3.29186e-06f, 2.82329e-06f, 2.54467e-06f}, + {0.0020343f, 0.000748349f, 0.000339965f, 0.000174612f, 9.84092e-05f, 5.88162e-05f, 3.66575e-05f, 2.38413e-05f, 1.5922e-05f, 1.09605e-05f, 7.79514e-06f, 5.76436e-06f, 4.44091e-06f, 3.59403e-06f, 3.06771e-06f, 2.75371e-06f}, + {0.00300857f, 0.0010926f, 0.000491688f, 0.000246388f, 0.000134689f, 7.80441e-05f, 4.756e-05f, 2.97255e-05f, 1.92082e-05f, 1.28153e-05f, 8.84601e-06f, 6.32998e-06f, 4.78029e-06f, 3.81701e-06f, 3.24172e-06f, 2.92231e-06f}, + {0.00456566f, 0.00165612f, 0.000718974f, 0.000348896f, 0.000183809f, 0.000102446f, 5.97574e-05f, 3.61011e-05f, 2.23647e-05f, 1.44132e-05f, 9.60647e-06f, 6.68339e-06f, 4.95371e-06f, 3.90912e-06f, 3.32515e-06f, 3.0115e-06f}, + {0.00738665f, 0.00259509f, 0.00107763f, 0.000497453f, 0.000248034f, 0.000130573f, 7.24356e-05f, 4.14835e-05f, 2.48774e-05f, 1.54146e-05f, 9.95278e-06f, 6.78691e-06f, 4.96036e-06f, 3.92023e-06f, 3.34373e-06f, 3.06328e-06f}, + {0.0125017f, 0.00419002f, 0.00162011f, 0.000690663f, 0.000319282f, 0.0001576f, 8.20314e-05f, 4.51641e-05f, 2.59064e-05f, 1.55605e-05f, 9.81415e-06f, 6.6463e-06f, 4.8242e-06f, 3.83793e-06f, 3.3166e-06f, 3.07314e-06f}, + {0.0224401f, 0.00691917f, 0.00236534f, 0.000899984f, 0.000378675f, 0.00017348f, 8.60665e-05f, 4.56151e-05f, 2.54936e-05f, 1.5027e-05f, 9.41134e-06f, 6.33024e-06f, 4.63698e-06f, 3.73457e-06 @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs