diff options
Diffstat (limited to 'intern/cycles/kernel/closure/bsdf_microfacet_multi.h')
-rw-r--r-- | intern/cycles/kernel/closure/bsdf_microfacet_multi.h | 40 |
1 files changed, 28 insertions, 12 deletions
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h index 6060d7d8ccb..acb50ce6faa 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h @@ -42,7 +42,7 @@ ccl_device_inline float D_ggx_aniso(const float3 wm, const float2 alpha) /* Sample slope distribution (based on page 14 of the supplemental implementation). */ ccl_device_inline float2 mf_sampleP22_11(const float cosI, const float2 randU) { - if(cosI > 0.9999f) { + if(cosI > 0.9999f || cosI < 1e-6f) { const float r = sqrtf(randU.x / (1.0f - randU.x)); const float phi = M_2PI_F * randU.y; return make_float2(r*cosf(phi), r*sinf(phi)); @@ -117,7 +117,7 @@ ccl_device_inline float3 mf_eval_phase_glossy(const float3 w, const float lambda if(dotW_WH < 0.0f) return make_float3(0.0f, 0.0f, 0.0f); - float phase = max(0.0f, dotW_WH) * 0.25f / (pArea * dotW_WH); + float phase = max(0.0f, dotW_WH) * 0.25f / max(pArea * dotW_WH, 1e-7f); if(alpha.x == alpha.y) phase *= D_ggx(wh, alpha.x); else @@ -200,9 +200,9 @@ ccl_device_inline float mf_lambda(const float3 w, const float2 alpha) if(w.z > 0.9999f) return 0.0f; else if(w.z < -0.9999f) - return -1.0f; + return -0.9999f; - const float inv_wz2 = 1.0f / (w.z*w.z); + const float inv_wz2 = 1.0f / max(w.z*w.z, 1e-7f); const float2 wa = make_float2(w.x, w.y)*alpha; float v = sqrtf(1.0f + dot(wa, wa) * inv_wz2); if(w.z <= 0.0f) @@ -271,7 +271,10 @@ ccl_device_inline float mf_ggx_albedo(float r) ccl_device_inline float mf_ggx_pdf(const float3 wi, const float3 wo, const float alpha) { - return 0.25f * D_ggx(normalize(wi+wo), alpha) / ((1.0f + mf_lambda(wi, make_float2(alpha, alpha))) * wi.z) + (1.0f - mf_ggx_albedo(alpha)) * wo.z; + float D = D_ggx(normalize(wi+wo), alpha); + float lambda = mf_lambda(wi, make_float2(alpha, alpha)); + float albedo = mf_ggx_albedo(alpha); + return 0.25f * D / max((1.0f + lambda) * wi.z, 1e-7f) + (1.0f - albedo) * wo.z; } ccl_device_inline float mf_ggx_aniso_pdf(const float3 wi, const float3 wo, const float2 alpha) @@ -348,11 +351,7 @@ ccl_device int bsdf_microfacet_multi_ggx_common_setup(ShaderClosure *sc) ccl_device int bsdf_microfacet_multi_ggx_aniso_setup(ShaderClosure *sc) { -#ifdef __KERNEL_OPENCL__ - if(all(sc->T == 0.0f)) -#else - if(sc->T == make_float3(0.0f, 0.0f, 0.0f)) -#endif + if(is_zero(sc->T)) sc->T = make_float3(1.0f, 0.0f, 0.0f); return bsdf_microfacet_multi_ggx_common_setup(sc); @@ -410,6 +409,10 @@ ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals *kg, const ShaderC *eval *= *pdf; *omega_in = X*localO.x + Y*localO.y + Z*localO.z; +#ifdef __RAY_DIFFERENTIALS__ + *domega_in_dx = (2 * dot(Z, dIdx)) * Z - dIdx; + *domega_in_dy = (2 * dot(Z, dIdy)) * Z - dIdy; +#endif return LABEL_REFLECT|LABEL_GLOSSY; } @@ -467,10 +470,23 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals *kg, const S *eval *= *pdf; *omega_in = X*localO.x + Y*localO.y + Z*localO.z; - if(localO.z*localI.z > 0.0f) + if(localO.z*localI.z > 0.0f) { +#ifdef __RAY_DIFFERENTIALS__ + *domega_in_dx = (2 * dot(Z, dIdx)) * Z - dIdx; + *domega_in_dy = (2 * dot(Z, dIdy)) * Z - dIdy; +#endif return LABEL_REFLECT|LABEL_GLOSSY; - else + } + else { +#ifdef __RAY_DIFFERENTIALS__ + float cosI = dot(Z, I); + float dnp = max(sqrtf(1.0f - (sc->data2 * sc->data2 * (1.0f - cosI*cosI))), 1e-7f); + *domega_in_dx = -(sc->data2 * dIdx) + ((sc->data2 - sc->data2 * sc->data2 * cosI / dnp) * dot(dIdx, Z)) * Z; + *domega_in_dy = -(sc->data2 * dIdy) + ((sc->data2 - sc->data2 * sc->data2 * cosI / dnp) * dot(dIdy, Z)) * Z; +#endif + return LABEL_TRANSMIT|LABEL_GLOSSY; + } } CCL_NAMESPACE_END |