diff options
author | Sebastian Herhoz <sebastian.herholz@intel.com> | 2022-09-21 18:46:10 +0300 |
---|---|---|
committer | Brecht Van Lommel <brecht@blender.org> | 2022-09-27 16:47:03 +0300 |
commit | bd249eb4f37e65b2f4b3deef775bb136a2c234d1 (patch) | |
tree | b25c4fa279f5d89929c81a901a81c4cd14ea5f81 /intern/cycles/kernel/closure/bsdf.h | |
parent | 715c86d9e58f44ed078dd61c1fed45739bf65723 (diff) |
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
Diffstat (limited to 'intern/cycles/kernel/closure/bsdf.h')
-rw-r--r-- | intern/cycles/kernel/closure/bsdf.h | 323 |
1 files changed, 309 insertions, 14 deletions
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 |