diff options
Diffstat (limited to 'intern/cycles/kernel/closure/bsdf_reflection.h')
-rw-r--r-- | intern/cycles/kernel/closure/bsdf_reflection.h | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/intern/cycles/kernel/closure/bsdf_reflection.h b/intern/cycles/kernel/closure/bsdf_reflection.h index c24ba170915..5e05e0a884e 100644 --- a/intern/cycles/kernel/closure/bsdf_reflection.h +++ b/intern/cycles/kernel/closure/bsdf_reflection.h @@ -70,7 +70,8 @@ ccl_device int bsdf_reflection_sample(const ShaderClosure *sc, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, - float *pdf) + float *pdf, + const ShaderData *sd) { const MicrofacetBsdf *bsdf = (const MicrofacetBsdf *)sc; float3 N = bsdf->N; @@ -81,8 +82,18 @@ ccl_device int bsdf_reflection_sample(const ShaderClosure *sc, *omega_in = (2 * cosNO) * N - I; if (dot(Ng, *omega_in) > 0) { #ifdef __RAY_DIFFERENTIALS__ - *domega_in_dx = 2 * dot(N, dIdx) * N - dIdx; - *domega_in_dy = 2 * dot(N, dIdy) * N - dIdy; +# ifdef __DNDU__ + /* as described in pbrt */ + float3 dwodx = -dIdx; + float3 dwody = -dIdy; + float dDNdx = dot(dwodx, N) + dot(I, sd->dNdx); + float dDNdy = dot(dwody, N) + dot(I, sd->dNdy); + *domega_in_dx = dwodx + 2.f * (dot(I, N) * sd->dNdx + dDNdx * N); + *domega_in_dy = dwody + 2.f * (dot(I, N) * sd->dNdy + dDNdy * N); +# else + *domega_in_dx = 2.0f * dot(N, dIdx) * N - dIdx; + *domega_in_dy = 2.0f * dot(N, dIdy) * N - dIdy; +# endif #endif /* Some high number for MIS. */ *pdf = 1e6f; |