Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Stockner <lukas.stockner@freenet.de>2022-10-30 01:14:03 +0300
committerLukas Stockner <lukas.stockner@freenet.de>2022-10-30 01:15:16 +0300
commitf4b61c696b740cf173d1ba7decc3f776955cf02b (patch)
tree038db9ab7971250c090896f4be3dff176632d72a
parentbc37e8d8399eef686b71341aa90eced9bc117786 (diff)
Simplify v1 Fresnel computation
-rw-r--r--intern/cycles/app/cycles_precompute.cpp2
-rw-r--r--intern/cycles/kernel/closure/bsdf_microfacet_util.h2
-rw-r--r--intern/cycles/kernel/closure/bsdf_util.h15
3 files changed, 12 insertions, 7 deletions
diff --git a/intern/cycles/app/cycles_precompute.cpp b/intern/cycles/app/cycles_precompute.cpp
index 6f9d9601b1e..b55246e9e91 100644
--- a/intern/cycles/app/cycles_precompute.cpp
+++ b/intern/cycles/app/cycles_precompute.cpp
@@ -213,7 +213,7 @@ static float precompute_ggx_dielectric_E(float rough, float mu, float eta, float
* is an issue since there are changes in that range at higher roughnesses.
* Therefore, the remapping is blended with the identity function for a compromise.
*/
- float F0 = fresnel_dielectric_cos(1.0f, eta);
+ float F0 = fresnel_dielectric_F0(eta);
auto get_remap = [eta, F0](float x) {
return mix(x, inverse_lerp(1.0f, F0, fresnel_dielectric_cos(x, eta)), 0.5f);
};
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet_util.h b/intern/cycles/kernel/closure/bsdf_microfacet_util.h
index b531c192e03..8a0902f054b 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet_util.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet_util.h
@@ -106,7 +106,7 @@ ccl_device_forceinline float microfacet_ggx_dielectric_E(KernelGlobals kg,
kernel_data.tables.ggx_dielectric_E_offset;
float macro_fresnel = fresnel_dielectric_cos(mu, ior);
- float F0 = fresnel_dielectric_cos(1.0f, ior);
+ float F0 = fresnel_dielectric_F0(ior);
float x = mix(mu, inverse_lerp(1.0f, F0, macro_fresnel), 0.5f);
float y = 1 - rough;
float z = sqrtf(0.5f * ((inv_table ? 1.0f / ior : ior) - 1.0f));
diff --git a/intern/cycles/kernel/closure/bsdf_util.h b/intern/cycles/kernel/closure/bsdf_util.h
index 13de4ac15b0..47a37a43c87 100644
--- a/intern/cycles/kernel/closure/bsdf_util.h
+++ b/intern/cycles/kernel/closure/bsdf_util.h
@@ -71,6 +71,13 @@ ccl_device float fresnel_dielectric_cos(float cosi, float eta)
return 1.0f; // TIR(no refracted component)
}
+/* Returns F0 (perpendicular) reflectivity for given eta,
+ * equivalent to fresnel_dielectric_cos(1.0f, eta). */
+ccl_device float fresnel_dielectric_F0(float eta)
+{
+ return sqr((eta - 1.0f) / (eta + 1.0f));
+}
+
ccl_device Spectrum fresnel_conductor(float cosi, const Spectrum eta, const Spectrum k)
{
Spectrum cosi2 = make_spectrum(sqr(cosi));
@@ -124,11 +131,9 @@ ccl_device_forceinline Spectrum interpolate_fresnel_color(Spectrum L,
{
/* Compute the real Fresnel term and remap it from real_F0...1 to F0...1.
* We could also just use actual Schlick fresnel (mix(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;
-
- return mix(F0, one_spectrum(), FH);
+ float real_F0 = fresnel_dielectric_F0(ior);
+ float mixFactor = inverse_lerp(real_F0, 1.0f, fresnel_dielectric_cos(dot(L, H), ior));
+ return mix(F0, one_spectrum(), mixFactor);
}
ccl_device float3 ensure_valid_reflection(float3 Ng, float3 I, float3 N)