From 5f9b518a8bf2f87e8aba19f661d526a3d93d7364 Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Sun, 5 Mar 2023 17:15:26 +0100 Subject: [PATCH] Cycles: Use per-microfacet Fresnel term for Glass closures This commit replaces the current Glass approach, where Glass is a virtual closure that gets replaced with a Glossy and a Refractive closure, with a combined closure that handles Fresnel after sampling the microfacet. That way, the Fresnel term is more accurate since it accounts for the microfacet normal, not the shading normal. Also updates the BSDF sampling to use a 3D sampler now, since we need two dimensions to pick the microfacet normal and then a third dimension to pick reflection/refraction. This can also be used to get rid of the LCG in the Principled Hair BSDF, which means we can remove it altogether once MultiGGX is gone. Also, "sharp" is now supported as a microfacet distribution in OSL, and 2 is supported as the "refract" argument to microfacet() in order to get glass. --- intern/cycles/kernel/CMakeLists.txt | 2 - intern/cycles/kernel/closure/bsdf.h | 207 +++++++------ .../kernel/closure/bsdf_hair_principled.h | 5 +- .../cycles/kernel/closure/bsdf_microfacet.h | 283 ++++++++++++++---- .../kernel/closure/bsdf_microfacet_multi.h | 6 +- .../cycles/kernel/closure/bsdf_reflection.h | 61 ---- .../cycles/kernel/closure/bsdf_refraction.h | 64 ---- intern/cycles/kernel/closure/bsdf_util.h | 11 +- intern/cycles/kernel/integrator/mnee.h | 17 +- .../cycles/kernel/integrator/shade_surface.h | 3 +- .../cycles/kernel/integrator/surface_shader.h | 28 +- intern/cycles/kernel/osl/closures_setup.h | 47 ++- .../kernel/osl/shaders/node_glass_bsdf.osl | 14 +- .../kernel/osl/shaders/node_glossy_bsdf.osl | 12 +- .../osl/shaders/node_refraction_bsdf.osl | 7 +- intern/cycles/kernel/svm/closure.h | 104 ++----- intern/cycles/kernel/svm/types.h | 14 +- intern/cycles/scene/shader_graph.cpp | 3 - intern/cycles/scene/shader_nodes.cpp | 6 +- intern/cycles/util/math.h | 5 + 20 files changed, 444 insertions(+), 455 deletions(-) delete mode 100644 intern/cycles/kernel/closure/bsdf_reflection.h delete mode 100644 intern/cycles/kernel/closure/bsdf_refraction.h diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index 431b520b282..0b643994422 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -113,8 +113,6 @@ set(SRC_KERNEL_CLOSURE_HEADERS closure/bsdf_microfacet_multi_impl.h closure/bsdf_oren_nayar.h closure/bsdf_phong_ramp.h - closure/bsdf_reflection.h - closure/bsdf_refraction.h closure/bsdf_toon.h closure/bsdf_transparent.h closure/bsdf_util.h diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h index 343c7c919c0..42218b0b218 100644 --- a/intern/cycles/kernel/closure/bsdf.h +++ b/intern/cycles/kernel/closure/bsdf.h @@ -11,8 +11,6 @@ #include "kernel/closure/bsdf_diffuse_ramp.h" #include "kernel/closure/bsdf_microfacet.h" #include "kernel/closure/bsdf_microfacet_multi.h" -#include "kernel/closure/bsdf_reflection.h" -#include "kernel/closure/bsdf_refraction.h" #include "kernel/closure/bsdf_transparent.h" #include "kernel/closure/bsdf_ashikhmin_shirley.h" #include "kernel/closure/bsdf_toon.h" @@ -110,8 +108,8 @@ ccl_device_inline bool bsdf_is_transmission(ccl_private const ShaderClosure *sc, ccl_device_inline int bsdf_sample(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private const ShaderClosure *sc, - float randu, - float randv, + const int path_flag, + const float3 rand, ccl_private Spectrum *eval, ccl_private float3 *wo, ccl_private float *pdf, @@ -125,110 +123,160 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg, switch (sc->type) { case CLOSURE_BSDF_DIFFUSE_ID: - label = bsdf_diffuse_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf); + label = bsdf_diffuse_sample(sc, Ng, sd->wi, rand.x, rand.y, eval, wo, pdf); *sampled_roughness = one_float2(); *eta = 1.0f; break; #if defined(__SVM__) || defined(__OSL__) case CLOSURE_BSDF_OREN_NAYAR_ID: - label = bsdf_oren_nayar_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf); + label = bsdf_oren_nayar_sample(sc, Ng, sd->wi, rand.x, rand.y, eval, wo, pdf); *sampled_roughness = one_float2(); *eta = 1.0f; break; # ifdef __OSL__ case CLOSURE_BSDF_PHONG_RAMP_ID: label = bsdf_phong_ramp_sample( - sc, Ng, sd->wi, randu, randv, eval, wo, pdf, sampled_roughness); + sc, Ng, sd->wi, rand.x, rand.y, eval, wo, pdf, sampled_roughness); *eta = 1.0f; break; case CLOSURE_BSDF_DIFFUSE_RAMP_ID: - label = bsdf_diffuse_ramp_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf); + label = bsdf_diffuse_ramp_sample(sc, Ng, sd->wi, rand.x, rand.y, eval, wo, pdf); *sampled_roughness = one_float2(); *eta = 1.0f; break; # endif case CLOSURE_BSDF_TRANSLUCENT_ID: - label = bsdf_translucent_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf); + label = bsdf_translucent_sample(sc, Ng, sd->wi, rand.x, rand.y, eval, wo, pdf); *sampled_roughness = one_float2(); *eta = 1.0f; break; - case CLOSURE_BSDF_REFLECTION_ID: - label = bsdf_reflection_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf, eta); - *sampled_roughness = zero_float2(); - break; - case CLOSURE_BSDF_REFRACTION_ID: - label = bsdf_refraction_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf, eta); - *sampled_roughness = zero_float2(); - break; case CLOSURE_BSDF_TRANSPARENT_ID: - label = bsdf_transparent_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf); + label = bsdf_transparent_sample(sc, Ng, sd->wi, rand.x, rand.y, eval, wo, pdf); *sampled_roughness = zero_float2(); *eta = 1.0f; break; + case CLOSURE_BSDF_REFLECTION_ID: + case CLOSURE_BSDF_REFRACTION_ID: + case CLOSURE_BSDF_SHARP_GLASS_ID: + label = bsdf_microfacet_sharp_sample(sc, + path_flag, + Ng, + sd->wi, + rand.x, + rand.y, + rand.z, + eval, + wo, + pdf, + sampled_roughness, + eta); + break; case CLOSURE_BSDF_MICROFACET_GGX_ID: case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID: case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID: case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: - label = bsdf_microfacet_ggx_sample( - sc, Ng, sd->wi, randu, randv, eval, wo, pdf, sampled_roughness, eta); + case CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID: + label = bsdf_microfacet_ggx_sample(sc, + path_flag, + Ng, + sd->wi, + rand.x, + rand.y, + rand.z, + eval, + wo, + pdf, + sampled_roughness, + eta); break; case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID: case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID: - label = bsdf_microfacet_multi_ggx_sample( - kg, sc, Ng, sd->wi, randu, randv, eval, wo, pdf, &sd->lcg_state, sampled_roughness, eta); + label = bsdf_microfacet_multi_ggx_sample(kg, + sc, + Ng, + sd->wi, + rand.x, + rand.y, + eval, + wo, + pdf, + &sd->lcg_state, + sampled_roughness, + eta); break; case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID: case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID: - label = bsdf_microfacet_multi_ggx_glass_sample( - kg, sc, Ng, sd->wi, randu, randv, eval, wo, pdf, &sd->lcg_state, sampled_roughness, eta); + label = bsdf_microfacet_multi_ggx_glass_sample(kg, + sc, + Ng, + sd->wi, + rand.x, + rand.y, + eval, + wo, + pdf, + &sd->lcg_state, + sampled_roughness, + eta); break; case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: - label = bsdf_microfacet_beckmann_sample( - sc, Ng, sd->wi, randu, randv, eval, wo, pdf, sampled_roughness, eta); + case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID: + label = bsdf_microfacet_beckmann_sample(sc, + path_flag, + Ng, + sd->wi, + rand.x, + rand.y, + rand.z, + eval, + wo, + pdf, + sampled_roughness, + eta); break; case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: label = bsdf_ashikhmin_shirley_sample( - sc, Ng, sd->wi, randu, randv, eval, wo, pdf, sampled_roughness); + sc, Ng, sd->wi, rand.x, rand.y, eval, wo, pdf, sampled_roughness); *eta = 1.0f; break; case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: - label = bsdf_ashikhmin_velvet_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf); + label = bsdf_ashikhmin_velvet_sample(sc, Ng, sd->wi, rand.x, rand.y, eval, wo, pdf); *sampled_roughness = one_float2(); *eta = 1.0f; break; case CLOSURE_BSDF_DIFFUSE_TOON_ID: - label = bsdf_diffuse_toon_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf); + label = bsdf_diffuse_toon_sample(sc, Ng, sd->wi, rand.x, rand.y, eval, wo, pdf); *sampled_roughness = one_float2(); *eta = 1.0f; break; case CLOSURE_BSDF_GLOSSY_TOON_ID: - label = bsdf_glossy_toon_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf); + label = bsdf_glossy_toon_sample(sc, Ng, sd->wi, rand.x, rand.y, eval, wo, pdf); // double check if this is valid *sampled_roughness = one_float2(); *eta = 1.0f; break; case CLOSURE_BSDF_HAIR_REFLECTION_ID: label = bsdf_hair_reflection_sample( - sc, Ng, sd->wi, randu, randv, eval, wo, pdf, sampled_roughness); + sc, Ng, sd->wi, rand.x, rand.y, eval, wo, pdf, sampled_roughness); *eta = 1.0f; break; case CLOSURE_BSDF_HAIR_TRANSMISSION_ID: label = bsdf_hair_transmission_sample( - sc, Ng, sd->wi, randu, randv, eval, wo, pdf, sampled_roughness); + sc, Ng, sd->wi, rand.x, rand.y, eval, wo, pdf, sampled_roughness); *eta = 1.0f; break; case CLOSURE_BSDF_HAIR_PRINCIPLED_ID: label = bsdf_principled_hair_sample( - kg, sc, sd, randu, randv, eval, wo, pdf, sampled_roughness, eta); + kg, sc, sd, rand.x, rand.y, rand.z, eval, wo, pdf, sampled_roughness, eta); break; case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID: - label = bsdf_principled_diffuse_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf); + label = bsdf_principled_diffuse_sample(sc, Ng, sd->wi, rand.x, rand.y, eval, wo, pdf); *sampled_roughness = one_float2(); *eta = 1.0f; break; case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID: - label = bsdf_principled_sheen_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf); + label = bsdf_principled_sheen_sample(sc, Ng, sd->wi, rand.x, rand.y, eval, wo, pdf); *sampled_roughness = one_float2(); *eta = 1.0f; break; @@ -277,7 +325,6 @@ ccl_device_inline void bsdf_roughness_eta(const KernelGlobals kg, ccl_private float *eta) { #ifdef __SVM__ - bool refractive = false; float alpha = 1.0f; #endif switch (sc->type) { @@ -305,40 +352,28 @@ ccl_device_inline void bsdf_roughness_eta(const KernelGlobals kg, *roughness = one_float2(); *eta = 1.0f; break; - case CLOSURE_BSDF_REFLECTION_ID: { - ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; - *roughness = zero_float2(); - *eta = bsdf->ior; - break; - } - case CLOSURE_BSDF_REFRACTION_ID: { - ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; - *roughness = zero_float2(); - // do we need to inverse eta?? - *eta = bsdf->ior; - break; - } case CLOSURE_BSDF_TRANSPARENT_ID: *roughness = zero_float2(); *eta = 1.0f; break; + case CLOSURE_BSDF_REFLECTION_ID: + case CLOSURE_BSDF_REFRACTION_ID: + case CLOSURE_BSDF_SHARP_GLASS_ID: case CLOSURE_BSDF_MICROFACET_GGX_ID: case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID: case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID: - case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: { + case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: + case CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID: + case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: + case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: + case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID: { ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; *roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y); - refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; - *eta = refractive ? 1.0f / bsdf->ior : bsdf->ior; + *eta = CLOSURE_IS_REFRACTIVE(bsdf->type) ? 1.0f / bsdf->ior : bsdf->ior; break; } case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID: - case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID: { - ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; - *roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y); - *eta = bsdf->ior; - break; - } + case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID: case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID: case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID: { ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; @@ -346,13 +381,6 @@ ccl_device_inline void bsdf_roughness_eta(const KernelGlobals kg, *eta = bsdf->ior; break; } - case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: - case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: { - ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; - *roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y); - refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID; - *eta = refractive ? 1.0f / bsdf->ior : bsdf->ior; - } break; case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: { ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; *roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y); @@ -432,38 +460,29 @@ ccl_device_inline int bsdf_label(const KernelGlobals kg, case CLOSURE_BSDF_TRANSLUCENT_ID: label = LABEL_TRANSMIT | LABEL_DIFFUSE; break; - case CLOSURE_BSDF_REFLECTION_ID: - label = LABEL_REFLECT | LABEL_SINGULAR; - break; - case CLOSURE_BSDF_REFRACTION_ID: - label = LABEL_TRANSMIT | LABEL_SINGULAR; - break; case CLOSURE_BSDF_TRANSPARENT_ID: label = LABEL_TRANSMIT | LABEL_TRANSPARENT; break; + case CLOSURE_BSDF_REFLECTION_ID: + case CLOSURE_BSDF_REFRACTION_ID: + case CLOSURE_BSDF_SHARP_GLASS_ID: case CLOSURE_BSDF_MICROFACET_GGX_ID: case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID: case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID: case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID: case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID: - case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: { - ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; - label = (bsdf->alpha_x * bsdf->alpha_y <= 1e-7f) ? LABEL_REFLECT | LABEL_SINGULAR : - LABEL_REFLECT | LABEL_GLOSSY; - break; - } + case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: - case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: { + case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: + case CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID: + case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID: + case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID: + case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID: { ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; - label = (bsdf->alpha_x * bsdf->alpha_y <= 1e-7f) ? LABEL_TRANSMIT | LABEL_SINGULAR : - LABEL_TRANSMIT | LABEL_GLOSSY; + label = ((bsdf_is_transmission(sc, wo)) ? LABEL_TRANSMIT : LABEL_REFLECT) | + ((bsdf->alpha_x * bsdf->alpha_y <= 1e-7f) ? LABEL_SINGULAR : LABEL_GLOSSY); break; } - case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID: - case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID: - label = (bsdf_is_transmission(sc, wo)) ? LABEL_TRANSMIT | LABEL_GLOSSY : - LABEL_REFLECT | LABEL_GLOSSY; - break; case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: label = LABEL_REFLECT | LABEL_GLOSSY; break; @@ -546,19 +565,19 @@ ccl_device_inline case CLOSURE_BSDF_TRANSLUCENT_ID: eval = bsdf_translucent_eval(sc, sd->wi, wo, pdf); break; - case CLOSURE_BSDF_REFLECTION_ID: - eval = bsdf_reflection_eval(sc, sd->wi, wo, pdf); - break; - case CLOSURE_BSDF_REFRACTION_ID: - eval = bsdf_refraction_eval(sc, sd->wi, wo, pdf); - break; case CLOSURE_BSDF_TRANSPARENT_ID: eval = bsdf_transparent_eval(sc, sd->wi, wo, pdf); break; + case CLOSURE_BSDF_REFLECTION_ID: + case CLOSURE_BSDF_REFRACTION_ID: + case CLOSURE_BSDF_SHARP_GLASS_ID: + eval = bsdf_microfacet_sharp_eval(sc, sd->N, sd->wi, wo, pdf); + break; case CLOSURE_BSDF_MICROFACET_GGX_ID: case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID: case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID: case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: + case CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID: eval = bsdf_microfacet_ggx_eval(sc, sd->N, sd->wi, wo, pdf); break; case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID: @@ -571,6 +590,7 @@ ccl_device_inline break; case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: + case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID: eval = bsdf_microfacet_beckmann_eval(sc, sd->N, sd->wi, wo, pdf); break; case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: @@ -643,10 +663,12 @@ ccl_device void bsdf_blur(KernelGlobals kg, ccl_private ShaderClosure *sc, float case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID: case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID: case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: + case CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID: bsdf_microfacet_ggx_blur(sc, roughness); break; case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: + case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID: bsdf_microfacet_beckmann_blur(sc, roughness); break; case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: @@ -678,9 +700,8 @@ ccl_device_inline Spectrum bsdf_albedo(ccl_private const ShaderData *sd, switch (sc->type) { case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID: case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID: - case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID: case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID: - albedo *= microfacet_fresnel((ccl_private const MicrofacetBsdf *)sc, sd->wi, sc->N); + albedo *= microfacet_fresnel((ccl_private const MicrofacetBsdf *)sc, sd->wi, sc->N, false); break; case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID: albedo *= ((ccl_private const PrincipledSheenBsdf *)sc)->avg_value; diff --git a/intern/cycles/kernel/closure/bsdf_hair_principled.h b/intern/cycles/kernel/closure/bsdf_hair_principled.h index ae3362c6cd1..febee4439d9 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_principled.h +++ b/intern/cycles/kernel/closure/bsdf_hair_principled.h @@ -338,6 +338,7 @@ ccl_device int bsdf_principled_hair_sample(KernelGlobals kg, ccl_private ShaderData *sd, float randu, float randv, + float randw, ccl_private Spectrum *eval, ccl_private float3 *wo, ccl_private float *pdf, @@ -359,8 +360,8 @@ ccl_device int bsdf_principled_hair_sample(KernelGlobals kg, float2 u[2]; u[0] = make_float2(randu, randv); - u[1].x = lcg_step_float(&sd->lcg_state); - u[1].y = lcg_step_float(&sd->lcg_state); + u[1].x = randw; + u[1].y = hash_float3_to_float(make_float3(randu, randv, randw)); const float sin_theta_o = local_O.x; const float cos_theta_o = cos_from_sin(sin_theta_o); diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h index d7c3d3651fc..d1f508734ea 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet.h @@ -19,6 +19,7 @@ CCL_NAMESPACE_BEGIN enum MicrofacetType { BECKMANN, GGX, + SHARP, }; typedef struct MicrofacetExtra { @@ -183,14 +184,18 @@ ccl_device_forceinline float3 microfacet_ggx_sample_vndf(const float3 wi, * Else it is simply white */ ccl_device_forceinline Spectrum microfacet_fresnel(ccl_private const MicrofacetBsdf *bsdf, - float3 wi, - float3 H) + const float3 wi, + const float3 H, + const bool refraction) { if (CLOSURE_IS_BSDF_MICROFACET_FRESNEL(bsdf->type)) { + kernel_assert(!refraction); return interpolate_fresnel_color(wi, H, bsdf->ior, bsdf->extra->cspec0); } - else if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) { - return make_spectrum(fresnel_dielectric_cos(dot(wi, H), bsdf->ior)); + else if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID || + CLOSURE_IS_GLASS(bsdf->type)) { + const float F = fresnel_dielectric_cos(dot(wi, H), bsdf->ior); + return make_spectrum(refraction ? 1.0f - F : F); } else { return one_spectrum(); @@ -200,7 +205,7 @@ ccl_device_forceinline Spectrum microfacet_fresnel(ccl_private const MicrofacetB ccl_device_forceinline void bsdf_microfacet_adjust_weight(ccl_private const ShaderData *sd, ccl_private MicrofacetBsdf *bsdf) { - bsdf->sample_weight *= average(microfacet_fresnel(bsdf, sd->wi, bsdf->N)); + bsdf->sample_weight *= average(microfacet_fresnel(bsdf, sd->wi, bsdf->N, false)); } /* Generalized Trowbridge-Reitz for clearcoat. */ @@ -227,8 +232,8 @@ ccl_device_inline float bsdf_lambda_from_sqr_alpha_tan_n(float sqr_alpha_tan_n) return 0.5f * (sqrtf(1.0f + sqr_alpha_tan_n) - 1.0f); } else { - /* m_type == MicrofacetType::BECKMANN - * Approximation from below Equation 69. */ + kernel_assert(m_type == MicrofacetType::BECKMANN); + /* Approximation from below Equation 69. */ if (sqr_alpha_tan_n < 0.39f) { /* Equivalent to a >= 1.6f, but also handles sqr_alpha_tan_n == 0.0f cleanly. */ return 0.0f; @@ -267,7 +272,7 @@ template ccl_device_inline float bsdf_D(float alpha2, flo return expf((1.0f - 1.0f / cos_NH2) / alpha2) / (M_PI_F * alpha2 * sqr(cos_NH2)); } else { - /* m_type == MicrofacetType::GGX */ + kernel_assert(m_type == MicrofacetType::GGX); return alpha2 / (M_PI_F * sqr(1.0f + (alpha2 - 1.0f) * cos_NH2)); } } @@ -284,7 +289,7 @@ ccl_device_inline float bsdf_aniso_D(float alpha_x, float alpha_y, float3 H) return expf(-(sqr(H.x) + sqr(H.y)) / cos_NH2) / (M_PI_F * alpha2 * sqr(cos_NH2)); } else { - /* m_type == MicrofacetType::GGX */ + kernel_assert(m_type == MicrofacetType::GGX); return M_1_PI_F / (alpha2 * sqr(len_squared(H))); } } @@ -296,9 +301,14 @@ ccl_device Spectrum bsdf_microfacet_eval(ccl_private const ShaderClosure *sc, const float3 wo, ccl_private float *pdf) { + if (m_type == MicrofacetType::SHARP) { + *pdf = 0.0f; + return zero_spectrum(); + } + ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; - const bool m_refractive = (bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID) || - (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID); + const bool m_refractive = CLOSURE_IS_REFRACTIVE(bsdf->type); + const bool m_glass = CLOSURE_IS_GLASS(bsdf->type); const float3 N = bsdf->N; const float cos_NI = dot(N, wi); @@ -308,14 +318,23 @@ ccl_device Spectrum bsdf_microfacet_eval(ccl_private const ShaderClosure *sc, const float alpha_x = bsdf->alpha_x; const float alpha_y = bsdf->alpha_y; - if ((cos_NI <= 0) || ((cos_NgO < 0.0f) != m_refractive) || ((cos_NO < 0.0f) != m_refractive) || - (alpha_x * alpha_y <= 1e-7f)) { + const bool is_refraction = (cos_NO < 0.0f); + + /* Check whether the pair of directions is valid for evaluation: + * - Incoming direction has to be in the upper hemisphere (Cycles convention) + * - Specular cases can't be evaluated, only sampled. + * - The outgoing direction has to be the in the same hemisphere w.r.t. both normals. + * - Purely reflective closures can't have refraction. + * - Purely refractive closures can't have reflection. + */ + if ((cos_NI <= 0) || (alpha_x * alpha_y <= 1e-7f) || ((cos_NgO < 0.0f) != is_refraction) || + (is_refraction && !m_refractive) || (!is_refraction && m_refractive && !m_glass)) { *pdf = 0.0f; return zero_spectrum(); } /* Compute half vector. */ - float3 H = m_refractive ? -(bsdf->ior * wo + wi) : (wi + wo); + float3 H = is_refraction ? -(bsdf->ior * wo + wi) : (wi + wo); const float inv_len_H = 1.0f / len(H); H *= inv_len_H; @@ -323,7 +342,7 @@ ccl_device Spectrum bsdf_microfacet_eval(ccl_private const ShaderClosure *sc, float D, lambdaI, lambdaO; /* TODO: add support for anisotropic transmission. */ - if (alpha_x == alpha_y || m_refractive) { /* Isotropic. */ + if (alpha_x == alpha_y || is_refraction) { /* Isotropic. */ float alpha2 = alpha_x * alpha_y; if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) { @@ -354,23 +373,31 @@ ccl_device Spectrum bsdf_microfacet_eval(ccl_private const ShaderClosure *sc, lambdaO = bsdf_aniso_lambda(alpha_x, alpha_y, local_O); } - const float common = D / cos_NI * - (m_refractive ? - sqr(bsdf->ior * inv_len_H) * fabsf(dot(H, wi) * dot(H, wo)) : - 0.25f); + float common = D / cos_NI * + (is_refraction ? sqr(bsdf->ior * inv_len_H) * fabsf(dot(H, wi) * dot(H, wo)) : + 0.25f); - *pdf = common / (1.0f + lambdaI); + float lobe_pdf = 1.0f; + if (m_glass) { + float fresnel = fresnel_dielectric_cos(dot(H, wi), bsdf->ior); + float reflect_pdf = (fresnel == 1.0f) ? 1.0f : clamp(fresnel, 0.125f, 0.875f); + lobe_pdf = is_refraction ? (1.0f - reflect_pdf) : reflect_pdf; + } - const Spectrum F = microfacet_fresnel(bsdf, wo, H); + *pdf = common * lobe_pdf / (1.0f + lambdaI); + + const Spectrum F = microfacet_fresnel(bsdf, wi, H, is_refraction); return F * common / (1.0f + lambdaO + lambdaI); } template ccl_device int bsdf_microfacet_sample(ccl_private const ShaderClosure *sc, + const int path_flag, float3 Ng, float3 wi, float randu, float randv, + float randw, ccl_private Spectrum *eval, ccl_private float3 *wo, ccl_private float *pdf, @@ -380,70 +407,116 @@ ccl_device int bsdf_microfacet_sample(ccl_private const ShaderClosure *sc, ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; const float m_eta = bsdf->ior; - const bool m_refractive = (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID) || - (bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID); - int label = m_refractive ? LABEL_TRANSMIT : LABEL_REFLECT; + const bool m_refractive = CLOSURE_IS_REFRACTIVE(bsdf->type); + const float alpha_x = bsdf->alpha_x; + const float alpha_y = bsdf->alpha_y; + bool m_singular = (m_type == MicrofacetType::SHARP) || (alpha_x * alpha_y <= 1e-7f); const float3 N = bsdf->N; const float cos_NI = dot(N, wi); if (cos_NI <= 0) { - return label | LABEL_GLOSSY; + *eval = zero_spectrum(); + *pdf = 0.0f; + return (m_refractive ? LABEL_TRANSMIT : LABEL_REFLECT) | + (m_singular ? LABEL_SINGULAR : LABEL_GLOSSY); } - float3 X, Y; - const float alpha_x = bsdf->alpha_x; - const float alpha_y = bsdf->alpha_y; - if (alpha_x == alpha_y) { - make_orthonormals(N, &X, &Y); + float3 H; + float cos_NH, cos_HI; + float3 local_H, local_I, X, Y; /* Nneeded for anisotropic microfacets later. */ + if (m_singular) { + H = N; + cos_NH = 1.0f; + cos_HI = cos_NI; } else { - make_orthonormals_tangent(N, bsdf->T, &X, &Y); + if (alpha_x == alpha_y) { + make_orthonormals(N, &X, &Y); + } + else { + make_orthonormals_tangent(N, bsdf->T, &X, &Y); + } + + /* Importance sampling with distribution of visible normals. Vectors are transformed to local + * space before and after sampling. */ + local_I = make_float3(dot(X, wi), dot(Y, wi), cos_NI); + if (m_type == MicrofacetType::GGX) { + local_H = microfacet_ggx_sample_vndf(local_I, alpha_x, alpha_y, randu, randv); + } + else { + /* m_type == MicrofacetType::BECKMANN */ + local_H = microfacet_beckmann_sample_vndf(local_I, alpha_x, alpha_y, randu, randv); + } + + H = X * local_H.x + Y * local_H.y + N * local_H.z; + cos_NH = local_H.z; + cos_HI = dot(H, wi); } - /* Importance sampling with distribution of visible normals. Vectors are transformed to local - * space before and after sampling. */ - const float3 local_I = make_float3(dot(X, wi), dot(Y, wi), cos_NI); - float3 local_H; - if (m_type == MicrofacetType::GGX) { - local_H = microfacet_ggx_sample_vndf(local_I, alpha_x, alpha_y, randu, randv); - } - else { - /* m_type == MicrofacetType::BECKMANN */ - local_H = microfacet_beckmann_sample_vndf(local_I, alpha_x, alpha_y, randu, randv); - } - - const float3 H = X * local_H.x + Y * local_H.y + N * local_H.z; - const float cos_NH = local_H.z; - const float cos_HI = dot(H, wi); - - bool valid = false; + bool valid; + bool do_refract; + float lobe_pdf; if (m_refractive) { - float3 R, T; bool inside; + float fresnel = fresnel_dielectric(m_eta, H, wi, wo, &inside); + valid = !inside; - float fresnel = fresnel_dielectric(m_eta, H, wi, &R, &T, &inside); - *wo = T; + /* For glass closures, we decide between reflection and refraction here. */ + if (CLOSURE_IS_GLASS(bsdf->type)) { + if (fresnel == 1.0f) { + /* TIR, reflection is the only option. */ + do_refract = false; + lobe_pdf = 1.0f; + } + else { + /* Decide between reflection and refraction, using defensive sampling to avoid + * excessive noise for reflection highlights. */ + float reflect_pdf = (path_flag & PATH_RAY_CAMERA) ? clamp(fresnel, 0.125f, 0.875f) : + fresnel; + do_refract = (randw >= reflect_pdf); + lobe_pdf = do_refract ? (1.0f - reflect_pdf) : reflect_pdf; + } + } + else { + /* For pure refractive closures, refraction is the only option. */ + do_refract = true; + lobe_pdf = 1.0f; + valid = valid && (fresnel != 1.0f); + } + } + else { + /* Pure reflective closure, reflection is the only option. */ + valid = true; + lobe_pdf = 1.0f; + do_refract = false; + } - valid = !inside && fresnel != 1.0f; + int label; + if (do_refract) { + /* wo was already set to the refracted direction by fresnel_dielectric. */ + // valid = valid && (dot(Ng, *wo) < 0); + label = LABEL_TRANSMIT; + /* If the IOR is close enough to 1.0, just treat the interaction as specular. */ + m_singular = m_singular || (fabsf(m_eta - 1.0f) < 1e-4f); } else { /* Eq. 39 - compute actual reflected direction */ *wo = 2 * cos_HI * H - wi; - - valid = dot(Ng, *wo) > 0; + valid = valid && (dot(Ng, *wo) > 0); + label = LABEL_REFLECT; } if (!valid) { *eval = zero_spectrum(); *pdf = 0.0f; - return label | LABEL_GLOSSY; + return label | (m_singular ? LABEL_SINGULAR : LABEL_GLOSSY); } - if (alpha_x * alpha_y <= 1e-7f || (m_refractive && fabsf(m_eta - 1.0f) < 1e-4f)) { + if (m_singular) { label |= LABEL_SINGULAR; /* Some high number for MIS. */ - *pdf = 1e6f; - *eval = make_spectrum(1e6f) * microfacet_fresnel(bsdf, *wo, H); + *pdf = lobe_pdf * 1e6f; + *eval = make_spectrum(1e6f) * microfacet_fresnel(bsdf, wi, H, do_refract); } else { label |= LABEL_GLOSSY; @@ -451,7 +524,7 @@ ccl_device int bsdf_microfacet_sample(ccl_private const ShaderClosure *sc, float D, lambdaI, lambdaO; /* TODO: add support for anisotropic transmission. */ - if (alpha_x == alpha_y || m_refractive) { /* Isotropic. */ + if (alpha_x == alpha_y || do_refract) { /* Isotropic. */ float alpha2 = alpha_x * alpha_y; if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) { @@ -479,17 +552,17 @@ ccl_device int bsdf_microfacet_sample(ccl_private const ShaderClosure *sc, const float cos_HO = dot(H, *wo); const float common = D / cos_NI * - (m_refractive ? fabsf(cos_HI * cos_HO) / sqr(cos_HO + cos_HI / m_eta) : - 0.25f); + (do_refract ? fabsf(cos_HI * cos_HO) / sqr(cos_HO + cos_HI / m_eta) : + 0.25f); - *pdf = common / (1.0f + lambdaI); + *pdf = common * lobe_pdf / (1.0f + lambdaI); - Spectrum F = microfacet_fresnel(bsdf, *wo, H); + const Spectrum F = microfacet_fresnel(bsdf, wi, H, do_refract); *eval = F * common / (1.0f + lambdaI + lambdaO); } *sampled_roughness = make_float2(alpha_x, alpha_y); - *eta = m_refractive ? 1.0f / m_eta : m_eta; + *eta = do_refract ? 1.0f / m_eta : m_eta; return label; } @@ -559,6 +632,18 @@ ccl_device int bsdf_microfacet_ggx_refraction_setup(ccl_private MicrofacetBsdf * return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_HAS_TRANSMISSION; } +ccl_device int bsdf_microfacet_ggx_glass_setup(ccl_private MicrofacetBsdf *bsdf) +{ + bsdf->extra = NULL; + + bsdf->alpha_x = saturatef(bsdf->alpha_x); + bsdf->alpha_y = bsdf->alpha_x; + + bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID; + + return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_HAS_TRANSMISSION; +} + ccl_device void bsdf_microfacet_ggx_blur(ccl_private ShaderClosure *sc, float roughness) { ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)sc; @@ -577,10 +662,12 @@ ccl_device Spectrum bsdf_microfacet_ggx_eval(ccl_private const ShaderClosure *sc } ccl_device int bsdf_microfacet_ggx_sample(ccl_private const ShaderClosure *sc, + const int path_flag, float3 Ng, float3 wi, float randu, float randv, + float randw, ccl_private Spectrum *eval, ccl_private float3 *wo, ccl_private float *pdf, @@ -588,7 +675,7 @@ ccl_device int bsdf_microfacet_ggx_sample(ccl_private const ShaderClosure *sc, ccl_private float *eta) { return bsdf_microfacet_sample( - sc, Ng, wi, randu, randv, eval, wo, pdf, sampled_roughness, eta); + sc, path_flag, Ng, wi, randu, randv, randw, eval, wo, pdf, sampled_roughness, eta); } /* Beckmann microfacet with Smith shadow-masking from: @@ -614,6 +701,15 @@ ccl_device int bsdf_microfacet_beckmann_refraction_setup(ccl_private MicrofacetB return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_HAS_TRANSMISSION; } +ccl_device int bsdf_microfacet_beckmann_glass_setup(ccl_private MicrofacetBsdf *bsdf) +{ + bsdf->alpha_x = saturatef(bsdf->alpha_x); + bsdf->alpha_y = bsdf->alpha_x; + + bsdf->type = CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID; + return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_HAS_TRANSMISSION; +} + ccl_device void bsdf_microfacet_beckmann_blur(ccl_private ShaderClosure *sc, float roughness) { ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)sc; @@ -632,10 +728,12 @@ ccl_device Spectrum bsdf_microfacet_beckmann_eval(ccl_private const ShaderClosur } ccl_device int bsdf_microfacet_beckmann_sample(ccl_private const ShaderClosure *sc, + const int path_flag, float3 Ng, float3 wi, float randu, float randv, + float randw, ccl_private Spectrum *eval, ccl_private float3 *wo, ccl_private float *pdf, @@ -643,7 +741,60 @@ ccl_device int bsdf_microfacet_beckmann_sample(ccl_private const ShaderClosure * ccl_private float *eta) { return bsdf_microfacet_sample( - sc, Ng, wi, randu, randv, eval, wo, pdf, sampled_roughness, eta); + sc, path_flag, Ng, wi, randu, randv, randw, eval, wo, pdf, sampled_roughness, eta); +} + +/* Specular interface, not really a microfacet model but close enough that sharing code makes + * sense. */ + +ccl_device int bsdf_reflection_setup(ccl_private MicrofacetBsdf *bsdf) +{ + bsdf->type = CLOSURE_BSDF_REFLECTION_ID; + bsdf->alpha_x = 0.0f; + bsdf->alpha_y = 0.0f; + return SD_BSDF; +} + +ccl_device int bsdf_refraction_setup(ccl_private MicrofacetBsdf *bsdf) +{ + bsdf->type = CLOSURE_BSDF_REFRACTION_ID; + bsdf->alpha_x = 0.0f; + bsdf->alpha_y = 0.0f; + return SD_BSDF | SD_BSDF_HAS_TRANSMISSION; +} + +ccl_device int bsdf_sharp_glass_setup(ccl_private MicrofacetBsdf *bsdf) +{ + bsdf->type = CLOSURE_BSDF_SHARP_GLASS_ID; + bsdf->alpha_x = 0.0f; + bsdf->alpha_y = 0.0f; + return SD_BSDF | SD_BSDF_HAS_TRANSMISSION; +} + +ccl_device Spectrum bsdf_microfacet_sharp_eval(ccl_private const ShaderClosure *sc, + const float3 Ng, + const float3 wi, + const float3 wo, + ccl_private float *pdf) +{ + return bsdf_microfacet_eval(sc, Ng, wi, wo, pdf); +} + +ccl_device int bsdf_microfacet_sharp_sample(ccl_private const ShaderClosure *sc, + const int path_flag, + float3 Ng, + float3 wi, + float randu, + float randv, + float randw, + ccl_private Spectrum *eval, + ccl_private float3 *wo, + ccl_private float *pdf, + ccl_private float2 *sampled_roughness, + ccl_private float *eta) +{ + return bsdf_microfacet_sample( + sc, path_flag, Ng, wi, randu, randv, randw, eval, wo, pdf, sampled_roughness, eta); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h index c2ef383f79f..405d4158f65 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h @@ -640,14 +640,14 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals kg, *sampled_roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y); if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) { - float3 R, T; + float3 T; bool inside; - float fresnel = fresnel_dielectric(bsdf->ior, Z, wi, &R, &T, &inside); + float fresnel = fresnel_dielectric(bsdf->ior, Z, wi, &T, &inside); *pdf = 1e6f; *eval = make_spectrum(1e6f); if (randu < fresnel) { - *wo = R; + *wo = 2 * dot(Z, wi) * Z - wi; return LABEL_REFLECT | LABEL_SINGULAR; } else { diff --git a/intern/cycles/kernel/closure/bsdf_reflection.h b/intern/cycles/kernel/closure/bsdf_reflection.h deleted file mode 100644 index 71ee5f389d2..00000000000 --- a/intern/cycles/kernel/closure/bsdf_reflection.h +++ /dev/null @@ -1,61 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Adapted from Open Shading Language - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011-2022 Blender Foundation. */ - -#pragma once - -CCL_NAMESPACE_BEGIN - -/* REFLECTION */ - -ccl_device int bsdf_reflection_setup(ccl_private MicrofacetBsdf *bsdf) -{ - bsdf->type = CLOSURE_BSDF_REFLECTION_ID; - return SD_BSDF; -} - -ccl_device Spectrum bsdf_reflection_eval(ccl_private const ShaderClosure *sc, - const float3 wi, - const float3 wo, - ccl_private float *pdf) -{ - *pdf = 0.0f; - return zero_spectrum(); -} - -ccl_device int bsdf_reflection_sample(ccl_private const ShaderClosure *sc, - float3 Ng, - float3 wi, - float randu, - float randv, - ccl_private Spectrum *eval, - ccl_private float3 *wo, - ccl_private float *pdf, - ccl_private float *eta) -{ - ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; - float3 N = bsdf->N; - *eta = bsdf->ior; - - // only one direction is possible - float cosNI = dot(N, wi); - if (cosNI > 0) { - *wo = (2 * cosNI) * N - wi; - if (dot(Ng, *wo) > 0) { - /* Some high number for MIS. */ - *pdf = 1e6f; - *eval = make_spectrum(1e6f); - } - } - else { - *pdf = 0.0f; - *eval = zero_spectrum(); - } - return LABEL_REFLECT | LABEL_SINGULAR; -} - -CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/closure/bsdf_refraction.h b/intern/cycles/kernel/closure/bsdf_refraction.h deleted file mode 100644 index f4beff81dd1..00000000000 --- a/intern/cycles/kernel/closure/bsdf_refraction.h +++ /dev/null @@ -1,64 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Adapted from Open Shading Language - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011-2022 Blender Foundation. */ - -#pragma once - -CCL_NAMESPACE_BEGIN - -/* REFRACTION */ - -ccl_device int bsdf_refraction_setup(ccl_private MicrofacetBsdf *bsdf) -{ - bsdf->type = CLOSURE_BSDF_REFRACTION_ID; - return SD_BSDF; -} - -ccl_device Spectrum bsdf_refraction_eval(ccl_private const ShaderClosure *sc, - const float3 wi, - const float3 wo, - ccl_private float *pdf) -{ - *pdf = 0.0f; - return zero_spectrum(); -} - -ccl_device int bsdf_refraction_sample(ccl_private const ShaderClosure *sc, - float3 Ng, - float3 wi, - float randu, - float randv, - ccl_private Spectrum *eval, - ccl_private float3 *wo, - ccl_private float *pdf, - ccl_private float *eta) -{ - ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; - float m_eta = bsdf->ior; - - *eta = 1.0f / m_eta; - float3 N = bsdf->N; - - float3 R, T; - bool inside; - float fresnel; - fresnel = fresnel_dielectric(m_eta, N, wi, &R, &T, &inside); - - if (!inside && fresnel != 1.0f) { - /* Some high number for MIS. */ - *pdf = 1e6f; - *eval = make_spectrum(1e6f); - *wo = T; - } - else { - *pdf = 0.0f; - *eval = zero_spectrum(); - } - return LABEL_TRANSMIT | LABEL_SINGULAR; -} - -CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/closure/bsdf_util.h b/intern/cycles/kernel/closure/bsdf_util.h index ee992375914..68fd61285e3 100644 --- a/intern/cycles/kernel/closure/bsdf_util.h +++ b/intern/cycles/kernel/closure/bsdf_util.h @@ -10,12 +10,8 @@ CCL_NAMESPACE_BEGIN -ccl_device float fresnel_dielectric(float eta, - const float3 N, - const float3 I, - ccl_private float3 *R, - ccl_private float3 *T, - ccl_private bool *is_inside) +ccl_device float fresnel_dielectric( + float eta, const float3 N, const float3 I, ccl_private float3 *T, ccl_private bool *is_inside) { float cos = dot(N, I), neta; float3 Nn; @@ -35,9 +31,6 @@ ccl_device float fresnel_dielectric(float eta, *is_inside = true; } - // compute reflection - *R = (2 * cos) * Nn - I; - float arg = 1 - (neta * neta * (1 - (cos * cos))); if (arg < 0) { *T = make_float3(0.0f, 0.0f, 0.0f); diff --git a/intern/cycles/kernel/integrator/mnee.h b/intern/cycles/kernel/integrator/mnee.h index f50e3bc6e0c..3cb2f1186b8 100644 --- a/intern/cycles/kernel/integrator/mnee.h +++ b/intern/cycles/kernel/integrator/mnee.h @@ -975,20 +975,13 @@ ccl_device_forceinline int kernel_path_mnee_sample(KernelGlobals kg, kg, state, sd_mnee, NULL, PATH_RAY_DIFFUSE, true); /* Get and sample refraction bsdf */ - bool found_transimissive_microfacet_bsdf = false; + bool found_refractive_microfacet_bsdf = false; for (int ci = 0; ci < sd_mnee->num_closure; ci++) { ccl_private ShaderClosure *bsdf = &sd_mnee->closure[ci]; - if (bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID || - bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID || - bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID || - bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID || - bsdf->type == CLOSURE_BSDF_REFRACTION_ID || - bsdf->type == CLOSURE_BSDF_SHARP_GLASS_ID) { - /* Note that CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID and - * CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID are treated as - * CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID further below. */ + if (CLOSURE_IS_REFRACTIVE(bsdf->type)) { + /* Note that Glass closures are treates as refractive further below. */ - found_transimissive_microfacet_bsdf = true; + found_refractive_microfacet_bsdf = true; ccl_private MicrofacetBsdf *microfacet_bsdf = (ccl_private MicrofacetBsdf *)bsdf; /* Figure out appropriate index of refraction ratio. */ @@ -1011,7 +1004,7 @@ ccl_device_forceinline int kernel_path_mnee_sample(KernelGlobals kg, break; } } - if (!found_transimissive_microfacet_bsdf) + if (!found_refractive_microfacet_bsdf) return 0; } diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h index 94b4ddabdf6..97e921795db 100644 --- a/intern/cycles/kernel/integrator/shade_surface.h +++ b/intern/cycles/kernel/integrator/shade_surface.h @@ -348,7 +348,7 @@ ccl_device_forceinline int integrate_surface_bsdf_bssrdf_bounce( return LABEL_NONE; } - float2 rand_bsdf = path_state_rng_2D(kg, rng_state, PRNG_SURFACE_BSDF); + float3 rand_bsdf = path_state_rng_3D(kg, rng_state, PRNG_SURFACE_BSDF); ccl_private const ShaderClosure *sc = surface_shader_bsdf_bssrdf_pick(sd, &rand_bsdf); #ifdef __SUBSURFACE__ @@ -393,6 +393,7 @@ ccl_device_forceinline int integrate_surface_bsdf_bssrdf_bounce( label = surface_shader_bsdf_sample_closure(kg, sd, sc, + INTEGRATOR_STATE(state, path, flag), rand_bsdf, &bsdf_eval, &bsdf_wo, diff --git a/intern/cycles/kernel/integrator/surface_shader.h b/intern/cycles/kernel/integrator/surface_shader.h index 4255b512b94..df8c826e7be 100644 --- a/intern/cycles/kernel/integrator/surface_shader.h +++ b/intern/cycles/kernel/integrator/surface_shader.h @@ -334,7 +334,7 @@ ccl_device_inline /* Randomly sample a BSSRDF or BSDF proportional to ShaderClosure.sample_weight. */ ccl_device_inline ccl_private const ShaderClosure *surface_shader_bsdf_bssrdf_pick( - ccl_private const ShaderData *ccl_restrict sd, ccl_private float2 *rand_bsdf) + ccl_private const ShaderData *ccl_restrict sd, ccl_private float3 *rand_bsdf) { int sampled = 0; @@ -350,7 +350,7 @@ ccl_device_inline ccl_private const ShaderClosure *surface_shader_bsdf_bssrdf_pi } } - float r = (*rand_bsdf).x * sum; + float r = (*rand_bsdf).z * sum; float partial_sum = 0.0f; for (int i = 0; i < sd->num_closure; i++) { @@ -363,7 +363,7 @@ ccl_device_inline ccl_private const ShaderClosure *surface_shader_bsdf_bssrdf_pi sampled = i; /* Rescale to reuse for direction sample, to better preserve stratification. */ - (*rand_bsdf).x = (r - partial_sum) / sc->sample_weight; + (*rand_bsdf).z = (r - partial_sum) / sc->sample_weight; break; } @@ -405,7 +405,7 @@ ccl_device int surface_shader_bsdf_guided_sample_closure(KernelGlobals kg, IntegratorState state, ccl_private ShaderData *sd, ccl_private const ShaderClosure *sc, - const float2 rand_bsdf, + const float3 rand_bsdf, ccl_private BsdfEval *bsdf_eval, ccl_private float3 *wo, ccl_private float *bsdf_pdf, @@ -443,7 +443,7 @@ ccl_device int surface_shader_bsdf_guided_sample_closure(KernelGlobals kg, if (sample_guiding) { /* Sample guiding distribution. */ - guide_pdf = guiding_bsdf_sample(kg, state, rand_bsdf, wo); + guide_pdf = guiding_bsdf_sample(kg, state, float3_to_float2(rand_bsdf), wo); *bsdf_pdf = 0.0f; if (guide_pdf != 0.0f) { @@ -483,8 +483,16 @@ ccl_device int surface_shader_bsdf_guided_sample_closure(KernelGlobals kg, else { /* Sample BSDF. */ *bsdf_pdf = 0.0f; - label = bsdf_sample( - kg, sd, sc, rand_bsdf.x, rand_bsdf.y, &eval, wo, unguided_bsdf_pdf, sampled_rougness, eta); + label = bsdf_sample(kg, + sd, + sc, + INTEGRATOR_STATE(state, path, flag), + rand_bsdf, + &eval, + wo, + unguided_bsdf_pdf, + sampled_rougness, + eta); # if 0 if (*unguided_bsdf_pdf > 0.0f) { surface_shader_validate_bsdf_sample(kg, sc, *wo, label, sampled_roughness, eta); @@ -523,7 +531,8 @@ ccl_device int surface_shader_bsdf_guided_sample_closure(KernelGlobals kg, ccl_device int surface_shader_bsdf_sample_closure(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private const ShaderClosure *sc, - const float2 rand_bsdf, + const int path_flag, + const float3 rand_bsdf, ccl_private BsdfEval *bsdf_eval, ccl_private float3 *wo, ccl_private float *pdf, @@ -537,8 +546,7 @@ ccl_device int surface_shader_bsdf_sample_closure(KernelGlobals kg, Spectrum eval = zero_spectrum(); *pdf = 0.0f; - label = bsdf_sample( - kg, sd, sc, rand_bsdf.x, rand_bsdf.y, &eval, wo, pdf, sampled_roughness, eta); + label = bsdf_sample(kg, sd, sc, path_flag, rand_bsdf, &eval, wo, pdf, sampled_roughness, eta); if (*pdf != 0.0f) { bsdf_eval_init(bsdf_eval, sc->type, eval * sc->weight); diff --git a/intern/cycles/kernel/osl/closures_setup.h b/intern/cycles/kernel/osl/closures_setup.h index 5ea8f080410..6e001f4a8f1 100644 --- a/intern/cycles/kernel/osl/closures_setup.h +++ b/intern/cycles/kernel/osl/closures_setup.h @@ -16,8 +16,6 @@ #include "kernel/closure/bsdf_microfacet.h" #include "kernel/closure/bsdf_microfacet_multi.h" #include "kernel/closure/bsdf_oren_nayar.h" -#include "kernel/closure/bsdf_reflection.h" -#include "kernel/closure/bsdf_refraction.h" #include "kernel/closure/bsdf_transparent.h" #include "kernel/closure/bsdf_ashikhmin_shirley.h" #include "kernel/closure/bsdf_toon.h" @@ -205,23 +203,44 @@ ccl_device void osl_closure_microfacet_setup(KernelGlobals kg, bsdf->ior = closure->ior; bsdf->T = closure->T; - /* GGX */ - if (closure->distribution == make_string("ggx", 11253504724482777663ull) || - closure->distribution == make_string("default", 4430693559278735917ull)) { - if (!closure->refract) { - sd->flag |= bsdf_microfacet_ggx_setup(bsdf); + /* Beckmann */ + if (closure->distribution == make_string("beckmann", 14712237670914973463ull)) { + if (closure->refract == 1) { + sd->flag |= bsdf_microfacet_beckmann_refraction_setup(bsdf); + } + else if (closure->refract == 2) { + sd->flag |= bsdf_microfacet_beckmann_glass_setup(bsdf); } else { - sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf); - } - } - /* Beckmann */ - else { - if (!closure->refract) { sd->flag |= bsdf_microfacet_beckmann_setup(bsdf); } + } + /* Sharp */ + else if (closure->distribution == make_string("sharp", 1870681295563127462ull)) { + if (closure->refract == 1) { + sd->flag |= bsdf_refraction_setup(bsdf); + } + else if (closure->refract == 2) { + sd->flag |= bsdf_sharp_glass_setup(bsdf); + } else { - sd->flag |= bsdf_microfacet_beckmann_refraction_setup(bsdf); + sd->flag |= bsdf_reflection_setup(bsdf); + } + } + /* Ashikhmin-Shirley */ + else if (closure->distribution == make_string("ashikhmin_shirley", 11318482998918370922ull)) { + sd->flag |= bsdf_ashikhmin_shirley_setup(bsdf); + } + /* GGX */ + else { + if (closure->refract == 1) { + sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf); + } + else if (closure->refract == 2) { + sd->flag |= bsdf_microfacet_ggx_glass_setup(bsdf); + } + else { + sd->flag |= bsdf_microfacet_ggx_setup(bsdf); } } } diff --git a/intern/cycles/kernel/osl/shaders/node_glass_bsdf.osl b/intern/cycles/kernel/osl/shaders/node_glass_bsdf.osl index 56ae180d276..9d14e08fa80 100644 --- a/intern/cycles/kernel/osl/shaders/node_glass_bsdf.osl +++ b/intern/cycles/kernel/osl/shaders/node_glass_bsdf.osl @@ -13,18 +13,10 @@ shader node_glass_bsdf(color Color = 0.8, { float f = max(IOR, 1e-5); float eta = backfacing() ? 1.0 / f : f; - float cosi = dot(I, Normal); - float Fr = fresnel_dielectric_cos(cosi, eta); float roughness = Roughness * Roughness; - if (distribution == "sharp") - BSDF = Color * (Fr * reflection(Normal) + (1.0 - Fr) * refraction(Normal, eta)); - else if (distribution == "beckmann") - BSDF = Color * (Fr * microfacet_beckmann(Normal, roughness) + - (1.0 - Fr) * microfacet_beckmann_refraction(Normal, roughness, eta)); - else if (distribution == "Multiscatter GGX") + if (distribution == "Multiscatter GGX") BSDF = Color * microfacet_multi_ggx_glass(Normal, roughness, eta, Color); - else if (distribution == "GGX") - BSDF = Color * (Fr * microfacet_ggx(Normal, roughness) + - (1.0 - Fr) * microfacet_ggx_refraction(Normal, roughness, eta)); + else + BSDF = Color * microfacet(distribution, Normal, roughness, eta, 2); } diff --git a/intern/cycles/kernel/osl/shaders/node_glossy_bsdf.osl b/intern/cycles/kernel/osl/shaders/node_glossy_bsdf.osl index 93a8ba16d8a..7850f0087bd 100644 --- a/intern/cycles/kernel/osl/shaders/node_glossy_bsdf.osl +++ b/intern/cycles/kernel/osl/shaders/node_glossy_bsdf.osl @@ -5,21 +5,15 @@ #include "stdcycles.h" shader node_glossy_bsdf(color Color = 0.8, - string distribution = "GGX", + string distribution = "ggx", float Roughness = 0.2, normal Normal = N, output closure color BSDF = 0) { float roughness = Roughness * Roughness; - if (distribution == "sharp") - BSDF = Color * reflection(Normal); - else if (distribution == "beckmann") - BSDF = Color * microfacet_beckmann(Normal, roughness); - else if (distribution == "GGX") - BSDF = Color * microfacet_ggx(Normal, roughness); - else if (distribution == "Multiscatter GGX") + if (distribution == "Multiscatter GGX") BSDF = Color * microfacet_multi_ggx(Normal, roughness, Color); else - BSDF = Color * ashikhmin_shirley(Normal, vector(0, 0, 0), roughness, roughness); + BSDF = Color * microfacet(distribution, Normal, roughness, 0.0, 0); } diff --git a/intern/cycles/kernel/osl/shaders/node_refraction_bsdf.osl b/intern/cycles/kernel/osl/shaders/node_refraction_bsdf.osl index d992821d3fe..a356356f5a0 100644 --- a/intern/cycles/kernel/osl/shaders/node_refraction_bsdf.osl +++ b/intern/cycles/kernel/osl/shaders/node_refraction_bsdf.osl @@ -14,10 +14,5 @@ shader node_refraction_bsdf(color Color = 0.8, float eta = backfacing() ? 1.0 / f : f; float roughness = Roughness * Roughness; - if (distribution == "sharp") - BSDF = Color * refraction(Normal, eta); - else if (distribution == "beckmann") - BSDF = Color * microfacet_beckmann_refraction(Normal, roughness, eta); - else if (distribution == "GGX") - BSDF = Color * microfacet_ggx_refraction(Normal, roughness, eta); + BSDF = microfacet(distribution, Normal, roughness, eta, 1); } diff --git a/intern/cycles/kernel/svm/closure.h b/intern/cycles/kernel/svm/closure.h index f52e13e37d8..5db671a8317 100644 --- a/intern/cycles/kernel/svm/closure.h +++ b/intern/cycles/kernel/svm/closure.h @@ -14,49 +14,6 @@ CCL_NAMESPACE_BEGIN /* Closure Nodes */ -ccl_device void svm_node_glass_setup(ccl_private ShaderData *sd, - ccl_private MicrofacetBsdf *bsdf, - int type, - float eta, - float roughness, - bool refract) -{ - if (type == CLOSURE_BSDF_SHARP_GLASS_ID) { - if (refract) { - bsdf->alpha_y = 0.0f; - bsdf->alpha_x = 0.0f; - bsdf->ior = eta; - sd->flag |= bsdf_refraction_setup(bsdf); - } - else { - bsdf->alpha_y = 0.0f; - bsdf->alpha_x = 0.0f; - bsdf->ior = eta; - sd->flag |= bsdf_reflection_setup(bsdf); - } - } - else if (type == CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID) { - bsdf->alpha_x = roughness; - bsdf->alpha_y = roughness; - bsdf->ior = eta; - - if (refract) - sd->flag |= bsdf_microfacet_beckmann_refraction_setup(bsdf); - else - sd->flag |= bsdf_microfacet_beckmann_setup(bsdf); - } - else { - bsdf->alpha_x = roughness; - bsdf->alpha_y = roughness; - bsdf->ior = eta; - - if (refract) - sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf); - else - sd->flag |= bsdf_microfacet_ggx_setup(bsdf); - } -} - ccl_device_inline int svm_node_closure_bsdf_skip(KernelGlobals kg, int offset, uint type) { if (type == CLOSURE_BSDF_PRINCIPLED_ID) { @@ -627,52 +584,39 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID: { #ifdef __CAUSTICS_TRICKS__ if (!kernel_data.integrator.caustics_reflective && - !kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE)) { + !kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE)) break; - } #endif Spectrum weight = sd->svm_closure_weight * mix_weight; + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), weight); - /* index of refraction */ - float eta = fmaxf(param2, 1e-5f); - eta = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta; + if (bsdf) { + bsdf->N = N; + bsdf->T = zero_float3(); + bsdf->extra = NULL; - /* fresnel */ - float cosNI = dot(N, sd->wi); - float fresnel = fresnel_dielectric_cos(cosNI, eta); - float roughness = sqr(param1); + float eta = fmaxf(param2, 1e-5f); + eta = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta; - /* reflection */ -#ifdef __CAUSTICS_TRICKS__ - if (kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) -#endif - { - ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( - sd, sizeof(MicrofacetBsdf), weight * fresnel); + /* setup bsdf */ + if (type == CLOSURE_BSDF_SHARP_GLASS_ID) { + bsdf->alpha_x = 0.0f; + bsdf->alpha_y = 0.0f; + bsdf->ior = eta; - if (bsdf) { - bsdf->N = N; - bsdf->T = zero_float3(); - bsdf->extra = NULL; - svm_node_glass_setup(sd, bsdf, type, eta, roughness, false); + sd->flag |= bsdf_sharp_glass_setup(bsdf); } - } + else { + float roughness = sqr(param1); + bsdf->alpha_x = roughness; + bsdf->alpha_y = roughness; + bsdf->ior = eta; - /* refraction */ -#ifdef __CAUSTICS_TRICKS__ - if (kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0) -#endif - { - /* This is to prevent MNEE from receiving a null BSDF. */ - float refraction_fresnel = fmaxf(0.0001f, 1.0f - fresnel); - ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( - sd, sizeof(MicrofacetBsdf), weight * refraction_fresnel); - - if (bsdf) { - bsdf->N = N; - bsdf->T = zero_float3(); - bsdf->extra = NULL; - svm_node_glass_setup(sd, bsdf, type, eta, roughness, true); + if (type == CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID) + sd->flag |= bsdf_microfacet_beckmann_glass_setup(bsdf); + else + sd->flag |= bsdf_microfacet_ggx_glass_setup(bsdf); } } diff --git a/intern/cycles/kernel/svm/types.h b/intern/cycles/kernel/svm/types.h index 12c5a17072b..54a5fce8975 100644 --- a/intern/cycles/kernel/svm/types.h +++ b/intern/cycles/kernel/svm/types.h @@ -436,11 +436,11 @@ typedef enum ClosureType { CLOSURE_BSDF_REFRACTION_ID, CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID, CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID, - CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID, + CLOSURE_BSDF_SHARP_GLASS_ID, CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID, CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID, + CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID, CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID, - CLOSURE_BSDF_SHARP_GLASS_ID, CLOSURE_BSDF_HAIR_PRINCIPLED_ID, CLOSURE_BSDF_HAIR_TRANSMISSION_ID, @@ -484,11 +484,9 @@ typedef enum ClosureType { #define CLOSURE_IS_BSDF_MICROFACET(type) \ ((type >= CLOSURE_BSDF_MICROFACET_GGX_ID && type <= CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID) || \ (type >= CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID && \ - type <= CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID) || \ - (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID)) + type <= CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID)) #define CLOSURE_IS_BSDF_MICROFACET_FRESNEL(type) \ (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID || \ - type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID || \ type == CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID) #define CLOSURE_IS_BSDF_OR_BSSRDF(type) (type <= CLOSURE_BSSRDF_RANDOM_WALK_FIXED_RADIUS_ID) #define CLOSURE_IS_BSSRDF(type) \ @@ -499,8 +497,12 @@ typedef enum ClosureType { #define CLOSURE_IS_VOLUME_ABSORPTION(type) (type == CLOSURE_VOLUME_ABSORPTION_ID) #define CLOSURE_IS_HOLDOUT(type) (type == CLOSURE_HOLDOUT_ID) #define CLOSURE_IS_PHASE(type) (type == CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID) +#define CLOSURE_IS_REFRACTIVE(type) \ + (type >= CLOSURE_BSDF_REFRACTION_ID && \ + type <= CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID) #define CLOSURE_IS_GLASS(type) \ - (type >= CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID && type <= CLOSURE_BSDF_SHARP_GLASS_ID) + (type >= CLOSURE_BSDF_SHARP_GLASS_ID && \ + type <= CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID) #define CLOSURE_IS_PRINCIPLED(type) (type == CLOSURE_BSDF_PRINCIPLED_ID) #define CLOSURE_WEIGHT_CUTOFF 1e-5f diff --git a/intern/cycles/scene/shader_graph.cpp b/intern/cycles/scene/shader_graph.cpp index ef3f142ed4e..b9e8892765b 100644 --- a/intern/cycles/scene/shader_graph.cpp +++ b/intern/cycles/scene/shader_graph.cpp @@ -1126,9 +1126,6 @@ int ShaderGraph::get_num_closures() else if (CLOSURE_IS_BSSRDF(closure_type)) { num_closures += 3; } - else if (CLOSURE_IS_GLASS(closure_type)) { - num_closures += 2; - } else if (CLOSURE_IS_BSDF_MULTISCATTER(closure_type)) { num_closures += 2; } diff --git a/intern/cycles/scene/shader_nodes.cpp b/intern/cycles/scene/shader_nodes.cpp index 1b7d66eeff1..7d1cb4aeec1 100644 --- a/intern/cycles/scene/shader_nodes.cpp +++ b/intern/cycles/scene/shader_nodes.cpp @@ -2417,7 +2417,7 @@ NODE_DEFINE(GlossyBsdfNode) static NodeEnum distribution_enum; distribution_enum.insert("sharp", CLOSURE_BSDF_REFLECTION_ID); distribution_enum.insert("beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_ID); - distribution_enum.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_ID); + distribution_enum.insert("ggx", CLOSURE_BSDF_MICROFACET_GGX_ID); distribution_enum.insert("ashikhmin_shirley", CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID); distribution_enum.insert("Multiscatter GGX", CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID); SOCKET_ENUM(distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_GGX_ID); @@ -2509,7 +2509,7 @@ NODE_DEFINE(GlassBsdfNode) static NodeEnum distribution_enum; distribution_enum.insert("sharp", CLOSURE_BSDF_SHARP_GLASS_ID); distribution_enum.insert("beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID); - distribution_enum.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID); + distribution_enum.insert("ggx", CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID); distribution_enum.insert("Multiscatter GGX", CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID); SOCKET_ENUM( distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID); @@ -2602,7 +2602,7 @@ NODE_DEFINE(RefractionBsdfNode) static NodeEnum distribution_enum; distribution_enum.insert("sharp", CLOSURE_BSDF_REFRACTION_ID); distribution_enum.insert("beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID); - distribution_enum.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID); + distribution_enum.insert("ggx", CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID); SOCKET_ENUM( distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID); diff --git a/intern/cycles/util/math.h b/intern/cycles/util/math.h index df75e7bf2b5..f323d0eeb0e 100644 --- a/intern/cycles/util/math.h +++ b/intern/cycles/util/math.h @@ -503,6 +503,11 @@ ccl_device_inline float3 float2_to_float3(const float2 a) return make_float3(a.x, a.y, 0.0f); } +ccl_device_inline float2 float3_to_float2(const float3 a) +{ + return make_float2(a.x, a.y); +} + ccl_device_inline float3 float4_to_float3(const float4 a) { return make_float3(a.x, a.y, a.z);