diff options
Diffstat (limited to 'intern/cycles/kernel/closure')
-rw-r--r-- | intern/cycles/kernel/closure/bsdf.h | 323 | ||||
-rw-r--r-- | intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h | 4 | ||||
-rw-r--r-- | intern/cycles/kernel/closure/bsdf_hair.h | 8 | ||||
-rw-r--r-- | intern/cycles/kernel/closure/bsdf_hair_principled.h | 7 | ||||
-rw-r--r-- | intern/cycles/kernel/closure/bsdf_microfacet.h | 15 | ||||
-rw-r--r-- | intern/cycles/kernel/closure/bsdf_microfacet_multi.h | 24 | ||||
-rw-r--r-- | intern/cycles/kernel/closure/bsdf_phong_ramp.h | 10 | ||||
-rw-r--r-- | intern/cycles/kernel/closure/bsdf_reflection.h | 4 | ||||
-rw-r--r-- | intern/cycles/kernel/closure/bsdf_refraction.h | 5 |
9 files changed, 375 insertions, 25 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 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; |