diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h index 227150a48ba..213135b576d 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet.h @@ -38,6 +38,7 @@ CCL_NAMESPACE_BEGIN typedef ccl_addr_space struct MicrofacetExtra { float3 color, cspec0; bool use_fresnel, is_disney_clearcoat; + float clearcoat; } MicrofacetExtra; typedef ccl_addr_space struct MicrofacetBsdf { @@ -253,6 +254,14 @@ ccl_device_forceinline float3 reflection_color(const MicrofacetBsdf *bsdf, float return F; } +ccl_device_forceinline float D_GTR1(float NdotH, float alpha) +{ + if (alpha >= 1.0f) return M_1_PI_F; + float alpha2 = alpha*alpha; + float t = 1.0f + (alpha2 - 1.0f) * NdotH*NdotH; + return (alpha2 - 1.0f) / (M_1_PI_F * logf(alpha2) * t); +} + /* GGX microfacet with Smith shadow-masking from: * * Microfacet Models for Refraction through Rough Surfaces @@ -404,14 +413,18 @@ ccl_device float3 bsdf_microfacet_ggx_eval_reflect(const ShaderClosure *sc, cons float cosThetaM2 = cosThetaM * cosThetaM; float cosThetaM4 = cosThetaM2 * cosThetaM2; float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2; - D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); - if(bsdf->extra) { - if(bsdf->extra->is_disney_clearcoat) { - /* the alpha value for clearcoat is a fixed 0.25 => alpha2 = 0.25 * 0.25 */ - alpha2 = 0.0625f; - } + if(bsdf->extra && bsdf->extra->is_disney_clearcoat) { + /* use GTR1 for clearcoat */ + D = D_GTR1(cosThetaM, bsdf->alpha_x); + + /* the alpha value for clearcoat is a fixed 0.25 => alpha2 = 0.25 * 0.25 */ + alpha2 = 0.0625f; } + else { + /* use GTR2 otherwise */ + D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); + } /* eq. 34: now calculate G1(i,m) and G1(o,m) */ G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); @@ -460,6 +473,9 @@ ccl_device float3 bsdf_microfacet_ggx_eval_reflect(const ShaderClosure *sc, cons float common = D * 0.25f / cosNO; float3 F = reflection_color(bsdf, omega_in, m); + if(bsdf->extra && bsdf->extra->is_disney_clearcoat) { + F *= 0.25f * bsdf->extra->clearcoat; + } float3 out = F * G * common; @@ -592,20 +608,26 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals *kg, const ShaderClosure float cosThetaM2 = cosThetaM * cosThetaM; float cosThetaM4 = cosThetaM2 * cosThetaM2; float tanThetaM2 = 1/(cosThetaM2) - 1; - D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); /* eval BRDF*cosNI */ float cosNI = dot(N, *omega_in); - /* eq. 34: now calculate G1(i,m) */ if(bsdf->extra && bsdf->extra->is_disney_clearcoat) { + /* use GTR1 for clearcoat */ + D = D_GTR1(cosThetaM, bsdf->alpha_x); + /* the alpha value for clearcoat is a fixed 0.25 => alpha2 = 0.25 * 0.25 */ alpha2 = 0.0625f; /* recalculate G1o */ G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); } + else { + /* use GTR2 otherwise */ + D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); + } + /* eq. 34: now calculate G1(i,m) */ G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); } else { @@ -639,6 +661,9 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals *kg, const ShaderClosure *pdf = common; float3 F = reflection_color(bsdf, *omega_in, m); + if(bsdf->extra && bsdf->extra->is_disney_clearcoat) { + F *= 0.25f * bsdf->extra->clearcoat; + } *eval = G1i * common * F; } diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp index 1dac0910a36..4d51dda7197 100644 --- a/intern/cycles/kernel/osl/osl_closures.cpp +++ b/intern/cycles/kernel/osl/osl_closures.cpp @@ -205,6 +205,7 @@ public: bsdf->alpha_y = 0.1f * (1.0f - clearcoat_gloss) + 0.001f * clearcoat_gloss; bsdf->extra->cspec0 = make_float3(0.04f, 0.04f, 0.04f); + bsdf->extra->clearcoat = clearcoat; return bsdf; } diff --git a/intern/cycles/kernel/shaders/node_disney_bsdf.osl b/intern/cycles/kernel/shaders/node_disney_bsdf.osl index 7e78c4cfed4..48aad1d90c9 100644 --- a/intern/cycles/kernel/shaders/node_disney_bsdf.osl +++ b/intern/cycles/kernel/shaders/node_disney_bsdf.osl @@ -113,7 +113,7 @@ shader node_disney_bsdf( } if (Clearcoat > 1e-5) { - BSDF = BSDF + 0.25 * Clearcoat * disney_clearcoat(ClearcoatNormal, Clearcoat, ClearcoatGloss); + BSDF = BSDF + disney_clearcoat(ClearcoatNormal, Clearcoat, ClearcoatGloss); } } diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h index db6c1ec4159..213265b2d37 100644 --- a/intern/cycles/kernel/svm/svm_closure.h +++ b/intern/cycles/kernel/svm/svm_closure.h @@ -432,9 +432,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * if(kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) { #endif if(clearcoat > CLOSURE_WEIGHT_CUTOFF) { - float3 clearcoat_weight = 0.25f * clearcoat * weight; - - MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), clearcoat_weight); + MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight); MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra)); if(bsdf && extra) { @@ -446,6 +444,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * bsdf->alpha_y = 0.1f * (1.0f - clearcoat_gloss) + 0.001f * clearcoat_gloss; bsdf->extra->cspec0 = make_float3(0.04f, 0.04f, 0.04f); + bsdf->extra->clearcoat = clearcoat; /* setup bsdf */ ccl_fetch(sd, flag) |= bsdf_microfacet_ggx_clearcoat_setup(bsdf);