Switching between OSL and SVM is more consistant now when using Disney

BSDF.

There were some minor differences in the OSL implementation, e.g. the
refraction roughness was missing.
This commit is contained in:
2016-10-20 10:01:45 +02:00
parent 2a5ac50922
commit 243a0e3eb8
3 changed files with 58 additions and 40 deletions

View File

@@ -276,7 +276,7 @@ ccl_device float3 MF_FUNCTION_FULL_NAME(mf_sample)(float3 wi, float3 *wo, const
float FH = (fresnel_dielectric_cos(dot(wi, normalize(wi + wr)), eta) - F0) * F0_norm; //schlick_fresnel(dot(wi, normalize(wi + wr))); // float FH = (fresnel_dielectric_cos(dot(wi, normalize(wi + wr)), eta) - F0) * F0_norm; //schlick_fresnel(dot(wi, normalize(wi + wr))); //
throughput2 = cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH; throughput2 = cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH;
} }
#else defined(MF_MULTI_GLOSSY) #elif defined(MF_MULTI_GLOSSY)
float3 t_color = cspec0; float3 t_color = cspec0;
float3 throughput2 = make_float3(1.0f, 1.0f, 1.0f); float3 throughput2 = make_float3(1.0f, 1.0f, 1.0f);
float F0 = fresnel_dielectric_cos(1.0f, eta); float F0 = fresnel_dielectric_cos(1.0f, eta);

View File

