From bd249eb4f37e65b2f4b3deef775bb136a2c234d1 Mon Sep 17 00:00:00 2001 From: Sebastian Herhoz Date: Wed, 21 Sep 2022 17:46:10 +0200 Subject: Cycles: BSDF changes in preparation of path guiding * Return roughness and IOR for BSDF sampling * Add functions to query IOR and label for given BSDF * Default IOR to 1.0 instead of 0.0 for BSDFs that don't use it * Ensure pdf >= 0.0 in case of numerical precision issues Ref T92571, D15286 --- intern/cycles/kernel/closure/bsdf.h | 323 ++++++++++++++++++++- .../cycles/kernel/closure/bsdf_ashikhmin_shirley.h | 4 +- intern/cycles/kernel/closure/bsdf_hair.h | 8 +- .../cycles/kernel/closure/bsdf_hair_principled.h | 7 +- intern/cycles/kernel/closure/bsdf_microfacet.h | 15 +- .../cycles/kernel/closure/bsdf_microfacet_multi.h | 24 +- intern/cycles/kernel/closure/bsdf_phong_ramp.h | 10 +- intern/cycles/kernel/closure/bsdf_reflection.h | 4 +- intern/cycles/kernel/closure/bsdf_refraction.h | 5 +- intern/cycles/kernel/integrator/shade_surface.h | 14 +- intern/cycles/kernel/integrator/surface_shader.h | 7 +- intern/cycles/kernel/osl/closures_setup.h | 4 +- intern/cycles/kernel/svm/closure.h | 4 +- 13 files changed, 396 insertions(+), 33 deletions(-) (limited to 'intern') diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h index f0b28ff77c4..d202018be9a 100644 --- a/intern/cycles/kernel/closure/bsdf.h +++ b/intern/cycles/kernel/closure/bsdf.h @@ -105,7 +105,9 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg, float randv, ccl_private Spectrum *eval, ccl_private float3 *omega_in, - ccl_private float *pdf) + ccl_private float *pdf, + ccl_private float2 *sampled_roughness, + ccl_private float *eta) { /* For curves use the smooth normal, particularly for ribbons the geometric * normal gives too much darkening otherwise. */ @@ -115,78 +117,131 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg, switch (sc->type) { case CLOSURE_BSDF_DIFFUSE_ID: label = bsdf_diffuse_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, 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->I, randu, randv, eval, omega_in, 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->I, randu, randv, eval, omega_in, pdf); + label = bsdf_phong_ramp_sample( + sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness); + *eta = 1.0f; break; case CLOSURE_BSDF_DIFFUSE_RAMP_ID: label = bsdf_diffuse_ramp_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); + *sampled_roughness = one_float2(); + *eta = 1.0f; break; # endif case CLOSURE_BSDF_TRANSLUCENT_ID: label = bsdf_translucent_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); + *sampled_roughness = one_float2(); + *eta = 1.0f; break; case CLOSURE_BSDF_REFLECTION_ID: - label = bsdf_reflection_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); + label = bsdf_reflection_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, eta); + *sampled_roughness = zero_float2(); break; case CLOSURE_BSDF_REFRACTION_ID: - label = bsdf_refraction_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); + label = bsdf_refraction_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, eta); + *sampled_roughness = zero_float2(); break; case CLOSURE_BSDF_TRANSPARENT_ID: label = bsdf_transparent_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); + *sampled_roughness = zero_float2(); + *eta = 1.0f; 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(kg, sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); + label = bsdf_microfacet_ggx_sample( + kg, sc, Ng, sd->I, randu, randv, eval, omega_in, 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->I, randu, randv, eval, omega_in, pdf, &sd->lcg_state); + label = bsdf_microfacet_multi_ggx_sample(kg, + sc, + Ng, + sd->I, + randu, + randv, + eval, + omega_in, + 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->I, randu, randv, eval, omega_in, pdf, &sd->lcg_state); + label = bsdf_microfacet_multi_ggx_glass_sample(kg, + sc, + Ng, + sd->I, + randu, + randv, + eval, + omega_in, + 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( - kg, sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); + kg, sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness, eta); break; case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: - label = bsdf_ashikhmin_shirley_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); + label = bsdf_ashikhmin_shirley_sample( + sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness); + *eta = 1.0f; break; case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: label = bsdf_ashikhmin_velvet_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); + *sampled_roughness = one_float2(); + *eta = 1.0f; break; case CLOSURE_BSDF_DIFFUSE_TOON_ID: label = bsdf_diffuse_toon_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); + *sampled_roughness = one_float2(); + *eta = 1.0f; break; case CLOSURE_BSDF_GLOSSY_TOON_ID: label = bsdf_glossy_toon_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, 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->I, randu, randv, eval, omega_in, pdf); + label = bsdf_hair_reflection_sample( + sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness); + *eta = 1.0f; break; case CLOSURE_BSDF_HAIR_TRANSMISSION_ID: - label = bsdf_hair_transmission_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); + label = bsdf_hair_transmission_sample( + sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness); + *eta = 1.0f; break; case CLOSURE_BSDF_HAIR_PRINCIPLED_ID: - label = bsdf_principled_hair_sample(kg, sc, sd, randu, randv, eval, omega_in, pdf); + label = bsdf_principled_hair_sample( + kg, sc, sd, randu, randv, eval, omega_in, pdf, sampled_roughness, eta); break; case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID: label = bsdf_principled_diffuse_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); + *sampled_roughness = one_float2(); + *eta = 1.0f; break; case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID: label = bsdf_principled_sheen_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); + *sampled_roughness = one_float2(); + *eta = 1.0f; break; #endif default: @@ -226,6 +281,246 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg, return label; } +ccl_device_inline void bsdf_roughness_eta(const KernelGlobals kg, + ccl_private const ShaderClosure *sc, + ccl_private float2 *roughness, + ccl_private float *eta) +{ + bool refractive = false; + float alpha = 1.0f; + switch (sc->type) { + case CLOSURE_BSDF_DIFFUSE_ID: + *roughness = one_float2(); + *eta = 1.0f; + break; +#ifdef __SVM__ + case CLOSURE_BSDF_OREN_NAYAR_ID: + *roughness = one_float2(); + *eta = 1.0f; + break; +# ifdef __OSL__ + case CLOSURE_BSDF_PHONG_RAMP_ID: + alpha = phong_ramp_exponent_to_roughness(((ccl_private const PhongRampBsdf *)sc)->exponent); + *roughness = make_float2(alpha, alpha); + *eta = 1.0f; + break; + case CLOSURE_BSDF_DIFFUSE_RAMP_ID: + *roughness = one_float2(); + *eta = 1.0f; + break; +# endif + case CLOSURE_BSDF_TRANSLUCENT_ID: + *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_MICROFACET_GGX_ID: + case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID: + case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID: + case CLOSURE_BSDF_MICROFACET_GGX_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_GGX_REFRACTION_ID; + *eta = refractive ? 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_GLASS_ID: + case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_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_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); + *eta = 1.0f; + break; + } + case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: + *roughness = one_float2(); + *eta = 1.0f; + break; + case CLOSURE_BSDF_DIFFUSE_TOON_ID: + *roughness = one_float2(); + *eta = 1.0f; + break; + case CLOSURE_BSDF_GLOSSY_TOON_ID: + // double check if this is valid + *roughness = one_float2(); + *eta = 1.0f; + break; + case CLOSURE_BSDF_HAIR_REFLECTION_ID: + *roughness = make_float2(((ccl_private HairBsdf *)sc)->roughness1, + ((ccl_private HairBsdf *)sc)->roughness2); + *eta = 1.0f; + break; + case CLOSURE_BSDF_HAIR_TRANSMISSION_ID: + *roughness = make_float2(((ccl_private HairBsdf *)sc)->roughness1, + ((ccl_private HairBsdf *)sc)->roughness2); + *eta = 1.0f; + break; + case CLOSURE_BSDF_HAIR_PRINCIPLED_ID: + alpha = ((ccl_private PrincipledHairBSDF *)sc)->m0_roughness; + *roughness = make_float2(alpha, alpha); + *eta = ((ccl_private PrincipledHairBSDF *)sc)->eta; + break; + case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID: + *roughness = one_float2(); + *eta = 1.0f; + break; + case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID: + *roughness = one_float2(); + *eta = 1.0f; + break; +#endif + default: + *roughness = one_float2(); + *eta = 1.0f; + break; + } +} + +ccl_device_inline int bsdf_label(const KernelGlobals kg, + ccl_private const ShaderClosure *sc, + const float3 omega_in) +{ + /* For curves use the smooth normal, particularly for ribbons the geometric + * normal gives too much darkening otherwise. */ + int label; + switch (sc->type) { + case CLOSURE_BSDF_DIFFUSE_ID: + case CLOSURE_BSSRDF_BURLEY_ID: + case CLOSURE_BSSRDF_RANDOM_WALK_ID: + case CLOSURE_BSSRDF_RANDOM_WALK_FIXED_RADIUS_ID: + label = LABEL_REFLECT | LABEL_DIFFUSE; + break; +#ifdef __SVM__ + case CLOSURE_BSDF_OREN_NAYAR_ID: + label = LABEL_REFLECT | LABEL_DIFFUSE; + break; +# ifdef __OSL__ + case CLOSURE_BSDF_PHONG_RAMP_ID: + label = LABEL_REFLECT | LABEL_GLOSSY; + break; + case CLOSURE_BSDF_DIFFUSE_RAMP_ID: + label = LABEL_REFLECT | LABEL_DIFFUSE; + break; +# endif + 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_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_GGX_REFRACTION_ID: + case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_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; + break; + } + case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID: + case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID: + label = (bsdf_is_transmission(sc, omega_in)) ? LABEL_TRANSMIT | LABEL_GLOSSY : + LABEL_REFLECT | LABEL_GLOSSY; + break; + case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: + label = LABEL_REFLECT | LABEL_GLOSSY; + break; + case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: + label = LABEL_REFLECT | LABEL_DIFFUSE; + break; + case CLOSURE_BSDF_DIFFUSE_TOON_ID: + label = LABEL_REFLECT | LABEL_DIFFUSE; + break; + case CLOSURE_BSDF_GLOSSY_TOON_ID: + label = LABEL_REFLECT | LABEL_GLOSSY; + break; + case CLOSURE_BSDF_HAIR_REFLECTION_ID: + label = LABEL_REFLECT | LABEL_GLOSSY; + break; + case CLOSURE_BSDF_HAIR_TRANSMISSION_ID: + label = LABEL_TRANSMIT | LABEL_GLOSSY; + break; + case CLOSURE_BSDF_HAIR_PRINCIPLED_ID: + if (is_transmission) + label = LABEL_TRANSMIT | LABEL_GLOSSY; + else + label = LABEL_REFLECT | LABEL_GLOSSY; + break; + case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID: + label = LABEL_REFLECT | LABEL_DIFFUSE; + break; + case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID: + label = LABEL_REFLECT | LABEL_DIFFUSE; + break; +#endif + default: + label = LABEL_NONE; + break; + } + + /* Test if BSDF sample should be treated as transparent for background. */ + if (label & LABEL_TRANSMIT) { + float threshold_squared = kernel_data.background.transparent_roughness_squared_threshold; + + if (threshold_squared >= 0.0f) { + if (bsdf_get_specular_roughness_squared(sc) <= threshold_squared) { + label |= LABEL_TRANSMIT_TRANSPARENT; + } + } + } + return label; +} + #ifndef __KERNEL_CUDA__ ccl_device #else diff --git a/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h b/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h index 75995262030..cfe1ced43f2 100644 --- a/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h +++ b/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h @@ -137,9 +137,11 @@ ccl_device int bsdf_ashikhmin_shirley_sample(ccl_private const ShaderClosure *sc float randv, ccl_private Spectrum *eval, ccl_private float3 *omega_in, - ccl_private float *pdf) + ccl_private float *pdf, + ccl_private float2 *sampled_roughness) { ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; + *sampled_roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y); float3 N = bsdf->N; int label = LABEL_REFLECT | LABEL_GLOSSY; diff --git a/intern/cycles/kernel/closure/bsdf_hair.h b/intern/cycles/kernel/closure/bsdf_hair.h index a29f7c444ae..69c05813982 100644 --- a/intern/cycles/kernel/closure/bsdf_hair.h +++ b/intern/cycles/kernel/closure/bsdf_hair.h @@ -155,13 +155,15 @@ ccl_device int bsdf_hair_reflection_sample(ccl_private const ShaderClosure *sc, float randv, ccl_private Spectrum *eval, ccl_private float3 *omega_in, - ccl_private float *pdf) + ccl_private float *pdf, + ccl_private float2 *sampled_roughness) { ccl_private const HairBsdf *bsdf = (ccl_private const HairBsdf *)sc; float offset = bsdf->offset; float3 Tg = bsdf->T; float roughness1 = bsdf->roughness1; float roughness2 = bsdf->roughness2; + *sampled_roughness = make_float2(roughness1, roughness2); float Iz = dot(Tg, I); float3 locy = normalize(I - Tg * Iz); float3 locx = cross(locy, Tg); @@ -206,13 +208,15 @@ ccl_device int bsdf_hair_transmission_sample(ccl_private const ShaderClosure *sc float randv, ccl_private Spectrum *eval, ccl_private float3 *omega_in, - ccl_private float *pdf) + ccl_private float *pdf, + ccl_private float2 *sampled_roughness) { ccl_private const HairBsdf *bsdf = (ccl_private const HairBsdf *)sc; float offset = bsdf->offset; float3 Tg = bsdf->T; float roughness1 = bsdf->roughness1; float roughness2 = bsdf->roughness2; + *sampled_roughness = make_float2(roughness1, roughness2); float Iz = dot(Tg, I); float3 locy = normalize(I - Tg * Iz); float3 locx = cross(locy, Tg); diff --git a/intern/cycles/kernel/closure/bsdf_hair_principled.h b/intern/cycles/kernel/closure/bsdf_hair_principled.h index 2236bc62050..d0a44c65d52 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_principled.h +++ b/intern/cycles/kernel/closure/bsdf_hair_principled.h @@ -354,10 +354,15 @@ ccl_device int bsdf_principled_hair_sample(KernelGlobals kg, float randv, ccl_private Spectrum *eval, ccl_private float3 *omega_in, - ccl_private float *pdf) + ccl_private float *pdf, + ccl_private float2 *sampled_roughness, + ccl_private float *eta) { ccl_private PrincipledHairBSDF *bsdf = (ccl_private PrincipledHairBSDF *)sc; + *sampled_roughness = make_float2(bsdf->m0_roughness, bsdf->m0_roughness); + *eta = bsdf->eta; + float3 Y = float4_to_float3(bsdf->extra->geom); float3 X = safe_normalize(sd->dPdu); diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h index 04d5ca90bfd..f29897bc55d 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet.h @@ -541,12 +541,18 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg, float randv, ccl_private Spectrum *eval, ccl_private float3 *omega_in, - ccl_private float *pdf) + ccl_private float *pdf, + ccl_private float2 *sampled_roughness, + ccl_private float *eta) { ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; float alpha_x = bsdf->alpha_x; float alpha_y = bsdf->alpha_y; bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; + + *sampled_roughness = make_float2(alpha_x, alpha_y); + *eta = m_refractive ? 1.0f / bsdf->ior : bsdf->ior; + float3 N = bsdf->N; int label; @@ -952,7 +958,9 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg, float randv, ccl_private Spectrum *eval, ccl_private float3 *omega_in, - ccl_private float *pdf) + ccl_private float *pdf, + ccl_private float2 *sampled_roughness, + ccl_private float *eta) { ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; float alpha_x = bsdf->alpha_x; @@ -961,6 +969,9 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg, float3 N = bsdf->N; int label; + *sampled_roughness = make_float2(alpha_x, alpha_y); + *eta = m_refractive ? 1.0f / bsdf->ior : bsdf->ior; + float cosNO = dot(N, I); if (cosNO > 0) { float3 X, Y, Z = N; diff --git a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h index 9402ce11f7a..34115749611 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h @@ -462,6 +462,12 @@ ccl_device Spectrum bsdf_microfacet_multi_ggx_eval_reflect(ccl_private const Sha *pdf = mf_ggx_aniso_pdf(localI, localO, make_float2(bsdf->alpha_x, bsdf->alpha_y)); else *pdf = mf_ggx_pdf(localI, localO, bsdf->alpha_x); + + if (*pdf <= 0.f) { + *pdf = 0.f; + return make_float3(0.f, 0.f, 0.f); + } + return mf_eval_glossy(localI, localO, true, @@ -483,7 +489,9 @@ ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals kg, ccl_private Spectrum *eval, ccl_private float3 *omega_in, ccl_private float *pdf, - ccl_private uint *lcg_state) + ccl_private uint *lcg_state, + ccl_private float2 *sampled_roughness, + ccl_private float *eta) { ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; @@ -511,6 +519,9 @@ ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals kg, bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID); + *eta = bsdf->ior; + *sampled_roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y); + bool is_aniso = (bsdf->alpha_x != bsdf->alpha_y); if (is_aniso) make_orthonormals_tangent(Z, bsdf->T, &X, &Y); @@ -541,6 +552,7 @@ ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals kg, *pdf = mf_ggx_aniso_pdf(localI, localO, make_float2(bsdf->alpha_x, bsdf->alpha_y)); else *pdf = mf_ggx_pdf(localI, localO, bsdf->alpha_x); + *pdf = fmaxf(0.f, *pdf); *eval *= *pdf; return LABEL_REFLECT | LABEL_GLOSSY; @@ -598,6 +610,7 @@ bsdf_microfacet_multi_ggx_glass_eval_transmit(ccl_private const ShaderClosure *s float3 localO = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z)); *pdf = mf_glass_pdf(localI, localO, bsdf->alpha_x, bsdf->ior); + kernel_assert(*pdf >= 0.f); return mf_eval_glass(localI, localO, false, @@ -634,6 +647,7 @@ bsdf_microfacet_multi_ggx_glass_eval_reflect(ccl_private const ShaderClosure *sc float3 localO = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z)); *pdf = mf_glass_pdf(localI, localO, bsdf->alpha_x, bsdf->ior); + kernel_assert(*pdf >= 0.f); return mf_eval_glass(localI, localO, true, @@ -655,13 +669,18 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals kg, ccl_private Spectrum *eval, ccl_private float3 *omega_in, ccl_private float *pdf, - ccl_private uint *lcg_state) + ccl_private uint *lcg_state, + ccl_private float2 *sampled_roughness, + ccl_private float *eta) { ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; float3 X, Y, Z; Z = bsdf->N; + *eta = bsdf->ior; + *sampled_roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y); + if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) { float3 R, T; bool inside; @@ -696,6 +715,7 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals kg, use_fresnel, bsdf->extra->cspec0); *pdf = mf_glass_pdf(localI, localO, bsdf->alpha_x, bsdf->ior); + kernel_assert(*pdf >= 0.f); *eval *= *pdf; *omega_in = X * localO.x + Y * localO.y + Z * localO.z; diff --git a/intern/cycles/kernel/closure/bsdf_phong_ramp.h b/intern/cycles/kernel/closure/bsdf_phong_ramp.h index 4236e77ae6c..a50df0b397d 100644 --- a/intern/cycles/kernel/closure/bsdf_phong_ramp.h +++ b/intern/cycles/kernel/closure/bsdf_phong_ramp.h @@ -79,6 +79,11 @@ ccl_device float3 bsdf_phong_ramp_eval_transmit(ccl_private const ShaderClosure return make_float3(0.0f, 0.0f, 0.0f); } +ccl_device_inline float phong_ramp_exponent_to_roughness(float exponent) +{ + return sqrt(1.0f / ((exponent + 2.0f) / 2.0f)); +} + ccl_device int bsdf_phong_ramp_sample(ccl_private const ShaderClosure *sc, float3 Ng, float3 I, @@ -86,11 +91,14 @@ ccl_device int bsdf_phong_ramp_sample(ccl_private const ShaderClosure *sc, float randv, ccl_private Spectrum *eval, ccl_private float3 *omega_in, - ccl_private float *pdf) + ccl_private float *pdf, + ccl_private float2 *sampled_roughness) { ccl_private const PhongRampBsdf *bsdf = (ccl_private const PhongRampBsdf *)sc; float cosNO = dot(bsdf->N, I); float m_exponent = bsdf->exponent; + const float m_roughness = phong_ramp_exponent_to_roughness(m_exponent); + *sampled_roughness = make_float2(m_roughness, m_roughness); if (cosNO > 0) { // reflect the view vector diff --git a/intern/cycles/kernel/closure/bsdf_reflection.h b/intern/cycles/kernel/closure/bsdf_reflection.h index 5e6c6cdcde6..798bcfaf9e7 100644 --- a/intern/cycles/kernel/closure/bsdf_reflection.h +++ b/intern/cycles/kernel/closure/bsdf_reflection.h @@ -43,10 +43,12 @@ ccl_device int bsdf_reflection_sample(ccl_private const ShaderClosure *sc, float randv, ccl_private Spectrum *eval, ccl_private float3 *omega_in, - ccl_private float *pdf) + 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 cosNO = dot(N, I); diff --git a/intern/cycles/kernel/closure/bsdf_refraction.h b/intern/cycles/kernel/closure/bsdf_refraction.h index e680a9617db..34836206ddf 100644 --- a/intern/cycles/kernel/closure/bsdf_refraction.h +++ b/intern/cycles/kernel/closure/bsdf_refraction.h @@ -43,10 +43,13 @@ ccl_device int bsdf_refraction_sample(ccl_private const ShaderClosure *sc, float randv, ccl_private Spectrum *eval, ccl_private float3 *omega_in, - ccl_private float *pdf) + 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; diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h index c19f56a9b70..7c31d673566 100644 --- a/intern/cycles/kernel/integrator/shade_surface.h +++ b/intern/cycles/kernel/integrator/shade_surface.h @@ -357,8 +357,18 @@ ccl_device_forceinline int integrate_surface_bsdf_bssrdf_bounce( float3 bsdf_omega_in ccl_optional_struct_init; int label; - label = surface_shader_bsdf_sample_closure( - kg, sd, sc, rand_bsdf, &bsdf_eval, &bsdf_omega_in, &bsdf_pdf); + float2 bsdf_sampled_roughness = make_float2(1.0f, 1.0f); + float bsdf_eta = 1.0f; + + label = surface_shader_bsdf_sample_closure(kg, + sd, + sc, + rand_bsdf, + &bsdf_eval, + &bsdf_omega_in, + &bsdf_pdf, + &bsdf_sampled_roughness, + &bsdf_eta); if (bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval)) { return LABEL_NONE; diff --git a/intern/cycles/kernel/integrator/surface_shader.h b/intern/cycles/kernel/integrator/surface_shader.h index 64b5556f7e9..125aaae1b3f 100644 --- a/intern/cycles/kernel/integrator/surface_shader.h +++ b/intern/cycles/kernel/integrator/surface_shader.h @@ -267,7 +267,9 @@ ccl_device int surface_shader_bsdf_sample_closure(KernelGlobals kg, const float2 rand_bsdf, ccl_private BsdfEval *bsdf_eval, ccl_private float3 *omega_in, - ccl_private float *pdf) + ccl_private float *pdf, + ccl_private float2 *sampled_roughness, + ccl_private float *eta) { /* BSSRDF should already have been handled elsewhere. */ kernel_assert(CLOSURE_IS_BSDF(sc->type)); @@ -276,7 +278,8 @@ 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, omega_in, pdf); + label = bsdf_sample( + kg, sd, sc, rand_bsdf.x, rand_bsdf.y, &eval, omega_in, 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 f8d68444f90..96c551b9951 100644 --- a/intern/cycles/kernel/osl/closures_setup.h +++ b/intern/cycles/kernel/osl/closures_setup.h @@ -428,7 +428,7 @@ ccl_device void osl_closure_microfacet_multi_ggx_setup( bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); bsdf->alpha_x = closure->alpha_x; bsdf->alpha_y = bsdf->alpha_x; - bsdf->ior = 0.0f; + bsdf->ior = 1.0f; bsdf->extra = extra; bsdf->extra->color = rgb_to_spectrum(closure->color); @@ -510,7 +510,7 @@ ccl_device void osl_closure_microfacet_multi_ggx_aniso_setup( bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); bsdf->alpha_x = closure->alpha_x; bsdf->alpha_y = closure->alpha_y; - bsdf->ior = 0.0f; + bsdf->ior = 1.0f; bsdf->extra = extra; bsdf->extra->color = rgb_to_spectrum(closure->color); diff --git a/intern/cycles/kernel/svm/closure.h b/intern/cycles/kernel/svm/closure.h index 2d91b014f60..d18f2cc0854 100644 --- a/intern/cycles/kernel/svm/closure.h +++ b/intern/cycles/kernel/svm/closure.h @@ -31,7 +31,7 @@ ccl_device void svm_node_glass_setup(ccl_private ShaderData *sd, else { bsdf->alpha_y = 0.0f; bsdf->alpha_x = 0.0f; - bsdf->ior = 0.0f; + bsdf->ior = eta; sd->flag |= bsdf_reflection_setup(bsdf); } } @@ -542,7 +542,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, float roughness = sqr(param1); bsdf->N = N; - bsdf->ior = 0.0f; + bsdf->ior = 1.0f; bsdf->extra = NULL; if (data_node.y == SVM_STACK_INVALID) { -- cgit v1.2.3