diff options
Diffstat (limited to 'intern/cycles/kernel/closure/bsdf_microfacet_multi.h')
-rw-r--r-- | intern/cycles/kernel/closure/bsdf_microfacet_multi.h | 24 |
1 files changed, 22 insertions, 2 deletions
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; |