diff options
author | Pascal Schoen <pascal_schoen@gmx.net> | 2016-09-16 09:47:56 +0300 |
---|---|---|
committer | Pascal Schoen <pascal_schoen@gmx.net> | 2016-09-16 09:47:56 +0300 |
commit | 3cd5eb56cf5c9006837f111c8866e4c6e1c2a6fd (patch) | |
tree | 68d84cded51b493ec2681761811f34fd9b74646d /intern/cycles | |
parent | 7cb37d711938e5626651db21f20da50edd96abaf (diff) |
Fixed a bug in the Disney BSDF that caused specular reflections to be too
bright and diffuse is now reacting to the roughness again
- A normalization for the fresnel was missing which caused the specular
reflections to become too bright for the single-scatter GGX
- The roughness value for the diffuse BSSRDF part has always been
overwritten and thus always 0
- Also the performance for refractive materials with roughness=0.0 has
been improved
Diffstat (limited to 'intern/cycles')
-rw-r--r-- | intern/cycles/kernel/closure/bsdf_disney_specular.h | 68 | ||||
-rw-r--r-- | intern/cycles/kernel/closure/bsdf_microfacet.h | 56 | ||||
-rw-r--r-- | intern/cycles/kernel/closure/bsdf_reflection.h | 16 | ||||
-rw-r--r-- | intern/cycles/kernel/closure/bssrdf.h | 15 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/osl_closures.cpp | 68 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/osl_closures.h | 2 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_closure.h | 64 |
7 files changed, 175 insertions, 114 deletions
diff --git a/intern/cycles/kernel/closure/bsdf_disney_specular.h b/intern/cycles/kernel/closure/bsdf_disney_specular.h index 7e8139fd040..b83bb2920fa 100644 --- a/intern/cycles/kernel/closure/bsdf_disney_specular.h +++ b/intern/cycles/kernel/closure/bsdf_disney_specular.h @@ -35,34 +35,39 @@ CCL_NAMESPACE_BEGIN +typedef ccl_addr_space struct DisneySpecularExtra { + float3 T, baseColor, cspec0; + bool alpha_x, alpha_y, rough_g, ior; +} DisneySpecularExtra; + typedef ccl_addr_space struct DisneySpecularBsdf { SHADER_CLOSURE_BASE; - float specular, specularTint, roughness, metallic, anisotropic, alpha_x, alpha_y, rough_g; - float3 N, T; - float3 baseColor, cspec0; + float specular, specularTint, roughness, metallic, anisotropic; + float3 N; + DisneySpecularExtra *extra; } DisneySpecularBsdf; ccl_device int bsdf_disney_specular_setup(DisneySpecularBsdf *bsdf) { - float m_cdlum = 0.3f * bsdf->baseColor.x + 0.6f * bsdf->baseColor.y + 0.1f * bsdf->baseColor.z; // luminance approx. + float m_cdlum = 0.3f * bsdf->extra->baseColor.x + 0.6f * bsdf->extra->baseColor.y + 0.1f * bsdf->extra->baseColor.z; // luminance approx. - float3 m_ctint = m_cdlum > 0.0f ? bsdf->baseColor / m_cdlum : make_float3(1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat + float3 m_ctint = m_cdlum > 0.0f ? bsdf->extra->baseColor / m_cdlum : make_float3(1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat float3 tmp_col = make_float3(1.0f, 1.0f, 1.0f) * (1.0f - bsdf->specularTint) + m_ctint * bsdf->specularTint; // lerp(make_float3(1.0f, 1.0f, 1.0f), m_ctint, sc->data2/*specularTint*/); - bsdf->cspec0 = (bsdf->specular * 0.08f * tmp_col) * (1.0f - bsdf->metallic) + bsdf->baseColor * bsdf->metallic; // lerp(sc->data1/*specular*/ * 0.08f * tmp_col, sc->color0/*baseColor*/, sc->data0/*metallic*/); + bsdf->extra->cspec0 = (bsdf->specular * 0.08f * tmp_col) * (1.0f - bsdf->metallic) + bsdf->extra->baseColor * bsdf->metallic; // lerp(sc->data1/*specular*/ * 0.08f * tmp_col, sc->color0/*baseColor*/, sc->data0/*metallic*/); float aspect = safe_sqrtf(1.0f - bsdf->anisotropic * 0.9f); float r2 = sqr(bsdf->roughness); /* ax */ - bsdf->alpha_x = fmaxf(0.001f, r2 / aspect); + bsdf->extra->alpha_x = fmaxf(0.001f, r2 / aspect); /* ay */ - bsdf->alpha_y = fmaxf(0.001f, r2 * aspect); + bsdf->extra->alpha_y = fmaxf(0.001f, r2 * aspect); /* rough_g */ - bsdf->rough_g = sqr(bsdf->roughness * 0.5f + 0.5f); + bsdf->extra->rough_g = sqr(bsdf->roughness * 0.5f + 0.5f); bsdf->type = CLOSURE_BSDF_DISNEY_SPECULAR_ID; return SD_BSDF|SD_BSDF_HAS_EVAL; @@ -75,7 +80,7 @@ ccl_device float3 bsdf_disney_specular_eval_reflect(const ShaderClosure *sc, con float3 N = bsdf->N; - if (fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f) + if (bsdf->extra->alpha_x*bsdf->extra->alpha_y <= 1e-7f) return make_float3(0.0f, 0.0f, 0.0f); float cosNO = dot(N, I); @@ -84,10 +89,10 @@ ccl_device float3 bsdf_disney_specular_eval_reflect(const ShaderClosure *sc, con if (cosNI > 0 && cosNO > 0) { /* get half vector */ float3 m = normalize(omega_in + I); - float alpha2 = bsdf->alpha_x * bsdf->alpha_y; + float alpha2 = bsdf->extra->alpha_x * bsdf->extra->alpha_y; float D, G1o, G1i; - if (bsdf->alpha_x == bsdf->alpha_y) { + if (bsdf->extra->alpha_x == bsdf->extra->alpha_y) { /* isotropic * eq. 20: (F*G*D)/(4*in*on) * eq. 33: first we calculate D(m) */ @@ -104,12 +109,12 @@ ccl_device float3 bsdf_disney_specular_eval_reflect(const ShaderClosure *sc, con else { /* anisotropic */ float3 X, Y, Z = N; - make_orthonormals_tangent(Z, bsdf->T, &X, &Y); + make_orthonormals_tangent(Z, bsdf->extra->T, &X, &Y); // distribution float3 local_m = make_float3(dot(X, m), dot(Y, m), dot(Z, m)); - float slope_x = -local_m.x/(local_m.z*bsdf->alpha_x); - float slope_y = -local_m.y/(local_m.z*bsdf->alpha_y); + float slope_x = -local_m.x/(local_m.z*bsdf->extra->alpha_x); + float slope_y = -local_m.y/(local_m.z*bsdf->extra->alpha_y); float slope_len = 1 + slope_x*slope_x + slope_y*slope_y; float cosThetaM = local_m.z; @@ -123,7 +128,7 @@ ccl_device float3 bsdf_disney_specular_eval_reflect(const ShaderClosure *sc, con float cosPhiO = dot(I, X); float sinPhiO = dot(I, Y); - float alphaO2 = (cosPhiO*cosPhiO)*(bsdf->alpha_x*bsdf->alpha_x) + (sinPhiO*sinPhiO)*(bsdf->alpha_y*bsdf->alpha_y); + float alphaO2 = (cosPhiO*cosPhiO)*(bsdf->extra->alpha_x*bsdf->extra->alpha_x) + (sinPhiO*sinPhiO)*(bsdf->extra->alpha_y*bsdf->extra->alpha_y); alphaO2 /= cosPhiO*cosPhiO + sinPhiO*sinPhiO; G1o = 2 / (1 + safe_sqrtf(1 + alphaO2 * tanThetaO2)); @@ -132,7 +137,7 @@ ccl_device float3 bsdf_disney_specular_eval_reflect(const ShaderClosure *sc, con float cosPhiI = dot(omega_in, X); float sinPhiI = dot(omega_in, Y); - float alphaI2 = (cosPhiI*cosPhiI)*(bsdf->alpha_x*bsdf->alpha_x) + (sinPhiI*sinPhiI)*(bsdf->alpha_y*bsdf->alpha_y); + float alphaI2 = (cosPhiI*cosPhiI)*(bsdf->extra->alpha_x*bsdf->extra->alpha_x) + (sinPhiI*sinPhiI)*(bsdf->extra->alpha_y*bsdf->extra->alpha_y); alphaI2 /= cosPhiI*cosPhiI + sinPhiI*sinPhiI; G1i = 2 / (1 + safe_sqrtf(1 + alphaI2 * tanThetaI2)); @@ -144,7 +149,7 @@ ccl_device float3 bsdf_disney_specular_eval_reflect(const ShaderClosure *sc, con float common = D * 0.25f / cosNO; float FH = schlick_fresnel(dot(omega_in, m)); - float3 F = bsdf->cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH; // lerp(sc->custom_color0, make_float3(1.0f, 1.0f, 1.0f), FH); + float3 F = bsdf->extra->cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH; // lerp(sc->custom_color0, make_float3(1.0f, 1.0f, 1.0f), FH); float3 out = F * G * common; @@ -181,25 +186,23 @@ ccl_device int bsdf_disney_specular_sample(const ShaderClosure *sc, if(cosNO > 0) { float3 X, Y, Z = N; - if (bsdf->alpha_x == bsdf->alpha_y) + if (bsdf->extra->alpha_x == bsdf->extra->alpha_y) make_orthonormals(Z, &X, &Y); else - make_orthonormals_tangent(Z, bsdf->T, &X, &Y); + make_orthonormals_tangent(Z, bsdf->extra->T, &X, &Y); /* importance sampling with distribution of visible normals. vectors are * transformed to local space before and after */ float3 local_I = make_float3(dot(X, I), dot(Y, I), cosNO); float3 local_m; - float3 m; float G1o; - local_m = importance_sample_microfacet_stretched(local_I, bsdf->alpha_x, bsdf->alpha_y, + local_m = importance_sample_microfacet_stretched(local_I, bsdf->extra->alpha_x, bsdf->extra->alpha_y, randu, randv, false, &G1o); - m = X*local_m.x + Y*local_m.y + Z*local_m.z; + float3 m = X*local_m.x + Y*local_m.y + Z*local_m.z; float cosThetaM = local_m.z; - /* reflection or refraction? */ float cosMO = dot(m, I); if(cosMO > 0) { @@ -207,7 +210,7 @@ ccl_device int bsdf_disney_specular_sample(const ShaderClosure *sc, *omega_in = 2 * cosMO * m - I; if(dot(Ng, *omega_in) > 0) { - if (fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f) { + if (bsdf->extra->alpha_x*bsdf->extra->alpha_y <= 1e-7f) { /* some high number for MIS */ *pdf = 1e6f; *eval = make_float3(1e6f, 1e6f, 1e6f); @@ -215,10 +218,10 @@ ccl_device int bsdf_disney_specular_sample(const ShaderClosure *sc, else { /* microfacet normal is visible to this ray */ /* eq. 33 */ - float alpha2 = bsdf->alpha_x * bsdf->alpha_y; + float alpha2 = bsdf->extra->alpha_x * bsdf->extra->alpha_y; float D, G1i; - if (bsdf->alpha_x == bsdf->alpha_y) { + if (bsdf->extra->alpha_x == bsdf->extra->alpha_y) { float cosThetaM2 = cosThetaM * cosThetaM; float cosThetaM4 = cosThetaM2 * cosThetaM2; float tanThetaM2 = 1/(cosThetaM2) - 1; @@ -232,8 +235,8 @@ ccl_device int bsdf_disney_specular_sample(const ShaderClosure *sc, } else { /* anisotropic distribution */ - float slope_x = -local_m.x / (local_m.z*bsdf->alpha_x); - float slope_y = -local_m.y / (local_m.z*bsdf->alpha_y); + float slope_x = -local_m.x / (local_m.z*bsdf->extra->alpha_x); + float slope_y = -local_m.y / (local_m.z*bsdf->extra->alpha_y); float slope_len = 1 + slope_x*slope_x + slope_y*slope_y; float cosThetaM = local_m.z; @@ -249,7 +252,7 @@ ccl_device int bsdf_disney_specular_sample(const ShaderClosure *sc, float cosPhiI = dot(*omega_in, X); float sinPhiI = dot(*omega_in, Y); - float alphaI2 = (cosPhiI*cosPhiI)*(bsdf->alpha_x*bsdf->alpha_x) + (sinPhiI*sinPhiI)*(bsdf->alpha_y*bsdf->alpha_y); + float alphaI2 = (cosPhiI*cosPhiI)*(bsdf->extra->alpha_x*bsdf->extra->alpha_x) + (sinPhiI*sinPhiI)*(bsdf->extra->alpha_y*bsdf->extra->alpha_y); alphaI2 /= cosPhiI*cosPhiI + sinPhiI*sinPhiI; G1i = 2 / (1 + safe_sqrtf(1 + alphaI2 * tanThetaI2)); @@ -259,8 +262,9 @@ ccl_device int bsdf_disney_specular_sample(const ShaderClosure *sc, float common = (G1o * D) * 0.25f / cosNO; *pdf = common; - float FH = schlick_fresnel(dot(*omega_in, m)); - float3 F = bsdf->cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH; // lerp(sc->custom_color0, make_float3(1.0f, 1.0f, 1.0f), FH); + float FH = fresnel_dielectric_cos(dot(*omega_in, m), bsdf->extra->ior); + //float FH = schlick_fresnel(dot(*omega_in, m)); + float3 F = bsdf->extra->cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH; // lerp(sc->custom_color0, make_float3(1.0f, 1.0f, 1.0f), FH); *eval = G1i * common * F; } diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h index 9ab9b17efe5..6c2f2958af9 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet.h @@ -410,9 +410,17 @@ ccl_device float3 bsdf_microfacet_ggx_eval_reflect(const ShaderClosure *sc, cons float3 F = make_float3(1.0f, 1.0f, 1.0f); if (bsdf->extra) { if (bsdf->extra->use_fresnel) { - float FH = fresnel_dielectric_cos(dot(omega_in, m), bsdf->ior); - - F = bsdf->extra->cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH; // lerp(sc->custom_color0, make_float3(1.0f, 1.0f, 1.0f), FH); + /* Calculate the fresnel interpolation factor + * The value from fresnel_dielectric_cos(...) has to be normalized because + * the cspec0 keeps the F0 color + */ + float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior); + float F0_norm = 1.0f / (1.0f - F0); + float FH = (fresnel_dielectric_cos(dot(omega_in, m), bsdf->ior) - F0) * F0_norm; + //float FH = schlick_fresnel(dot(omega_in, m)); + + /* Blend between white and a specular color with respect to the fresnel */ + F = bsdf->extra->cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH; } } @@ -485,9 +493,17 @@ ccl_device float3 bsdf_microfacet_ggx_eval_transmit(const ShaderClosure *sc, con float3 F = make_float3(1.0f, 1.0f, 1.0f); if (bsdf->extra) { if (bsdf->extra->use_fresnel) { - float FH = fresnel_dielectric_cos(dot(omega_in, Ht), bsdf->ior); - - F = bsdf->extra->cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH; // lerp(sc->custom_color0, make_float3(1.0f, 1.0f, 1.0f), FH); + /* Calculate the fresnel interpolation factor + * The value from fresnel_dielectric_cos(...) has to be normalized because + * the cspec0 keeps the F0 color + */ + float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior); + float F0_norm = 1.0f / (1.0f - F0); + float FH = (fresnel_dielectric_cos(dot(omega_in, Ht), bsdf->ior) - F0) * F0_norm; + //float FH = schlick_fresnel(dot(omega_in, Ht)); + + /* Blend between white and a specular color with respect to the fresnel */ + F = bsdf->extra->cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH; } } @@ -599,9 +615,17 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals *kg, const ShaderClosure float3 F = make_float3(1.0f, 1.0f, 1.0f); if (bsdf->extra) { if (bsdf->extra->use_fresnel) { - float FH = fresnel_dielectric_cos(dot(*omega_in, m), bsdf->ior); - - F = bsdf->extra->cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH; // lerp(sc->custom_color0, make_float3(1.0f, 1.0f, 1.0f), FH); + /* Calculate the fresnel interpolation factor + * The value from fresnel_dielectric_cos(...) has to be normalized because + * the cspec0 keeps the F0 color + */ + float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior); + float F0_norm = 1.0f / (1.0f - F0); + float FH = (fresnel_dielectric_cos(dot(*omega_in, m), bsdf->ior) - F0) * F0_norm; + //float FH = schlick_fresnel(dot(*omega_in, m)); + + /* Blend between white and a specular color with respect to the fresnel */ + F = bsdf->extra->cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH; } } @@ -670,9 +694,17 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals *kg, const ShaderClosure float3 F = make_float3(1.0f, 1.0f, 1.0f); if (bsdf->extra) { if (bsdf->extra->use_fresnel) { - float FH = fresnel_dielectric_cos(dot(*omega_in, m), bsdf->ior); - - F = bsdf->extra->cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH; // lerp(sc->custom_color0, make_float3(1.0f, 1.0f, 1.0f), FH); + /* Calculate the fresnel interpolation factor + * The value from fresnel_dielectric_cos(...) has to be normalized because + * the cspec0 keeps the F0 color + */ + float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior); + float F0_norm = 1.0f / (1.0f - F0); + float FH = (fresnel_dielectric_cos(dot(*omega_in, m), bsdf->ior) - F0) * F0_norm; + //float FH = schlick_fresnel(dot(*omega_in, m)); + + /* Blend between white and a specular color with respect to the fresnel */ + F = bsdf->extra->cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH; } } diff --git a/intern/cycles/kernel/closure/bsdf_reflection.h b/intern/cycles/kernel/closure/bsdf_reflection.h index 1d21614ecee..45fdecfd554 100644 --- a/intern/cycles/kernel/closure/bsdf_reflection.h +++ b/intern/cycles/kernel/closure/bsdf_reflection.h @@ -37,8 +37,11 @@ CCL_NAMESPACE_BEGIN /* REFLECTION */ -ccl_device int bsdf_reflection_setup(MicrofacetBsdf *bsdf) +ccl_device int bsdf_reflection_setup(MicrofacetBsdf *bsdf, bool use_fresnel = false) { + if (bsdf->extra) { + bsdf->extra->use_fresnel = use_fresnel; + } bsdf->type = CLOSURE_BSDF_REFLECTION_ID; return SD_BSDF; } @@ -70,6 +73,17 @@ ccl_device int bsdf_reflection_sample(const ShaderClosure *sc, float3 Ng, float3 /* Some high number for MIS. */ *pdf = 1e6f; *eval = make_float3(1e6f, 1e6f, 1e6f); + + if (bsdf->extra) { + if (bsdf->extra->use_fresnel) { + *pdf = 1.0f; + + float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior); + float F0_norm = 1.0f / (1.0f - F0); + float FH = (fresnel_dielectric_cos(dot(I, normalize(I + *omega_in)), bsdf->ior) - F0) * F0_norm; + *eval = bsdf->extra->cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH; + } + } } } return LABEL_REFLECT|LABEL_SINGULAR; diff --git a/intern/cycles/kernel/closure/bssrdf.h b/intern/cycles/kernel/closure/bssrdf.h index b713ff56b2f..ce28f0dbcbe 100644 --- a/intern/cycles/kernel/closure/bssrdf.h +++ b/intern/cycles/kernel/closure/bssrdf.h @@ -364,10 +364,19 @@ ccl_device int bssrdf_setup(Bssrdf *bssrdf, ClosureType type) /* revert to diffuse BSDF if radius too small */ int flag; if (type == CLOSURE_BSSRDF_DISNEY_ID) { + float roughness = bssrdf->roughness; + float3 baseColor = bssrdf->baseColor; + float3 N = bssrdf->N; + float3 weight = bssrdf->weight; + float sample_weight = bssrdf->sample_weight; + DisneyDiffuseBsdf *bsdf = (DisneyDiffuseBsdf*)bssrdf; - bsdf->N = bssrdf->N; - bsdf->roughness = bssrdf->roughness; - bsdf->baseColor = bssrdf->baseColor; + + bsdf->N = N; + bsdf->roughness = roughness; + bsdf->baseColor = baseColor; + bsdf->weight = weight; + bsdf->sample_weight = sample_weight; flag = bsdf_disney_diffuse_setup(bsdf); bsdf->type = CLOSURE_BSDF_BSSRDF_DISNEY_ID; } diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp index 9711f914ef2..4418da3223c 100644 --- a/intern/cycles/kernel/osl/osl_closures.cpp +++ b/intern/cycles/kernel/osl/osl_closures.cpp @@ -192,16 +192,16 @@ BSDF_CLOSURE_CLASS_BEGIN(DisneySheen, disney_sheen, DisneySheenBsdf, LABEL_DIFFU CLOSURE_FLOAT_PARAM(DisneySheenClosure, params.sheenTint), BSDF_CLOSURE_CLASS_END(DisneySheen, disney_sheen) -BSDF_CLOSURE_CLASS_BEGIN(DisneySpecular, disney_specular, DisneySpecularBsdf, LABEL_GLOSSY | LABEL_REFLECT) +/*BSDF_CLOSURE_CLASS_BEGIN(DisneySpecular, disney_specular, DisneySpecularBsdf, LABEL_GLOSSY | LABEL_REFLECT) CLOSURE_FLOAT3_PARAM(DisneySpecularClosure, params.N), CLOSURE_FLOAT3_PARAM(DisneySpecularClosure, params.T), - CLOSURE_FLOAT3_PARAM(DisneySpecularClosure, params.baseColor), + CLOSURE_FLOAT3_PARAM(DisneySpecularClosure, params.extra->baseColor), CLOSURE_FLOAT_PARAM(DisneySpecularClosure, params.metallic), CLOSURE_FLOAT_PARAM(DisneySpecularClosure, params.specular), CLOSURE_FLOAT_PARAM(DisneySpecularClosure, params.specularTint), CLOSURE_FLOAT_PARAM(DisneySpecularClosure, params.roughness), CLOSURE_FLOAT_PARAM(DisneySpecularClosure, params.anisotropic), -BSDF_CLOSURE_CLASS_END(DisneySpecular, disney_specular) +BSDF_CLOSURE_CLASS_END(DisneySpecular, disney_specular)*/ BSDF_CLOSURE_CLASS_BEGIN(DisneyClearcoat, disney_clearcoat, DisneyClearcoatBsdf, LABEL_GLOSSY|LABEL_REFLECT) CLOSURE_FLOAT3_PARAM(DisneyClearcoatClosure, params.N), @@ -363,59 +363,49 @@ CCLOSURE_PREPARE(bsdf_disney_sheen_prepare, DisneySheenClosure) */ /* DISNEY SPECULAR */ -/*class DisneySpecularClosure : public CBSDFClosure { +class DisneySpecularClosure : public CBSDFClosure { public: - DisneySpecularClosure() : CBSDFClosure(LABEL_REFLECT | LABEL_GLOSSY) - {} - - void setup() - { - sc.prim = this; - m_shaderdata_flag = bsdf_disney_specular_setup(&sc); - } - - void blur(float roughness) - { - } + DisneySpecularBsdf params; - float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float& pdf) const + DisneySpecularBsdf *alloc(ShaderData *sd, int path_flag, float3 weight) { - return bsdf_disney_specular_eval_reflect(&sc, omega_out, omega_in, &pdf); - } + if (!skip(sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { + DisneySpecularBsdf *bsdf = (DisneySpecularBsdf*)bsdf_alloc_osl(sd, sizeof(DisneySpecularBsdf), weight, ¶ms); + DisneySpecularExtra *extra = (DisneySpecularExtra*)closure_alloc_extra(sd, sizeof(DisneySpecularExtra)); + if (bsdf && extra) { + bsdf->extra = extra; + return bsdf; + } + } - float3 eval_transmit(const float3 &omega_out, const float3 &omega_in, float& pdf) const - { - return bsdf_disney_specular_eval_transmit(&sc, omega_out, omega_in, &pdf); + return NULL; } - int sample(const float3 &Ng, const float3 &omega_out, const float3 &domega_out_dx, - const float3 &domega_out_dy, float randu, float randv, float3 &omega_in, - float3 &domega_in_dx, float3 &domega_in_dy, float &pdf, float3 &eval) const + void setup(ShaderData *sd, int path_flag, float3 weight) { - return bsdf_disney_specular_sample(&sc, Ng, omega_out, domega_out_dx, domega_out_dy, - randu, randv, &eval, &omega_in, &domega_in_dx, &domega_in_dy, &pdf); + DisneySpecularBsdf *bsdf = alloc(sd, path_flag, weight); + sd->flag |= (bsdf) ? bsdf_disney_specular_setup(bsdf) : 0; } }; -ClosureParam *bsdf_disney_specular_params() +ClosureParam *closure_bsdf_disney_specular_params() { static ClosureParam params[] = { - CLOSURE_FLOAT3_PARAM(DisneySpecularClosure, sc.N), - CLOSURE_FLOAT3_PARAM(DisneySpecularClosure, sc.T), - CLOSURE_FLOAT3_PARAM(DisneySpecularClosure, sc.color0), // base color - CLOSURE_FLOAT_PARAM(DisneySpecularClosure, sc.data0), // metallic - CLOSURE_FLOAT_PARAM(DisneySpecularClosure, sc.data1), // specular - CLOSURE_FLOAT_PARAM(DisneySpecularClosure, sc.data2), // specularTint - CLOSURE_FLOAT_PARAM(DisneySpecularClosure, sc.data3), // roughness - CLOSURE_FLOAT_PARAM(DisneySpecularClosure, sc.data4), // anisotropic + CLOSURE_FLOAT3_PARAM(DisneySpecularClosure, params.N), + CLOSURE_FLOAT3_PARAM(DisneySpecularClosure, params.extra->T), + CLOSURE_FLOAT3_PARAM(DisneySpecularClosure, params.extra->baseColor), + CLOSURE_FLOAT_PARAM(DisneySpecularClosure, params.metallic), + CLOSURE_FLOAT_PARAM(DisneySpecularClosure, params.specular), + CLOSURE_FLOAT_PARAM(DisneySpecularClosure, params.specularTint), + CLOSURE_FLOAT_PARAM(DisneySpecularClosure, params.roughness), + CLOSURE_FLOAT_PARAM(DisneySpecularClosure, params.anisotropic), CLOSURE_STRING_KEYPARAM(DisneySpecularClosure, label, "label"), CLOSURE_FINISH_PARAM(DisneySpecularClosure) }; return params; } +CCLOSURE_PREPARE(closure_bsdf_disney_specular_prepare, DisneySpecularClosure); -CCLOSURE_PREPARE(bsdf_disney_specular_prepare, DisneySpecularClosure) -*/ /* Registration */ @@ -487,7 +477,7 @@ void OSLShader::register_closures(OSLShadingSystem *ss_) register_closure(ss, "disney_sheen", id++, bsdf_disney_sheen_params(), bsdf_disney_sheen_prepare); register_closure(ss, "disney_specular", id++, - bsdf_disney_specular_params(), bsdf_disney_specular_prepare); + closure_bsdf_disney_specular_params(), closure_bsdf_disney_specular_prepare); register_closure(ss, "disney_clearcoat", id++, bsdf_disney_clearcoat_params(), bsdf_disney_clearcoat_prepare); diff --git a/intern/cycles/kernel/osl/osl_closures.h b/intern/cycles/kernel/osl/osl_closures.h index ae0ba7704aa..e924541a31d 100644 --- a/intern/cycles/kernel/osl/osl_closures.h +++ b/intern/cycles/kernel/osl/osl_closures.h @@ -62,6 +62,7 @@ OSL::ClosureParam *closure_bsdf_microfacet_ggx_aniso_fresnel_params(); OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_fresnel_params(); OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_glass_fresnel_params(); OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_aniso_fresnel_params(); +OSL::ClosureParam *closure_bsdf_disney_specular_params(); void closure_emission_prepare(OSL::RendererServices *, int id, void *data); void closure_background_prepare(OSL::RendererServices *, int id, void *data); @@ -83,6 +84,7 @@ void closure_bsdf_microfacet_ggx_aniso_fresnel_prepare(OSL::RendererServices *, void closure_bsdf_microfacet_multi_ggx_fresnel_prepare(OSL::RendererServices *, int id, void *data); void closure_bsdf_microfacet_multi_ggx_glass_fresnel_prepare(OSL::RendererServices *, int id, void *data); void closure_bsdf_microfacet_multi_ggx_aniso_fresnel_prepare(OSL::RendererServices *, int id, void *data); +void closure_bsdf_disney_specular_prepare(OSL::RendererServices *, int id, void *data); #define CCLOSURE_PREPARE(name, classname) \ void name(RendererServices *, int id, void *data) \ diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h index dada2a0786f..d3ed0bd1982 100644 --- a/intern/cycles/kernel/svm/svm_closure.h +++ b/intern/cycles/kernel/svm/svm_closure.h @@ -265,7 +265,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * bsdf->extra->color = baseColor; /* setup bsdf */ - if (distribution == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID) + if (distribution == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID && roughness > 0.075f) ccl_fetch(sd, flag) |= bsdf_microfacet_multi_ggx_aniso_setup(bsdf, true); else ccl_fetch(sd, flag) |= bsdf_microfacet_ggx_aniso_setup(bsdf, true); @@ -284,27 +284,11 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * float3 cspec0 = baseColor * specularTint + make_float3(1.0f, 1.0f, 1.0f) * (1.0f - specularTint); bool frontfacing = (ccl_fetch(sd, flag) & SD_BACKFACING) == 0; - if (distribution == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID) { - MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), glass_weight); - MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra)); - - if (bsdf && extra) { - bsdf->N = N; - bsdf->extra = extra; - bsdf->T = make_float3(0.0f, 0.0f, 0.0f); - - bsdf->alpha_x = roughness * roughness; - bsdf->alpha_y = roughness * roughness; - bsdf->ior = ior; + if (roughness <= 5e-2f || distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID) { + float refl_roughness = roughness; + if (roughness <= 1e-2f) + refl_roughness = 0.0f; - bsdf->extra->color = baseColor; - bsdf->extra->cspec0 = cspec0; - - /* setup bsdf */ - ccl_fetch(sd, flag) |= bsdf_microfacet_multi_ggx_glass_setup(bsdf, true, frontfacing); - } - } - else { /* reflection */ #ifdef __CAUSTICS_TRICKS__ if (kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) @@ -317,14 +301,17 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * bsdf->N = N; bsdf->extra = extra; - bsdf->alpha_x = roughness * roughness; - bsdf->alpha_y = roughness * roughness; + bsdf->alpha_x = refl_roughness * refl_roughness; + bsdf->alpha_y = refl_roughness * refl_roughness; bsdf->ior = ior; bsdf->extra->color = baseColor; bsdf->extra->cspec0 = cspec0; - ccl_fetch(sd, flag) |= bsdf_microfacet_ggx_setup(bsdf, true); + if (refl_roughness == 0.0f) + ccl_fetch(sd, flag) |= bsdf_reflection_setup(bsdf, true); + else + ccl_fetch(sd, flag) |= bsdf_microfacet_ggx_setup(bsdf, true); } } @@ -333,14 +320,17 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * if (kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0) #endif { - MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), glass_weight*(1.0f - fresnel)); + MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), baseColor*glass_weight*(1.0f - fresnel)); MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra)); if (bsdf && extra) { bsdf->N = N; bsdf->extra = extra; - refraction_roughness = 1.0f - (1.0f - roughness) * (1.0f - refraction_roughness); + if (distribution == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID) + refraction_roughness = roughness; + else + refraction_roughness = 1.0f - (1.0f - roughness) * (1.0f - refraction_roughness); bsdf->alpha_x = refraction_roughness * refraction_roughness; bsdf->alpha_y = refraction_roughness * refraction_roughness; @@ -349,10 +339,30 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * bsdf->extra->color = baseColor; bsdf->extra->cspec0 = cspec0; - ccl_fetch(sd, flag) |= bsdf_microfacet_ggx_refraction_setup(bsdf, true); + ccl_fetch(sd, flag) |= bsdf_microfacet_ggx_refraction_setup(bsdf); } } } + else { + MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), glass_weight); + MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra)); + + if (bsdf && extra) { + bsdf->N = N; + bsdf->extra = extra; + bsdf->T = make_float3(0.0f, 0.0f, 0.0f); + + bsdf->alpha_x = roughness * roughness; + bsdf->alpha_y = roughness * roughness; + bsdf->ior = ior; + + bsdf->extra->color = baseColor; + bsdf->extra->cspec0 = cspec0; + + /* setup bsdf */ + ccl_fetch(sd, flag) |= bsdf_microfacet_multi_ggx_glass_setup(bsdf, true, frontfacing); + } + } } #ifdef __CAUSTICS_TRICKS__ } |