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);