@@ -18,9 +18,9 @@
#include "node_fresnel.h" #include "node_fresnel.h"
shader node_disney_bsdf( shader node_disney_bsdf(
string distribution = "Multiscatter GGX", string distribution = "Multiscatter GGX",
color BaseColor = color(0.64555527, 0.41514809, 0.01698805), color BaseColor = color(0.64555527, 0.41514809, 0.01698805),
color SubsurfaceColor = color(0.64555527, 0.41514809, 0.01698805), color SubsurfaceColor = color(0.64555527, 0.41514809, 0.01698805),
float Metallic = 0.0, float Metallic = 0.0,
float Subsurface = 0.0, float Subsurface = 0.0,
float Specular = 0.5, float Specular = 0.5,
@@ -33,16 +33,23 @@ shader node_disney_bsdf(
float ClearcoatGloss = 1.0, float ClearcoatGloss = 1.0,
float IOR = 1.45, float IOR = 1.45,
float Transparency = 0.0, float Transparency = 0.0,
float RefractionRoughness = 0.0,
float AnisotropicRotation = 0.0, float AnisotropicRotation = 0.0,
normal Normal = N, normal Normal = N,
normal ClearcoatNormal = N, normal ClearcoatNormal = N,
normal Tangent = normalize(dPdu), normal Tangent = normalize(dPdu),
output closure color BSDF = 0) output closure color BSDF = 0)
{ {
float f = max(IOR, 1e-5); float f = max(IOR, 1e-5);
float diffuse_weight = (1.0 - clamp(Metallic, 0.0, 1.0)) * (1.0 - clamp(Transparency, 0.0, 1.0)); float diffuse_weight = (1.0 - clamp(Metallic, 0.0, 1.0)) * (1.0 - clamp(Transparency, 0.0, 1.0));
float transp = clamp(Transparency, 0.0, 1.0) * (1.0 - clamp(Metallic, 0.0, 1.0)); float transp = clamp(Transparency, 0.0, 1.0) * (1.0 - clamp(Metallic, 0.0, 1.0));
float specular_weight = (1.0 - transp); float specular_weight = (1.0 - transp);
vector T = Tangent;
/* rotate tangent */
if (AnisotropicRotation != 0.0)
T = rotate(T, AnisotropicRotation * M_2PI, point(0.0, 0.0, 0.0), Normal);
if (diffuse_weight > 1e-5) { if (diffuse_weight > 1e-5) {
if (Subsurface > 1e-5) { if (Subsurface > 1e-5) {
@@ -51,7 +58,7 @@ shader node_disney_bsdf(
BSDF = disney_diffuse(Normal, BaseColor, Roughness); BSDF = disney_diffuse(Normal, BaseColor, Roughness);
} }
if (Sheen != 0.0) { if (Sheen > 1e-5) {
BSDF = BSDF + disney_sheen(Normal, BaseColor, Sheen, SheenTint); BSDF = BSDF + disney_sheen(Normal, BaseColor, Sheen, SheenTint);
} }
@@ -71,10 +78,10 @@ shader node_disney_bsdf(
color Cspec0 = (Specular * 0.08 * tmp_col) * (1.0 - Metallic) + BaseColor * Metallic; color Cspec0 = (Specular * 0.08 * tmp_col) * (1.0 - Metallic) + BaseColor * Metallic;
if (distribution == "Multiscatter GGX") { if (distribution == "GGX" || Roughness <= 0.075) {
BSDF = BSDF + specular_weight * microfacet_multi_ggx_aniso_fresnel(Normal, Tangent, alpha_x, alpha_y, (2.0 / (1.0 - sqrt(0.08 * Specular))) - 1.0, BaseColor, Cspec0); BSDF = BSDF + specular_weight * microfacet_ggx_aniso_fresnel(Normal, T, alpha_x, alpha_y, (2.0 / (1.0 - sqrt(0.08 * Specular))) - 1.0, BaseColor, Cspec0);
} else { } else {
BSDF = BSDF + specular_weight * microfacet_ggx_aniso_fresnel(Normal, Tangent, alpha_x, alpha_y, (2.0 / (1.0 - sqrt(0.08 * Specular))) - 1.0, BaseColor, Cspec0); BSDF = BSDF + specular_weight * microfacet_multi_ggx_aniso_fresnel(Normal, T, alpha_x, alpha_y, (2.0 / (1.0 - sqrt(0.08 * Specular))) - 1.0, BaseColor, Cspec0);
} }
} }
@@ -82,19 +89,27 @@ shader node_disney_bsdf(
color Cspec0 = BaseColor * SpecularTint + color(1.0, 1.0, 1.0) * (1.0 - SpecularTint); color Cspec0 = BaseColor * SpecularTint + color(1.0, 1.0, 1.0) * (1.0 - SpecularTint);
float eta = backfacing() ? 1.0 / f : f; float eta = backfacing() ? 1.0 / f : f;
if (distribution == "Multiscatter GGX") { if (distribution == "GGX" || Roughness <= 5e-2) {
BSDF = BSDF + transp * microfacet_multi_ggx_glass_fresnel(Normal, Roughness * Roughness, eta, BaseColor, Cspec0);
} else {
float cosNO = dot(Normal, I); float cosNO = dot(Normal, I);
float Fr = fresnel_dielectric_cos(cosNO, eta); float Fr = fresnel_dielectric_cos(cosNO, eta);
float refl_roughness = Roughness;
if (Roughness <= 1e-2)
refl_roughness = 0.0;
float refraction_roughness = refl_roughness;
if (distribution == "GGX")
refraction_roughness = 1.0 - (1.0 - refl_roughness) * (1.0 - RefractionRoughness);
BSDF = BSDF + transp * (Fr * microfacet_ggx_fresnel(Normal, Roughness * Roughness, eta, BaseColor, Cspec0) + BSDF = BSDF + transp * (Fr * microfacet_ggx_fresnel(Normal, refl_roughness * refl_roughness, eta, BaseColor, Cspec0) +
(1.0 - Fr) * BaseColor * microfacet_ggx_refraction(Normal, Roughness * Roughness, eta)); (1.0 - Fr) * BaseColor * microfacet_ggx_refraction(Normal, refraction_roughness * refraction_roughness, eta));
} else {
BSDF = BSDF + transp * microfacet_multi_ggx_glass_fresnel(Normal, Roughness * Roughness, eta, BaseColor, Cspec0);
} }
} }
if (Clearcoat > 1e-5) { if (Clearcoat > 1e-5) {
BSDF = BSDF + 0.25 * Clearcoat * disney_clearcoat(Normal, Clearcoat, ClearcoatGloss); BSDF = BSDF + 0.25 * Clearcoat * disney_clearcoat(ClearcoatNormal, Clearcoat, ClearcoatGloss);
} }
} }

View File

@@ -153,7 +153,6 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
/* diffuse */ /* diffuse */
if (diffuse_weight > CLOSURE_WEIGHT_CUTOFF && fabsf(average(baseColor)) > CLOSURE_WEIGHT_CUTOFF) { if (diffuse_weight > CLOSURE_WEIGHT_CUTOFF && fabsf(average(baseColor)) > CLOSURE_WEIGHT_CUTOFF) {
float3 diff_weight = weight * diffuse_weight; float3 diff_weight = weight * diffuse_weight;
float diff_sample_weight = fabsf(average(diff_weight));
DisneyDiffuseBsdf *bsdf = (DisneyDiffuseBsdf*)bsdf_alloc(sd, sizeof(DisneyDiffuseBsdf), diff_weight); DisneyDiffuseBsdf *bsdf = (DisneyDiffuseBsdf*)bsdf_alloc(sd, sizeof(DisneyDiffuseBsdf), diff_weight);
@@ -186,6 +185,8 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
bssrdf->N = N; bssrdf->N = N;
bssrdf->baseColor = baseColor; bssrdf->baseColor = baseColor;
bssrdf->roughness = roughness; bssrdf->roughness = roughness;
/* setup bsdf */
ccl_fetch(sd, flag) |= bssrdf_setup(bssrdf, (ClosureType)CLOSURE_BSSRDF_DISNEY_ID); ccl_fetch(sd, flag) |= bssrdf_setup(bssrdf, (ClosureType)CLOSURE_BSSRDF_DISNEY_ID);
} }
@@ -199,6 +200,8 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
bssrdf->N = N; bssrdf->N = N;
bssrdf->baseColor = baseColor; bssrdf->baseColor = baseColor;
bssrdf->roughness = roughness; bssrdf->roughness = roughness;
/* setup bsdf */
ccl_fetch(sd, flag) |= bssrdf_setup(bssrdf, (ClosureType)CLOSURE_BSSRDF_DISNEY_ID); ccl_fetch(sd, flag) |= bssrdf_setup(bssrdf, (ClosureType)CLOSURE_BSSRDF_DISNEY_ID);
} }
@@ -212,14 +215,15 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
bssrdf->N = N; bssrdf->N = N;
bssrdf->baseColor = baseColor; bssrdf->baseColor = baseColor;
bssrdf->roughness = roughness; bssrdf->roughness = roughness;
/* setup bsdf */
ccl_fetch(sd, flag) |= bssrdf_setup(bssrdf, (ClosureType)CLOSURE_BSSRDF_DISNEY_ID); ccl_fetch(sd, flag) |= bssrdf_setup(bssrdf, (ClosureType)CLOSURE_BSSRDF_DISNEY_ID);
} }
} }
#else #else
/* diffuse */ /* diffuse */
if (diffuse_weight > 0.0f) { if (diffuse_weight > CLOSURE_WEIGHT_CUTOFF) {
float3 diff_weight = weight * diffuse_weight; float3 diff_weight = weight * diffuse_weight;
float diff_sample_weight = fabsf(average(diff_weight));
DisneyDiffuseBsdf *bsdf = (DisneyDiffuseBsdf*)bsdf_alloc(sd, sizeof(DisneyDiffuseBsdf), diff_weight); DisneyDiffuseBsdf *bsdf = (DisneyDiffuseBsdf*)bsdf_alloc(sd, sizeof(DisneyDiffuseBsdf), diff_weight);
@@ -234,13 +238,11 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
} }
#endif #endif
float sheen_diffuse_weight = diffuse_weight * 1.0f + (1.0f - diffuse_weight) * transp;
/* sheen */ /* sheen */
if (sheen_diffuse_weight > CLOSURE_WEIGHT_CUTOFF && sheen > CLOSURE_WEIGHT_CUTOFF) { if (diffuse_weight > CLOSURE_WEIGHT_CUTOFF && sheen > CLOSURE_WEIGHT_CUTOFF) {
float3 sheen_weight = weight * sheen_diffuse_weight; float3 sheen_weight = weight * diffuse_weight;
float sheen_sample_weight = fabsf(average(sheen_weight));
DisneySheenBsdf *bsdf = (DisneySheenBsdf*)bsdf_alloc(sd, sizeof(DisneySheenBsdf), weight); DisneySheenBsdf *bsdf = (DisneySheenBsdf*)bsdf_alloc(sd, sizeof(DisneySheenBsdf), sheen_weight);
if (bsdf) { if (bsdf) {
bsdf->N = N; bsdf->N = N;
@@ -258,7 +260,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) { if (kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) {
#endif #endif
if (specular_weight > CLOSURE_WEIGHT_CUTOFF && (specular > CLOSURE_WEIGHT_CUTOFF || metallic > CLOSURE_WEIGHT_CUTOFF)) { if (specular_weight > CLOSURE_WEIGHT_CUTOFF && (specular > CLOSURE_WEIGHT_CUTOFF || metallic > CLOSURE_WEIGHT_CUTOFF)) {
float3 spec_weight = weight * specular_weight/* * (specular * (1.0f - metallic) + metallic)*/; float3 spec_weight = weight * specular_weight;
MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), spec_weight); MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), spec_weight);
MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra)); MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
@@ -279,14 +281,14 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
float3 m_ctint = m_cdlum > 0.0f ? baseColor / m_cdlum : make_float3(0.0f, 0.0f, 0.0f); // normalize lum. to isolate hue+sat float3 m_ctint = m_cdlum > 0.0f ? baseColor / m_cdlum : make_float3(0.0f, 0.0f, 0.0f); // normalize lum. to isolate hue+sat
float3 tmp_col = make_float3(1.0f, 1.0f, 1.0f) * (1.0f - specularTint) + m_ctint * specularTint; float3 tmp_col = make_float3(1.0f, 1.0f, 1.0f) * (1.0f - specularTint) + m_ctint * specularTint;
bsdf->extra->cspec0 = (/*fresnel_dielectric_cos(1.0f, ior)*/specular * 0.08f * tmp_col) * (1.0f - metallic) + baseColor * metallic; bsdf->extra->cspec0 = (specular * 0.08f * tmp_col) * (1.0f - metallic) + baseColor * metallic;
bsdf->extra->color = baseColor; bsdf->extra->color = baseColor;
/* setup bsdf */ /* setup bsdf */
if (distribution == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID && roughness > 0.075f) if (distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID || roughness <= 0.075f) /* use single-scatter GGX */
ccl_fetch(sd, flag) |= bsdf_microfacet_multi_ggx_aniso_setup(bsdf, true);
else
ccl_fetch(sd, flag) |= bsdf_microfacet_ggx_aniso_setup(bsdf, true); ccl_fetch(sd, flag) |= bsdf_microfacet_ggx_aniso_setup(bsdf, true);
else /* use multi-scatter GGX */
ccl_fetch(sd, flag) |= bsdf_microfacet_multi_ggx_aniso_setup(bsdf, true);
} }
} }
#ifdef __CAUSTICS_TRICKS__ #ifdef __CAUSTICS_TRICKS__
@@ -298,11 +300,11 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
if (kernel_data.integrator.caustics_reflective || kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0) { if (kernel_data.integrator.caustics_reflective || kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0) {
#endif #endif
if (transp > CLOSURE_WEIGHT_CUTOFF) { if (transp > CLOSURE_WEIGHT_CUTOFF) {
float3 glass_weight = /*baseColor */ weight * transp; float3 glass_weight = weight * transp;
float3 cspec0 = baseColor * specularTint + make_float3(1.0f, 1.0f, 1.0f) * (1.0f - specularTint); float3 cspec0 = baseColor * specularTint + make_float3(1.0f, 1.0f, 1.0f) * (1.0f - specularTint);
bool frontfacing = (ccl_fetch(sd, flag) & SD_BACKFACING) == 0; bool frontfacing = (ccl_fetch(sd, flag) & SD_BACKFACING) == 0;
if (roughness <= 5e-2f || distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID) { if (roughness <= 5e-2f || distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID) { /* use single-scatter GGX */
float refl_roughness = roughness; float refl_roughness = roughness;
if (roughness <= 1e-2f) if (roughness <= 1e-2f)
refl_roughness = 0.0f; refl_roughness = 0.0f;
@@ -326,6 +328,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
bsdf->extra->color = baseColor; bsdf->extra->color = baseColor;
bsdf->extra->cspec0 = cspec0; bsdf->extra->cspec0 = cspec0;
/* setup bsdf */
if (refl_roughness == 0.0f) if (refl_roughness == 0.0f)
ccl_fetch(sd, flag) |= bsdf_reflection_setup(bsdf, true); ccl_fetch(sd, flag) |= bsdf_reflection_setup(bsdf, true);
else else
@@ -345,10 +348,10 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
bsdf->N = N; bsdf->N = N;
bsdf->extra = extra; bsdf->extra = extra;
if (distribution == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID) if (distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID)
refraction_roughness = roughness; refraction_roughness = 1.0f - (1.0f - refl_roughness) * (1.0f - refraction_roughness);
else else
refraction_roughness = 1.0f - (1.0f - roughness) * (1.0f - refraction_roughness); refraction_roughness = refl_roughness;
bsdf->alpha_x = refraction_roughness * refraction_roughness; bsdf->alpha_x = refraction_roughness * refraction_roughness;
bsdf->alpha_y = refraction_roughness * refraction_roughness; bsdf->alpha_y = refraction_roughness * refraction_roughness;
@@ -357,11 +360,12 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
bsdf->extra->color = baseColor; bsdf->extra->color = baseColor;
bsdf->extra->cspec0 = cspec0; bsdf->extra->cspec0 = cspec0;
/* setup bsdf */
ccl_fetch(sd, flag) |= bsdf_microfacet_ggx_refraction_setup(bsdf); ccl_fetch(sd, flag) |= bsdf_microfacet_ggx_refraction_setup(bsdf);
} }
} }
} }
else { else { /* use multi-scatter GGX */
MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), glass_weight); MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), glass_weight);
MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra)); MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
@@ -392,7 +396,6 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
#endif #endif
if (clearcoat > CLOSURE_WEIGHT_CUTOFF) { if (clearcoat > CLOSURE_WEIGHT_CUTOFF) {
float3 clearcoat_weight = 0.25f * clearcoat * weight; float3 clearcoat_weight = 0.25f * clearcoat * weight;
float clearcoat_sample_weight = fabsf(average(clearcoat_weight));
MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), clearcoat_weight); MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), clearcoat_weight);
MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra)); MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));