Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/kernel/closure/bsdf_microfacet_multi.h')
-rw-r--r--intern/cycles/kernel/closure/bsdf_microfacet_multi.h40
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