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:
-rw-r--r--intern/cycles/blender/blender_shader.cpp8
-rw-r--r--intern/cycles/kernel/closure/bsdf.h18
-rw-r--r--intern/cycles/kernel/closure/bsdf_disney_diffuse.h164
-rw-r--r--intern/cycles/kernel/closure/bsdf_microfacet.h50
-rw-r--r--intern/cycles/kernel/closure/bssrdf.h4
-rw-r--r--intern/cycles/kernel/kernel_subsurface.h2
-rw-r--r--intern/cycles/kernel/osl/osl_bssrdf.cpp4
-rw-r--r--intern/cycles/kernel/osl/osl_closures.cpp16
-rw-r--r--intern/cycles/kernel/shaders/node_disney_bsdf.osl42
-rw-r--r--intern/cycles/kernel/shaders/stdosl.h6
-rw-r--r--intern/cycles/kernel/svm/svm_closure.h92
-rw-r--r--intern/cycles/kernel/svm/svm_types.h8
-rw-r--r--intern/cycles/render/graph.cpp2
-rw-r--r--intern/cycles/render/nodes.cpp33
-rw-r--r--intern/cycles/render/nodes.h11
m---------release/datafiles/locale0
m---------release/scripts/addons0
m---------release/scripts/addons_contrib0
-rw-r--r--source/blender/editors/space_node/drawnode.c10
-rw-r--r--source/blender/makesdna/DNA_node_types.h4
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c12
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_disney.c43
22 files changed, 436 insertions, 93 deletions
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index cb50b741567..6f6a4d0b434 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -528,6 +528,14 @@ static ShaderNode *add_node(Scene *scene,
disney->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID;
break;
}
+ switch (b_disney_node.surface_type()) {
+ case BL::ShaderNodeBsdfDisney::surface_type_THIN_SURFACE:
+ disney->surface_type = THIN_SURFACE;
+ break;
+ case BL::ShaderNodeBsdfDisney::surface_type_SOLID_SURFACE:
+ disney->surface_type = SOLID_SURFACE;
+ break;
+ }
node = disney;
}
else if(b_node.is_a(&RNA_ShaderNodeBsdfTranslucent)) {
diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h
index b46f6a7f1c5..41ea7864d1c 100644
--- a/intern/cycles/kernel/closure/bsdf.h
+++ b/intern/cycles/kernel/closure/bsdf.h
@@ -93,6 +93,7 @@ ccl_device_forceinline int bsdf_sample(KernelGlobals *kg,
case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
case CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_THIN_ID:
label = bsdf_microfacet_ggx_sample(kg, sc, ccl_fetch(sd, Ng), ccl_fetch(sd, I), ccl_fetch(sd, dI).dx, ccl_fetch(sd, dI).dy, randu, randv,
eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
@@ -138,10 +139,15 @@ ccl_device_forceinline int bsdf_sample(KernelGlobals *kg,
eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
case CLOSURE_BSDF_DISNEY_DIFFUSE_ID:
+ case CLOSURE_BSDF_DISNEY_DIFFUSE_TRANSMIT_ID:
case CLOSURE_BSDF_BSSRDF_DISNEY_ID:
label = bsdf_disney_diffuse_sample(sc, ccl_fetch(sd, Ng), ccl_fetch(sd, I), ccl_fetch(sd, dI).dx, ccl_fetch(sd, dI).dy, randu, randv,
eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
+ case CLOSURE_BSDF_DISNEY_RETRO_REFLECTION_ID:
+ label = bsdf_disney_retro_reflection_sample(sc, ccl_fetch(sd, Ng), ccl_fetch(sd, I), ccl_fetch(sd, dI).dx, ccl_fetch(sd, dI).dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ break;
case CLOSURE_BSDF_DISNEY_SHEEN_ID:
label = bsdf_disney_sheen_sample(sc, ccl_fetch(sd, Ng), ccl_fetch(sd, I), ccl_fetch(sd, dI).dx, ccl_fetch(sd, dI).dy, randu, randv,
eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
@@ -209,6 +215,7 @@ float3 bsdf_eval(KernelGlobals *kg,
case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
case CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_THIN_ID:
eval = bsdf_microfacet_ggx_eval_reflect(sc, ccl_fetch(sd, I), omega_in, pdf);
break;
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
@@ -244,9 +251,13 @@ float3 bsdf_eval(KernelGlobals *kg,
eval = bsdf_hair_transmission_eval_reflect(sc, ccl_fetch(sd, I), omega_in, pdf);
break;
case CLOSURE_BSDF_DISNEY_DIFFUSE_ID:
+ case CLOSURE_BSDF_DISNEY_DIFFUSE_TRANSMIT_ID:
case CLOSURE_BSDF_BSSRDF_DISNEY_ID:
eval = bsdf_disney_diffuse_eval_reflect(sc, ccl_fetch(sd, I), omega_in, pdf);
break;
+ case CLOSURE_BSDF_DISNEY_RETRO_REFLECTION_ID:
+ eval = bsdf_disney_retro_reflection_eval_reflect(sc, ccl_fetch(sd, I), omega_in, pdf);
+ break;
case CLOSURE_BSDF_DISNEY_SHEEN_ID:
eval = bsdf_disney_sheen_eval_reflect(sc, ccl_fetch(sd, I), omega_in, pdf);
break;
@@ -289,6 +300,7 @@ float3 bsdf_eval(KernelGlobals *kg,
case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
case CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_THIN_ID:
eval = bsdf_microfacet_ggx_eval_transmit(sc, ccl_fetch(sd, I), omega_in, pdf);
break;
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
@@ -324,9 +336,13 @@ float3 bsdf_eval(KernelGlobals *kg,
eval = bsdf_hair_transmission_eval_transmit(sc, ccl_fetch(sd, I), omega_in, pdf);
break;
case CLOSURE_BSDF_DISNEY_DIFFUSE_ID:
+ case CLOSURE_BSDF_DISNEY_DIFFUSE_TRANSMIT_ID:
case CLOSURE_BSDF_BSSRDF_DISNEY_ID:
eval = bsdf_disney_diffuse_eval_transmit(sc, ccl_fetch(sd, I), omega_in, pdf);
break;
+ case CLOSURE_BSDF_DISNEY_RETRO_REFLECTION_ID:
+ eval = bsdf_disney_retro_reflection_eval_transmit(sc, ccl_fetch(sd, I), omega_in, pdf);
+ break;
case CLOSURE_BSDF_DISNEY_SHEEN_ID:
eval = bsdf_disney_sheen_eval_transmit(sc, ccl_fetch(sd, I), omega_in, pdf);
break;
@@ -362,6 +378,7 @@ ccl_device void bsdf_blur(KernelGlobals *kg, ShaderClosure *sc, float roughness)
case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
case CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_THIN_ID:
bsdf_microfacet_ggx_blur(sc, roughness);
break;
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
@@ -399,6 +416,7 @@ ccl_device bool bsdf_merge(ShaderClosure *a, ShaderClosure *b)
case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
case CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_THIN_ID:
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
diff --git a/intern/cycles/kernel/closure/bsdf_disney_diffuse.h b/intern/cycles/kernel/closure/bsdf_disney_diffuse.h
index ccb5966db1a..a76be38758a 100644
--- a/intern/cycles/kernel/closure/bsdf_disney_diffuse.h
+++ b/intern/cycles/kernel/closure/bsdf_disney_diffuse.h
@@ -27,51 +27,174 @@ CCL_NAMESPACE_BEGIN
typedef ccl_addr_space struct DisneyDiffuseBsdf {
SHADER_CLOSURE_BASE;
- float roughness;
+ float roughness, flatness;
float3 N;
} DisneyDiffuseBsdf;
+
+/* DIFFUSE */
+
ccl_device float3 calculate_disney_diffuse_brdf(const DisneyDiffuseBsdf *bsdf,
- float3 N, float3 V, float3 L, float3 H, float *pdf)
+ float NdotL, float NdotV, float LdotH)
+{
+ float FL = schlick_fresnel(NdotL), FV = schlick_fresnel(NdotV);
+ float Fd = (1.0f - 0.5f * FL) * (1.0f - 0.5f * FV);
+
+ float ss = 0.0f;
+ if(bsdf->flatness > 0.0f) {
+ // Based on Hanrahan-Krueger BRDF approximation of isotropic BSSRDF
+ // 1.25 scale is used to (roughly) preserve albedo
+ // Fss90 used to "flatten" retro-reflection based on roughness
+ float Fss90 = LdotH*LdotH * bsdf->roughness;
+ float Fss = (1.0f + (Fss90 - 1.0f) * FL) * (1.0f + (Fss90 - 1.0f) * FV);
+ ss = 1.25f * (Fss * (1.0f / (NdotL + NdotV) - 0.5f) + 0.5f);
+ }
+
+ float value = Fd + (ss - Fd) * bsdf->flatness;
+ value *= M_1_PI_F * NdotL;
+
+ return make_float3(value, value, value);
+}
+
+ccl_device int bsdf_disney_diffuse_setup(DisneyDiffuseBsdf *bsdf)
+{
+ bsdf->type = CLOSURE_BSDF_DISNEY_DIFFUSE_ID;
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
+}
+
+ccl_device int bsdf_disney_diffuse_transmit_setup(DisneyDiffuseBsdf *bsdf)
+{
+ bsdf->type = CLOSURE_BSDF_DISNEY_DIFFUSE_TRANSMIT_ID;
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
+}
+
+ccl_device float3 bsdf_disney_diffuse_eval_reflect(const ShaderClosure *sc, const float3 I,
+ const float3 omega_in, float *pdf)
+{
+ const DisneyDiffuseBsdf *bsdf = (const DisneyDiffuseBsdf *)sc;
+ bool m_transmittance = bsdf->type == CLOSURE_BSDF_DISNEY_DIFFUSE_TRANSMIT_ID;
+
+ if(m_transmittance)
+ return make_float3(0.0f, 0.0f, 0.0f);
+
+ float3 N = bsdf->N;
+
+ if(dot(N, omega_in) > 0.0f) {
+ float3 H = normalize(I + omega_in);
+
+ *pdf = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F;
+ return calculate_disney_diffuse_brdf(bsdf, fmaxf(dot(N, omega_in), 0.0f), fmaxf(dot(N, I), 0.0f), dot(omega_in, H));
+ }
+ else {
+ *pdf = 0.0f;
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
+}
+
+ccl_device float3 bsdf_disney_diffuse_eval_transmit(const ShaderClosure *sc, const float3 I,
+ const float3 omega_in, float *pdf)
{
- float NdotL = max(dot(N, L), 0.0f);
- float NdotV = max(dot(N, V), 0.0f);
+ const DisneyDiffuseBsdf *bsdf = (const DisneyDiffuseBsdf *)sc;
+ bool m_transmittance = bsdf->type == CLOSURE_BSDF_DISNEY_DIFFUSE_TRANSMIT_ID;
- if(NdotL < 0 || NdotV < 0) {
+ if(!m_transmittance)
+ return make_float3(0.0f, 0.0f, 0.0f);
+
+ float3 N = bsdf->N;
+
+ if(dot(-N, omega_in) > 0.0f) {
+ float3 H = normalize(I + omega_in);
+
+ *pdf = fmaxf(dot(-N, omega_in), 0.0f) * M_1_PI_F;
+ return calculate_disney_diffuse_brdf(bsdf, fmaxf(dot(-N, omega_in), 0.0f), fmaxf(dot(N, I), 0.0f), dot(omega_in, H));
+ }
+ else {
*pdf = 0.0f;
return make_float3(0.0f, 0.0f, 0.0f);
}
+}
+
+ccl_device int bsdf_disney_diffuse_sample(const ShaderClosure *sc,
+ float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv,
+ float3 *eval, float3 *omega_in, float3 *domega_in_dx,
+ float3 *domega_in_dy, float *pdf)
+{
+ const DisneyDiffuseBsdf *bsdf = (const DisneyDiffuseBsdf *)sc;
+ bool m_transmittance = bsdf->type == CLOSURE_BSDF_DISNEY_DIFFUSE_TRANSMIT_ID;
+
+ float3 N = bsdf->N;
+
+ if(m_transmittance) {
+ sample_uniform_hemisphere(-N, randu, randv, omega_in, pdf);
+ }
+ else {
+ sample_cos_hemisphere(N, randu, randv, omega_in, pdf);
+ }
+
+ if(m_transmittance && dot(-Ng, *omega_in) > 0) {
+ float3 I_t = -((2 * dot(N, I)) * N - I);
+ float3 H = normalize(I_t + *omega_in);
+
+ *eval = calculate_disney_diffuse_brdf(bsdf, fmaxf(dot(-N, *omega_in), 0.0f), fmaxf(dot(N, I), 0.0f), dot(*omega_in, H));
+
+#ifdef __RAY_DIFFERENTIALS__
+ // TODO: find a better approximation for the diffuse bounce
+ *domega_in_dx = -((2 * dot(N, dIdx)) * N - dIdx);
+ *domega_in_dy = -((2 * dot(N, dIdy)) * N - dIdy);
+#endif
+ }
+ else if(!m_transmittance && dot(Ng, *omega_in) > 0) {
+ float3 H = normalize(I + *omega_in);
+
+ *eval = calculate_disney_diffuse_brdf(bsdf, fmaxf(dot(N, *omega_in), 0.0f), fmaxf(dot(N, I), 0.0f), dot(*omega_in, H));
+
+#ifdef __RAY_DIFFERENTIALS__
+ // TODO: find a better approximation for the diffuse bounce
+ *domega_in_dx = -((2 * dot(N, dIdx)) * N - dIdx);
+ *domega_in_dy = -((2 * dot(N, dIdy)) * N - dIdy);
+#endif
+ }
+ else {
+ *pdf = 0.0f;
+ }
- float LdotH = dot(L, H);
+ return (m_transmittance) ? LABEL_TRANSMIT|LABEL_DIFFUSE : LABEL_REFLECT|LABEL_DIFFUSE;
+}
+
+
+/* RETRO-REFLECTION */
+ccl_device float3 calculate_retro_reflection(const DisneyDiffuseBsdf *bsdf,
+ float NdotL, float NdotV, float LdotH)
+{
float FL = schlick_fresnel(NdotL), FV = schlick_fresnel(NdotV);
- const float Fd90 = 0.5f + 2.0f * LdotH*LdotH * bsdf->roughness;
- float Fd = (1.0f * (1.0f - FL) + Fd90 * FL) * (1.0f * (1.0f - FV) + Fd90 * FV);
+ float RR = 2.0f * bsdf->roughness * LdotH*LdotH;
+
+ float FRR = RR * (FL + FV + FL * FV * (RR - 1.0f));
- float value = M_1_PI_F * NdotL * Fd;
+ float value = M_1_PI_F * FRR * NdotL;
return make_float3(value, value, value);
}
-ccl_device int bsdf_disney_diffuse_setup(DisneyDiffuseBsdf *bsdf)
+ccl_device int bsdf_disney_retro_reflection_setup(DisneyDiffuseBsdf *bsdf)
{
- bsdf->type = CLOSURE_BSDF_DISNEY_DIFFUSE_ID;
+ bsdf->type = CLOSURE_BSDF_DISNEY_RETRO_REFLECTION_ID;
return SD_BSDF|SD_BSDF_HAS_EVAL;
}
-ccl_device float3 bsdf_disney_diffuse_eval_reflect(const ShaderClosure *sc, const float3 I,
+ccl_device float3 bsdf_disney_retro_reflection_eval_reflect(const ShaderClosure *sc, const float3 I,
const float3 omega_in, float *pdf)
{
const DisneyDiffuseBsdf *bsdf = (const DisneyDiffuseBsdf *)sc;
float3 N = bsdf->N;
- float3 V = I; // outgoing
- float3 L = omega_in; // incoming
- float3 H = normalize(L + V);
if(dot(N, omega_in) > 0.0f) {
+ float3 H = normalize(I + omega_in);
+
*pdf = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F;
- return calculate_disney_diffuse_brdf(bsdf, N, V, L, H, pdf);
+ return calculate_retro_reflection(bsdf, fmaxf(dot(N, omega_in), 0.0f), fmaxf(dot(N, I), 0.0f), dot(omega_in, H));
}
else {
*pdf = 0.0f;
@@ -79,13 +202,13 @@ ccl_device float3 bsdf_disney_diffuse_eval_reflect(const ShaderClosure *sc, cons
}
}
-ccl_device float3 bsdf_disney_diffuse_eval_transmit(const ShaderClosure *sc, const float3 I,
+ccl_device float3 bsdf_disney_retro_reflection_eval_transmit(const ShaderClosure *sc, const float3 I,
const float3 omega_in, float *pdf)
{
return make_float3(0.0f, 0.0f, 0.0f);
}
-ccl_device int bsdf_disney_diffuse_sample(const ShaderClosure *sc,
+ccl_device int bsdf_disney_retro_reflection_sample(const ShaderClosure *sc,
float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv,
float3 *eval, float3 *omega_in, float3 *domega_in_dx,
float3 *domega_in_dy, float *pdf)
@@ -94,12 +217,12 @@ ccl_device int bsdf_disney_diffuse_sample(const ShaderClosure *sc,
float3 N = bsdf->N;
- sample_cos_hemisphere(N, randu, randv, omega_in, pdf);
+ sample_uniform_hemisphere(N, randu, randv, omega_in, pdf);
if(dot(Ng, *omega_in) > 0) {
float3 H = normalize(I + *omega_in);
- *eval = calculate_disney_diffuse_brdf(bsdf, N, I, *omega_in, H, pdf);
+ *eval = calculate_retro_reflection(bsdf, fmaxf(dot(N, *omega_in), 0.0f), fmaxf(dot(N, I), 0.0f), dot(*omega_in, H));
#ifdef __RAY_DIFFERENTIALS__
// TODO: find a better approximation for the diffuse bounce
@@ -110,6 +233,7 @@ ccl_device int bsdf_disney_diffuse_sample(const ShaderClosure *sc,
else {
*pdf = 0.0f;
}
+
return LABEL_REFLECT|LABEL_DIFFUSE;
}
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h
index 38364bb1026..81ecfd0ebd3 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet.h
@@ -370,6 +370,18 @@ ccl_device int bsdf_microfacet_ggx_refraction_setup(MicrofacetBsdf *bsdf)
return SD_BSDF|SD_BSDF_HAS_EVAL;
}
+ccl_device int bsdf_microfacet_ggx_refraction_thin_setup(MicrofacetBsdf *bsdf)
+{
+ bsdf->extra = NULL;
+
+ bsdf->alpha_x = saturate(bsdf->alpha_x);
+ bsdf->alpha_y = bsdf->alpha_x;
+
+ bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_THIN_ID;
+
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
+}
+
ccl_device void bsdf_microfacet_ggx_blur(ShaderClosure *sc, float roughness)
{
MicrofacetBsdf *bsdf = (MicrofacetBsdf*)sc;
@@ -383,7 +395,7 @@ ccl_device float3 bsdf_microfacet_ggx_eval_reflect(const ShaderClosure *sc, cons
const MicrofacetBsdf *bsdf = (const MicrofacetBsdf*)sc;
float alpha_x = bsdf->alpha_x;
float alpha_y = bsdf->alpha_y;
- bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
+ bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID || bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_THIN_ID;
float3 N = bsdf->N;
if(m_refractive || alpha_x*alpha_y <= 1e-7f)
@@ -494,7 +506,7 @@ ccl_device float3 bsdf_microfacet_ggx_eval_transmit(const ShaderClosure *sc, con
float alpha_x = bsdf->alpha_x;
float alpha_y = bsdf->alpha_y;
float m_eta = bsdf->ior;
- bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
+ bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID || bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_THIN_ID;
float3 N = bsdf->N;
if(!m_refractive || alpha_x*alpha_y <= 1e-7f)
@@ -507,7 +519,15 @@ ccl_device float3 bsdf_microfacet_ggx_eval_transmit(const ShaderClosure *sc, con
return make_float3(0.0f, 0.0f, 0.0f); /* vectors on same side -- not possible */
/* compute half-vector of the refraction (eq. 16) */
- float3 ht = -(m_eta * omega_in + I);
+ float3 ht;
+ if(bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_THIN_ID) {
+ /* for thin surfaces refraction approximately cancels and thus specular transmission is modelled
+ * using a microfacet distribution which is simply reflected to the other side */
+ ht = -(omega_in + I);
+ }
+ else {
+ ht = -(m_eta * omega_in + I);
+ }
float3 Ht = normalize(ht);
float cosHO = dot(Ht, I);
float cosHI = dot(Ht, omega_in);
@@ -536,7 +556,13 @@ ccl_device float3 bsdf_microfacet_ggx_eval_transmit(const ShaderClosure *sc, con
/* out = fabsf(cosHI * cosHO) * (m_eta * m_eta) * G * D / (cosNO * Ht2)
* pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2 */
- float common = D * (m_eta * m_eta) / (cosNO * Ht2);
+ float common;
+ if(bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_THIN_ID) {
+ common = D * 0.25f / cosNO;
+ }
+ else {
+ common = D * (m_eta * m_eta) / (cosNO * Ht2);
+ }
float out = G * fabsf(cosHI * cosHO) * common;
*pdf = G1o * fabsf(cosHO * cosHI) * common;
@@ -548,7 +574,7 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals *kg, const ShaderClosure
const MicrofacetBsdf *bsdf = (const MicrofacetBsdf*)sc;
float alpha_x = bsdf->alpha_x;
float alpha_y = bsdf->alpha_y;
- bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
+ bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID || bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_THIN_ID;
float3 N = bsdf->N;
float cosNO = dot(N, I);
@@ -686,6 +712,10 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals *kg, const ShaderClosure
float m_eta = bsdf->ior, fresnel;
bool inside;
+ if(bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_THIN_ID) {
+ m_eta = 1.0f;
+ }
+
fresnel = fresnel_dielectric(m_eta, m, I, &R, &T,
#ifdef __RAY_DIFFERENTIALS__
dIdx, dIdy, &dRdx, &dRdy, &dTdx, &dTdy,
@@ -1055,7 +1085,7 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals *kg, const ShaderCl
*domega_in_dy = dTdy;
#endif
- if(alpha_x*alpha_y <= 1e-7f || fabsf(m_eta - 1.0f) < 1e-4f) {
+ if(alpha_x*alpha_y <= 1e-7f || (fabsf(m_eta - 1.0f) < 1e-4f && bsdf->type != CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_THIN_ID)) {
/* some high number for MIS */
*pdf = 1e6f;
*eval = make_float3(1e6f, 1e6f, 1e6f);
@@ -1082,7 +1112,13 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals *kg, const ShaderCl
Ht2 *= Ht2;
/* see eval function for derivation */
- float common = D * (m_eta * m_eta) / (cosNO * Ht2);
+ float common;
+ if(bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_THIN_ID) {
+ common = D * 0.25f / cosNO;
+ }
+ else {
+ common = D * (m_eta * m_eta) / (cosNO * Ht2);
+ }
float out = G * fabsf(cosHI * cosHO) * common;
*pdf = G1o * cosHO * fabsf(cosHI) * common;
diff --git a/intern/cycles/kernel/closure/bssrdf.h b/intern/cycles/kernel/closure/bssrdf.h
index a5a578375dc..3f8192f588e 100644
--- a/intern/cycles/kernel/closure/bssrdf.h
+++ b/intern/cycles/kernel/closure/bssrdf.h
@@ -27,7 +27,6 @@ typedef ccl_addr_space struct Bssrdf {
float d;
float texture_blur;
float albedo;
- float roughness;
float3 N;
float3 base_color;
} Bssrdf;
@@ -364,7 +363,6 @@ 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 N = bssrdf->N;
float3 weight = bssrdf->weight * bssrdf->base_color;
float sample_weight = bssrdf->sample_weight;
@@ -372,7 +370,7 @@ ccl_device int bssrdf_setup(Bssrdf *bssrdf, ClosureType type)
DisneyDiffuseBsdf *bsdf = (DisneyDiffuseBsdf*)bssrdf;
bsdf->N = N;
- bsdf->roughness = roughness;
+ bsdf->flatness = 0.0f;
bsdf->weight = weight;
bsdf->sample_weight = sample_weight;
flag = bsdf_disney_diffuse_setup(bsdf);
diff --git a/intern/cycles/kernel/kernel_subsurface.h b/intern/cycles/kernel/kernel_subsurface.h
index 908c2d0b17d..1a831ad3b20 100644
--- a/intern/cycles/kernel/kernel_subsurface.h
+++ b/intern/cycles/kernel/kernel_subsurface.h
@@ -154,7 +154,7 @@ ccl_device void subsurface_scatter_setup_diffuse_bsdf(ShaderData *sd, ShaderClos
if(bsdf) {
bsdf->N = N;
- bsdf->roughness = bssrdf->roughness;
+ bsdf->flatness = 0.0f;
sd->flag |= bsdf_disney_diffuse_setup(bsdf);
/* replace CLOSURE_BSDF_DISNEY_DIFFUSE_ID with this special ID so render passes
diff --git a/intern/cycles/kernel/osl/osl_bssrdf.cpp b/intern/cycles/kernel/osl/osl_bssrdf.cpp
index 790dd3a2d46..b552f3af131 100644
--- a/intern/cycles/kernel/osl/osl_bssrdf.cpp
+++ b/intern/cycles/kernel/osl/osl_bssrdf.cpp
@@ -81,7 +81,6 @@ public:
bssrdf->sharpness = sharpness;
bssrdf->N = params.N;
bssrdf->base_color = params.base_color;
- bssrdf->roughness = params.roughness;
ccl_fetch(sd, flag) |= bssrdf_setup(bssrdf, (ClosureType)type);
}
@@ -94,7 +93,6 @@ public:
bssrdf->sharpness = sharpness;
bssrdf->N = params.N;
bssrdf->base_color = params.base_color;
- bssrdf->roughness = params.roughness;
ccl_fetch(sd, flag) |= bssrdf_setup(bssrdf, (ClosureType)type);
}
@@ -107,7 +105,6 @@ public:
bssrdf->sharpness = sharpness;
bssrdf->N = params.N;
bssrdf->base_color = params.base_color;
- bssrdf->roughness = params.roughness;
ccl_fetch(sd, flag) |= bssrdf_setup(bssrdf, (ClosureType)type);
}
}
@@ -206,7 +203,6 @@ ClosureParam *closure_bssrdf_disney_params()
CLOSURE_FLOAT_PARAM(DisneyBSSRDFClosure, params.texture_blur),
CLOSURE_FLOAT3_PARAM(DisneyBSSRDFClosure, params.base_color),
CLOSURE_FLOAT3_PARAM(DisneyBSSRDFClosure, albedo),
- CLOSURE_FLOAT_PARAM(DisneyBSSRDFClosure, params.roughness),
CLOSURE_STRING_KEYPARAM(DisneyBSSRDFClosure, label, "label"),
CLOSURE_FINISH_PARAM(DisneyBSSRDFClosure)
};
diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp
index 4d51dda7197..923ea908f1d 100644
--- a/intern/cycles/kernel/osl/osl_closures.cpp
+++ b/intern/cycles/kernel/osl/osl_closures.cpp
@@ -180,8 +180,20 @@ VOLUME_CLOSURE_CLASS_END(VolumeAbsorption, absorption)
BSDF_CLOSURE_CLASS_BEGIN(DisneyDiffuse, disney_diffuse, DisneyDiffuseBsdf, LABEL_DIFFUSE)
CLOSURE_FLOAT3_PARAM(DisneyDiffuseClosure, params.N),
CLOSURE_FLOAT_PARAM(DisneyDiffuseClosure, params.roughness),
+ CLOSURE_FLOAT_PARAM(DisneyDiffuseClosure, params.flatness),
BSDF_CLOSURE_CLASS_END(DisneyDiffuse, disney_diffuse)
+BSDF_CLOSURE_CLASS_BEGIN(DisneyDiffuseTransmit, disney_diffuse_transmit, DisneyDiffuseBsdf, LABEL_DIFFUSE|LABEL_TRANSMIT)
+ CLOSURE_FLOAT3_PARAM(DisneyDiffuseTransmitClosure, params.N),
+ CLOSURE_FLOAT_PARAM(DisneyDiffuseTransmitClosure, params.roughness),
+ CLOSURE_FLOAT_PARAM(DisneyDiffuseTransmitClosure, params.flatness),
+BSDF_CLOSURE_CLASS_END(DisneyDiffuseTransmit, disney_diffuse_transmit)
+
+BSDF_CLOSURE_CLASS_BEGIN(DisneyRetroReflection, disney_retro_reflection, DisneyDiffuseBsdf, LABEL_DIFFUSE)
+ CLOSURE_FLOAT3_PARAM(DisneyRetroReflectionClosure, params.N),
+ CLOSURE_FLOAT_PARAM(DisneyRetroReflectionClosure, params.roughness),
+BSDF_CLOSURE_CLASS_END(DisneyRetroReflection, disney_retro_reflection)
+
BSDF_CLOSURE_CLASS_BEGIN(DisneySheen, disney_sheen, DisneySheenBsdf, LABEL_DIFFUSE)
CLOSURE_FLOAT3_PARAM(DisneySheenClosure, params.N),
BSDF_CLOSURE_CLASS_END(DisneySheen, disney_sheen)
@@ -299,6 +311,10 @@ void OSLShader::register_closures(OSLShadingSystem *ss_)
bsdf_glossy_toon_params(), bsdf_glossy_toon_prepare);
register_closure(ss, "disney_diffuse", id++,
bsdf_disney_diffuse_params(), bsdf_disney_diffuse_prepare);
+ register_closure(ss, "disney_diffuse_transmit", id++,
+ bsdf_disney_diffuse_transmit_params(), bsdf_disney_diffuse_transmit_prepare);
+ register_closure(ss, "disney_retro_reflection", id++,
+ bsdf_disney_retro_reflection_params(), bsdf_disney_retro_reflection_prepare);
register_closure(ss, "disney_sheen", id++,
bsdf_disney_sheen_params(), bsdf_disney_sheen_prepare);
register_closure(ss, "disney_clearcoat", id++,
diff --git a/intern/cycles/kernel/shaders/node_disney_bsdf.osl b/intern/cycles/kernel/shaders/node_disney_bsdf.osl
index 313f4bdb8e4..8b5bacb64f4 100644
--- a/intern/cycles/kernel/shaders/node_disney_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_disney_bsdf.osl
@@ -19,6 +19,7 @@
shader node_disney_bsdf(
string distribution = "Multiscatter GGX",
+ string surface_type = "Solid Surface",
color BaseColor = color(0.8, 0.8, 0.8),
float Subsurface = 0.0,
vector SubsurfaceRadius = vector(1.0, 1.0, 1.0),
@@ -33,8 +34,10 @@ shader node_disney_bsdf(
float SheenTint = 0.5,
float Clearcoat = 0.0,
float ClearcoatGloss = 1.0,
+ float SpecularTransmission = 0.0,
float IOR = 1.45,
- float Transparency = 0.0,
+ float Flatness = 0.0,
+ float DiffuseTransmission = 0.0,
float RefractionRoughness = 0.0,
normal Normal = N,
normal ClearcoatNormal = N,
@@ -42,8 +45,8 @@ shader node_disney_bsdf(
output closure color BSDF = 0)
{
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 transp = clamp(Transparency, 0.0, 1.0) * (1.0 - clamp(Metallic, 0.0, 1.0));
+ float diffuse_weight = (1.0 - clamp(Metallic, 0.0, 1.0)) * (1.0 - clamp(SpecularTransmission, 0.0, 1.0));
+ float transp = clamp(SpecularTransmission, 0.0, 1.0) * (1.0 - clamp(Metallic, 0.0, 1.0));
float specular_weight = (1.0 - transp);
vector T = Tangent;
@@ -56,10 +59,24 @@ shader node_disney_bsdf(
T = rotate(T, AnisotropicRotation * M_2PI, point(0.0, 0.0, 0.0), Normal);
if (diffuse_weight > 1e-5) {
- if (Subsurface > 1e-5) {
- BSDF = bssrdf_disney(Normal, Subsurface * SubsurfaceRadius, 0.0, BaseColor, SubsurfaceColor, Roughness);
+ float flat = Flatness;
+ float diff_trans = clamp(DiffuseTransmission, 0.0, 2.0);
+ if (surface_type == "Solid Surface") {
+ flat = 0.0;
+ diff_trans = 0.0;
+ }
+
+ if (Subsurface > 1e-5 && surface_type == "Solid Surface") {
+ BSDF = bssrdf_disney(Normal, Subsurface * SubsurfaceRadius, 0.0, BaseColor, SubsurfaceColor);
} else {
- BSDF = BaseColor * disney_diffuse(Normal, Roughness);
+ BSDF = BaseColor * disney_diffuse(Normal, Roughness, flat) * ((2.0 - diff_trans) / 2.0);
+ }
+
+ /* diffuse retro-reflection */
+ BSDF = BSDF + BaseColor * disney_retro_reflection(Normal, Roughness);
+
+ if (diff_trans > 1e-5) {
+ BSDF = BSDF + BaseColor * disney_diffuse_transmit(Normal, Roughness, flat) * (diff_trans / 2.0);
}
if (Sheen > 1e-5) {
@@ -91,20 +108,23 @@ shader node_disney_bsdf(
if (transp > 1e-5) {
color Cspec0 = BaseColor * SpecularTint + color(1.0, 1.0, 1.0) * (1.0 - SpecularTint);
- float eta = backfacing() ? 1.0 / f : f;
+ float eta = (backfacing() && (surface_type == "Solid Surface")) ? 1.0 / f : f;
- if (distribution == "GGX" || Roughness <= 5e-2) {
+ if (distribution == "GGX" || Roughness <= 5e-2 || surface_type == "Thin Surface") {
float cosNO = dot(Normal, I);
float Fr = fresnel_dielectric_cos(cosNO, eta);
- float refl_roughness = Roughness;
- if (Roughness <= 1e-2)
- refl_roughness = 0.0;
+ 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);
+ if (surface_type == "Thin Surface")
+ refraction_roughness = refraction_roughness * (0.65 * eta - 0.35);
+
BSDF = BSDF + transp * (Fr * microfacet_ggx_fresnel(Normal, refl_roughness * refl_roughness, eta, BaseColor, Cspec0) +
(1.0 - Fr) * BaseColor * microfacet_ggx_refraction(Normal, refraction_roughness * refraction_roughness, eta));
} else {
diff --git a/intern/cycles/kernel/shaders/stdosl.h b/intern/cycles/kernel/shaders/stdosl.h
index 7991b19d8b5..7a98722e82c 100644
--- a/intern/cycles/kernel/shaders/stdosl.h
+++ b/intern/cycles/kernel/shaders/stdosl.h
@@ -544,7 +544,9 @@ closure color emission() BUILTIN;
closure color background() BUILTIN;
closure color holdout() BUILTIN;
closure color ambient_occlusion() BUILTIN;
-closure color disney_diffuse(normal N, float roughness) BUILTIN;
+closure color disney_diffuse(normal N, float roughness, float flatness) BUILTIN;
+closure color disney_diffuse_transmit(normal N, float roughness, float flatness) BUILTIN;
+closure color disney_retro_reflection(normal N, float roughness) BUILTIN;
closure color disney_sheen(normal N) BUILTIN;
closure color disney_clearcoat(normal N, float clearcoat, float clearcoat_gloss) BUILTIN;
@@ -552,7 +554,7 @@ closure color disney_clearcoat(normal N, float clearcoat, float clearcoat_gloss)
closure color bssrdf_cubic(normal N, vector radius, float texture_blur, float sharpness) BUILTIN;
closure color bssrdf_gaussian(normal N, vector radius, float texture_blur) BUILTIN;
closure color bssrdf_burley(normal N, vector radius, float texture_blur, color albedo) BUILTIN;
-closure color bssrdf_disney(normal N, vector radius, float texture_blur, color base_color, color subsurface_color, float roughness) BUILTIN;
+closure color bssrdf_disney(normal N, vector radius, float texture_blur, color base_color, color subsurface_color) BUILTIN;
// Hair
closure color hair_reflection(normal N, float roughnessu, float roughnessv, vector T, float offset) BUILTIN;
diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h
index bfcd2a290a8..7e6471458ef 100644
--- a/intern/cycles/kernel/svm/svm_closure.h
+++ b/intern/cycles/kernel/svm/svm_closure.h
@@ -78,14 +78,16 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
switch(type) {
case CLOSURE_BSDF_DISNEY_ID: {
uint specular_offset, roughness_offset, specular_tint_offset, anisotropic_offset, sheen_offset,
- sheen_tint_offset, clearcoat_offset, clearcoat_gloss_offset, eta_offset, transparency_offset,
- anisotropic_rotation_offset, refraction_roughness_offset;
+ sheen_tint_offset, clearcoat_offset, clearcoat_gloss_offset, eta_offset, spec_trans_offset,
+ anisotropic_rotation_offset, refraction_roughness_offset, flatness_offset, diff_trans_offset, invalid0, invalid1;
+
uint4 data_node2 = read_node(kg, offset);
float3 T = stack_load_float3(stack, data_node.y);
decode_node_uchar4(data_node.z, &specular_offset, &roughness_offset, &specular_tint_offset, &anisotropic_offset);
decode_node_uchar4(data_node.w, &sheen_offset, &sheen_tint_offset, &clearcoat_offset, &clearcoat_gloss_offset);
- decode_node_uchar4(data_node2.x, &eta_offset, &transparency_offset, &anisotropic_rotation_offset, &refraction_roughness_offset);
+ decode_node_uchar4(data_node2.x, &eta_offset, &spec_trans_offset, &anisotropic_rotation_offset, &refraction_roughness_offset);
+ decode_node_uchar4(data_node2.y, &flatness_offset, &diff_trans_offset, &invalid0, &invalid1);
// get disney parameters
float metallic = param1;
@@ -98,29 +100,32 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
float sheen_tint = stack_load_float(stack, sheen_tint_offset);
float clearcoat = stack_load_float(stack, clearcoat_offset);
float clearcoat_gloss = stack_load_float(stack, clearcoat_gloss_offset);
- float transparency = stack_load_float(stack, transparency_offset);
+ float spec_trans = stack_load_float(stack, spec_trans_offset);
float anisotropic_rotation = stack_load_float(stack, anisotropic_rotation_offset);
float refraction_roughness = stack_load_float(stack, refraction_roughness_offset);
float eta = fmaxf(stack_load_float(stack, eta_offset), 1e-5f);
+ float flatness = stack_load_float(stack, flatness_offset);
+ float diff_trans = clamp(stack_load_float(stack, diff_trans_offset), 0.0f, 2.0f);
- ClosureType distribution = stack_valid(data_node2.y) ? (ClosureType) data_node2.y : CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID;
+ ClosureType distribution = stack_valid(data_node2.z) ? (ClosureType) data_node2.z : CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID;
+ SurfaceType surface_type = stack_valid(data_node2.w) ? (SurfaceType) data_node2.w : SOLID_SURFACE;
/* rotate tangent */
if(anisotropic_rotation != 0.0f)
T = rotate_around_axis(T, N, anisotropic_rotation * M_2PI_F);
/* calculate ior */
- float ior = (ccl_fetch(sd, flag) & SD_BACKFACING) ? 1.0f / eta : eta;
+ float ior = ((ccl_fetch(sd, flag) & SD_BACKFACING) && (surface_type == SOLID_SURFACE)) ? 1.0f / eta : eta;
// calculate fresnel for refraction
float cosNO = dot(N, ccl_fetch(sd, I));
float fresnel = fresnel_dielectric_cos(cosNO, ior);
// calculate weights of the diffuse and specular part
- float diffuse_weight = (1.0f - saturate(metallic)) * (1.0f - saturate(transparency)); // lerp(1.0f - clamp(metallic, 0.0f, 1.0f), 0.0f, lerp(clamp(transparency, 0.0f, 1.0f), 0.0f, clamp(metallic, 0.0f, 1.0f)));
-
- float transp = saturate(transparency) * (1.0f - saturate(metallic)); // lerp(clamp(transparency, 0.0f, 1.0f), 0.0f, clamp(metallic, 0.0f, 1.0f));
- float specular_weight = (1.0f - transp); // + fresnel * transp; // lerp(1.0f, fresnel, transp);
+ float diffuse_weight = (1.0f - saturate(metallic)) * (1.0f - saturate(spec_trans)); // lerp(1.0f - clamp(metallic, 0.0f, 1.0f), 0.0f, lerp(clamp(spec_trans, 0.0f, 1.0f), 0.0f, clamp(metallic, 0.0f, 1.0f)));
+
+ float spec_transp = saturate(spec_trans) * (1.0f - saturate(metallic)); // lerp(clamp(spec_trans, 0.0f, 1.0f), 0.0f, clamp(metallic, 0.0f, 1.0f));
+ float specular_weight = (1.0f - spec_transp); // + fresnel * spec_transp; // lerp(1.0f, fresnel, spec_transp);
// get the base color
uint4 data_base_color = read_node(kg, offset);
@@ -139,6 +144,11 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
float3 weight = ccl_fetch(sd, svm_closure_weight) * mix_weight;
+ if(surface_type == SOLID_SURFACE) {
+ flatness = 0.0f;
+ diff_trans = 0.0f;
+ }
+
#ifdef __SUBSURFACE__
float3 albedo = subsurface_color;
float3 subsurf_weight = weight * diffuse_weight;
@@ -152,20 +162,21 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
}
/* diffuse */
- if(subsurface < CLOSURE_WEIGHT_CUTOFF && diffuse_weight > CLOSURE_WEIGHT_CUTOFF && fabsf(average(base_color)) > CLOSURE_WEIGHT_CUTOFF) {
- float3 diff_weight = weight * base_color * diffuse_weight;
+ if((surface_type == THIN_SURFACE || subsurface < CLOSURE_WEIGHT_CUTOFF) && diffuse_weight > CLOSURE_WEIGHT_CUTOFF && fabsf(average(base_color)) > CLOSURE_WEIGHT_CUTOFF) {
+ float3 diff_weight = weight * base_color * diffuse_weight * ((2.0f - diff_trans) / 2.0f);
DisneyDiffuseBsdf *bsdf = (DisneyDiffuseBsdf*)bsdf_alloc(sd, sizeof(DisneyDiffuseBsdf), diff_weight);
if(bsdf) {
bsdf->N = N;
+ bsdf->flatness = flatness;
bsdf->roughness = roughness;
/* setup bsdf */
ccl_fetch(sd, flag) |= bsdf_disney_diffuse_setup(bsdf);
}
}
- else if(subsurf_sample_weight > CLOSURE_WEIGHT_CUTOFF) {
+ else if(surface_type == SOLID_SURFACE && subsurf_sample_weight > CLOSURE_WEIGHT_CUTOFF) {
/* radius * scale */
float3 radius = subsurface_radius * subsurface;
/* sharpness */
@@ -183,7 +194,6 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
bssrdf->sharpness = sharpness;
bssrdf->N = N;
bssrdf->base_color = base_color;
- bssrdf->roughness = roughness;
/* setup bsdf */
ccl_fetch(sd, flag) |= bssrdf_setup(bssrdf, (ClosureType)CLOSURE_BSSRDF_DISNEY_ID);
@@ -198,7 +208,6 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
bssrdf->sharpness = sharpness;
bssrdf->N = N;
bssrdf->base_color = base_color;
- bssrdf->roughness = roughness;
/* setup bsdf */
ccl_fetch(sd, flag) |= bssrdf_setup(bssrdf, (ClosureType)CLOSURE_BSSRDF_DISNEY_ID);
@@ -213,7 +222,6 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
bssrdf->sharpness = sharpness;
bssrdf->N = N;
bssrdf->base_color = base_color;
- bssrdf->roughness = roughness;
/* setup bsdf */
ccl_fetch(sd, flag) |= bssrdf_setup(bssrdf, (ClosureType)CLOSURE_BSSRDF_DISNEY_ID);
@@ -228,6 +236,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
if(bsdf) {
bsdf->N = N;
+ bsdf->flatness = flatness;
bsdf->roughness = roughness;
/* setup bsdf */
@@ -236,6 +245,21 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
}
#endif
+ /* retro reflection */
+ if(diffuse_weight > CLOSURE_WEIGHT_CUTOFF && fabsf(average(base_color)) > CLOSURE_WEIGHT_CUTOFF) {
+ float3 diff_weight = weight * base_color * diffuse_weight;
+
+ DisneyDiffuseBsdf *bsdf = (DisneyDiffuseBsdf*)bsdf_alloc(sd, sizeof(DisneyDiffuseBsdf), diff_weight);
+
+ if(bsdf) {
+ bsdf->N = N;
+ bsdf->roughness = roughness;
+
+ /* setup bsdf */
+ ccl_fetch(sd, flag) |= bsdf_disney_retro_reflection_setup(bsdf);
+ }
+ }
+
/* sheen */
if(diffuse_weight > CLOSURE_WEIGHT_CUTOFF && sheen > CLOSURE_WEIGHT_CUTOFF) {
float m_cdlum = linear_rgb_to_gray(base_color);
@@ -256,6 +280,20 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
}
}
+ /* diffuse transmission */
+ if(surface_type == THIN_SURFACE && diff_trans > CLOSURE_WEIGHT_CUTOFF && diffuse_weight > CLOSURE_WEIGHT_CUTOFF) {
+ float3 diff_weight = weight * base_color * diffuse_weight * (diff_trans / 2.0f);
+
+ DisneyDiffuseBsdf *bsdf = (DisneyDiffuseBsdf*)bsdf_alloc(sd, sizeof(DisneyDiffuseBsdf), diff_weight);
+
+ if(bsdf) {
+ bsdf->N = N;
+
+ /* setup bsdf */
+ ccl_fetch(sd, flag) |= bsdf_disney_diffuse_transmit_setup(bsdf);
+ }
+ }
+
/* specular reflection */
#ifdef __CAUSTICS_TRICKS__
if(kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) {
@@ -327,11 +365,11 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
#ifdef __CAUSTICS_TRICKS__
if(kernel_data.integrator.caustics_reflective || kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0) {
#endif
- if(transp > CLOSURE_WEIGHT_CUTOFF) {
- float3 glass_weight = weight * transp;
+ if(spec_transp > CLOSURE_WEIGHT_CUTOFF) {
+ float3 glass_weight = weight * spec_transp;
float3 cspec0 = base_color * specular_tint + make_float3(1.0f, 1.0f, 1.0f) * (1.0f - specular_tint);
- if(roughness <= 5e-2f || distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID) { /* use single-scatter GGX */
+ if(roughness <= 5e-2f || distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID || surface_type == THIN_SURFACE) { /* use single-scatter GGX */
float refl_roughness = roughness;
/* reflection */
@@ -393,8 +431,20 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
else
refraction_roughness = refl_roughness;
- bsdf->alpha_x = refraction_roughness * refraction_roughness;
- bsdf->alpha_y = refraction_roughness * refraction_roughness;
+ /* Remap the roughness for thin surfaces as introduced in the 2015 Disney paper:
+ *
+ * Extending the Disney BRDF to a BSDF with Integrated Subsurface Scattering
+ * Burley, Brent (Walt Disney Animation Studios) */
+ if(surface_type == THIN_SURFACE) {
+ refraction_roughness *= 0.65f * ior - 0.35f;
+ //refraction_roughness = safe_sqrtf(refraction_roughness);
+ }
+ else {
+ refraction_roughness *= refraction_roughness;
+ }
+
+ bsdf->alpha_x = refraction_roughness;
+ bsdf->alpha_y = refraction_roughness;
bsdf->ior = ior;
/* setup bsdf */
diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h
index ae75a9f4bf6..f3df5d7bf6d 100644
--- a/intern/cycles/kernel/svm/svm_types.h
+++ b/intern/cycles/kernel/svm/svm_types.h
@@ -396,6 +396,8 @@ typedef enum ClosureType {
CLOSURE_BSDF_OREN_NAYAR_ID,
CLOSURE_BSDF_DIFFUSE_RAMP_ID,
CLOSURE_BSDF_DISNEY_DIFFUSE_ID,
+ CLOSURE_BSDF_DISNEY_DIFFUSE_TRANSMIT_ID,
+ CLOSURE_BSDF_DISNEY_RETRO_REFLECTION_ID,
CLOSURE_BSDF_DISNEY_SHEEN_ID,
CLOSURE_BSDF_DIFFUSE_TOON_ID,
@@ -426,6 +428,7 @@ typedef enum ClosureType {
CLOSURE_BSDF_REFRACTION_ID,
CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID,
CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID,
+ CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_THIN_ID,
CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID,
CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID,
CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID,
@@ -483,6 +486,11 @@ typedef enum ClosureType {
#define CLOSURE_WEIGHT_CUTOFF 1e-5f
+typedef enum SurfaceType {
+ SOLID_SURFACE,
+ THIN_SURFACE
+} SurfaceType;
+
CCL_NAMESPACE_END
#endif /* __SVM_TYPES_H__ */
diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp
index 3d91ce08d13..1dece5408b2 100644
--- a/intern/cycles/render/graph.cpp
+++ b/intern/cycles/render/graph.cpp
@@ -980,7 +980,7 @@ int ShaderGraph::get_num_closures()
num_closures += 2;
}
else if(CLOSURE_IS_DISNEY(closure_type)) {
- num_closures += 8;
+ num_closures += 10;
}
else {
++num_closures;
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 848076cf818..21db1be706e 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -2229,6 +2229,10 @@ NODE_DEFINE(DisneyBsdfNode)
distribution_enum.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID);
distribution_enum.insert("Multiscatter GGX", CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
SOCKET_ENUM(distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
+ static NodeEnum surface_type_enum;
+ surface_type_enum.insert("Solid Surface", SOLID_SURFACE);
+ surface_type_enum.insert("Thin Surface", THIN_SURFACE);
+ SOCKET_ENUM(surface_type, "Surface Type", surface_type_enum, SOLID_SURFACE);
SOCKET_IN_COLOR(base_color, "Base Color", make_float3(0.8f, 0.8f, 0.8f));
SOCKET_IN_COLOR(subsurface_color, "Subsurface Color", make_float3(0.8f, 0.8f, 0.8f));
SOCKET_IN_FLOAT(metallic, "Metallic", 0.0f);
@@ -2238,14 +2242,16 @@ NODE_DEFINE(DisneyBsdfNode)
SOCKET_IN_FLOAT(roughness, "Roughness", 0.0f);
SOCKET_IN_FLOAT(specular_tint, "Specular Tint", 0.0f);
SOCKET_IN_FLOAT(anisotropic, "Anisotropic", 0.0f);
+ SOCKET_IN_FLOAT(anisotropic_rotation, "Anisotropic Rotation", 0.0f);
SOCKET_IN_FLOAT(sheen, "Sheen", 0.0f);
SOCKET_IN_FLOAT(sheen_tint, "Sheen Tint", 0.0f);
SOCKET_IN_FLOAT(clearcoat, "Clearcoat", 0.0f);
SOCKET_IN_FLOAT(clearcoat_gloss, "Clearcoat Gloss", 0.0f);
+ SOCKET_IN_FLOAT(spec_trans, "Specular Transmission", 0.0f);
SOCKET_IN_FLOAT(ior, "IOR", 0.0f);
- SOCKET_IN_FLOAT(transparency, "Transparency", 0.0f);
+ SOCKET_IN_FLOAT(flatness, "Flatness", 0.0f);
+ SOCKET_IN_FLOAT(diff_trans, "Diffuse Transmission", 0.0f);
SOCKET_IN_FLOAT(refraction_roughness, "Refraction Roughness", 0.0f);
- SOCKET_IN_FLOAT(anisotropic_rotation, "Anisotropic Rotation", 0.0f);
SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
SOCKET_IN_NORMAL(clearcoat_normal, "Clearcoat Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
SOCKET_IN_NORMAL(tangent, "Tangent", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TANGENT);
@@ -2278,9 +2284,9 @@ void DisneyBsdfNode::attributes(Shader *shader, AttributeRequestSet *attributes)
}
void DisneyBsdfNode::compile(SVMCompiler& compiler, ShaderInput *p_metallic, ShaderInput *p_subsurface, ShaderInput *p_subsurface_radius,
- ShaderInput *p_specular, ShaderInput *p_roughness, ShaderInput *p_specular_tint, ShaderInput *p_anisotropic,
- ShaderInput *p_sheen, ShaderInput *p_sheen_tint, ShaderInput *p_clearcoat, ShaderInput *p_clearcoat_gloss,
- ShaderInput *p_ior, ShaderInput *p_transparency, ShaderInput *p_anisotropic_rotation, ShaderInput *p_refraction_roughness)
+ ShaderInput *p_specular, ShaderInput *p_specular_tint, ShaderInput *p_roughness, ShaderInput *p_anisotropic, ShaderInput *p_anisotropic_rotation,
+ ShaderInput *p_sheen, ShaderInput *p_sheen_tint, ShaderInput *p_clearcoat, ShaderInput *p_clearcoat_gloss, ShaderInput *p_spec_trans,
+ ShaderInput *p_ior, ShaderInput *p_flatness, ShaderInput *p_diff_trans, ShaderInput *p_refraction_roughness)
{
ShaderInput *base_color_in = input("Base Color");
ShaderInput *subsurface_color_in = input("Subsurface Color");
@@ -2299,14 +2305,16 @@ void DisneyBsdfNode::compile(SVMCompiler& compiler, ShaderInput *p_metallic, Sha
int roughness_offset = compiler.stack_assign(p_roughness);
int specular_tint_offset = compiler.stack_assign(p_specular_tint);
int anisotropic_offset = compiler.stack_assign(p_anisotropic);
+ int anisotropic_rotation_offset = compiler.stack_assign(p_anisotropic_rotation);
int sheen_offset = compiler.stack_assign(p_sheen);
int sheen_tint_offset = compiler.stack_assign(p_sheen_tint);
int clearcoat_offset = compiler.stack_assign(p_clearcoat);
int clearcoat_gloss_offset = compiler.stack_assign(p_clearcoat_gloss);
+ int spec_trans_offset = compiler.stack_assign(p_spec_trans);
int ior_offset = compiler.stack_assign(p_ior);
- int transparency_offset = compiler.stack_assign(p_transparency);
+ int flatness_offset = compiler.stack_assign(p_flatness);
+ int diff_trans_offset = compiler.stack_assign(p_diff_trans);
int refraction_roughness_offset = compiler.stack_assign(p_refraction_roughness);
- int anisotropic_rotation_offset = compiler.stack_assign(p_anisotropic_rotation);
int subsurface_radius_offset = compiler.stack_assign(p_subsurface_radius);
compiler.add_node(NODE_CLOSURE_BSDF,
@@ -2321,8 +2329,8 @@ void DisneyBsdfNode::compile(SVMCompiler& compiler, ShaderInput *p_metallic, Sha
compiler.encode_uchar4(specular_offset, roughness_offset, specular_tint_offset, anisotropic_offset),
compiler.encode_uchar4(sheen_offset, sheen_tint_offset, clearcoat_offset, clearcoat_gloss_offset));
- compiler.add_node(compiler.encode_uchar4(ior_offset, transparency_offset, anisotropic_rotation_offset, refraction_roughness_offset),
- distribution, SVM_STACK_INVALID, SVM_STACK_INVALID);
+ compiler.add_node(compiler.encode_uchar4(ior_offset, spec_trans_offset, anisotropic_rotation_offset, refraction_roughness_offset),
+ compiler.encode_uchar4(flatness_offset, diff_trans_offset, SVM_STACK_INVALID, SVM_STACK_INVALID), distribution, surface_type);
float3 bc_default = get_float3(base_color_in->socket_type);
@@ -2346,14 +2354,15 @@ bool DisneyBsdfNode::has_integrator_dependency()
void DisneyBsdfNode::compile(SVMCompiler& compiler)
{
compile(compiler, input("Metallic"), input("Subsurface"), input("Subsurface Radius"), input("Specular"),
- input("Roughness"), input("Specular Tint"), input("Anisotropic"), input("Sheen"), input("Sheen Tint"),
- input("Clearcoat"), input("Clearcoat Gloss"), input("IOR"), input("Transparency"),
- input("Anisotropic Rotation"), input("Refraction Roughness"));
+ input("Specular Tint"), input("Roughness"), input("Anisotropic"), input("Anisotropic Rotation"),
+ input("Sheen"), input("Sheen Tint"), input("Clearcoat"), input("Clearcoat Gloss"), input("Specular Transmission"),
+ input("IOR"), input("Flatness"), input("Diffuse Transmission"), input("Refraction Roughness"));
}
void DisneyBsdfNode::compile(OSLCompiler& compiler)
{
compiler.parameter(this, "distribution");
+ compiler.parameter(this, "surface_type");
compiler.add(this, "node_disney_bsdf");
}
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index c3e93143259..b19109b43a7 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -370,18 +370,19 @@ public:
bool has_surface_bssrdf() { return true; }
bool has_bssrdf_bump();
void compile(SVMCompiler& compiler, ShaderInput *metallic, ShaderInput *subsurface, ShaderInput *subsurface_radius,
- ShaderInput *specular, ShaderInput *roughness, ShaderInput *specular_tint, ShaderInput *anisotropic,
- ShaderInput *sheen, ShaderInput *sheen_tint, ShaderInput *clearcoat, ShaderInput *clearcoat_gloss,
- ShaderInput *ior, ShaderInput *transparency, ShaderInput *anisotropic_rotation, ShaderInput *refraction_roughness);
+ ShaderInput *specular, ShaderInput *specular_tint, ShaderInput *roughness, ShaderInput *anisotropic, ShaderInput *anisotropic_rotation,
+ ShaderInput *sheen, ShaderInput *sheen_tint, ShaderInput *clearcoat, ShaderInput *clearcoat_gloss, ShaderInput *spec_trans,
+ ShaderInput *ior, ShaderInput *flatness, ShaderInput *diff_trans, ShaderInput *refraction_roughness);
float3 base_color;
float3 subsurface_color, subsurface_radius;
float metallic, subsurface, specular, roughness, specular_tint, anisotropic,
- sheen, sheen_tint, clearcoat, clearcoat_gloss, ior, transparency,
- anisotropic_rotation, refraction_roughness;
+ sheen, sheen_tint, clearcoat, clearcoat_gloss, ior, spec_trans, diff_trans,
+ anisotropic_rotation, refraction_roughness, flatness;
float3 normal, clearcoat_normal, tangent;
float surface_mix_weight;
ClosureType closure, distribution, distribution_orig;
+ SurfaceType surface_type;
virtual bool equals(const ShaderNode * /*other*/)
{
diff --git a/release/datafiles/locale b/release/datafiles/locale
-Subproject dc166057192ea882b5cc70484d4c8bacd7cb41b
+Subproject 2b3c19f5f61fc72dba56a7edfdc4e55e2327dc1
diff --git a/release/scripts/addons b/release/scripts/addons
-Subproject 06dad53c80801e0e0919f086040e3d9c31bbd0a
+Subproject 3d8df6195de4062b60783c6c7791904a5f0087a
diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib
-Subproject 04af69be141a5757fc60b44cc1a5b72db524af3
+Subproject a52733b58d95ce60ecde95a9eca242e7319c285
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index c3e222cb726..cdf6ca70621 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -1071,6 +1071,12 @@ static void node_shader_buts_glossy(uiLayout *layout, bContext *UNUSED(C), Point
uiItemR(layout, ptr, "distribution", 0, "", ICON_NONE);
}
+static void node_shader_buts_disney(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "distribution", 0, "", ICON_NONE);
+ uiItemR(layout, ptr, "surface_type", 0, "", ICON_NONE);
+}
+
static void node_shader_buts_anisotropic(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "distribution", 0, "", ICON_NONE);
@@ -1234,9 +1240,11 @@ static void node_shader_set_butfunc(bNodeType *ntype)
case SH_NODE_BSDF_GLOSSY:
case SH_NODE_BSDF_GLASS:
case SH_NODE_BSDF_REFRACTION:
- case SH_NODE_BSDF_DISNEY:
ntype->draw_buttons = node_shader_buts_glossy;
break;
+ case SH_NODE_BSDF_DISNEY:
+ ntype->draw_buttons = node_shader_buts_disney;
+ break;
case SH_NODE_BSDF_ANISOTROPIC:
ntype->draw_buttons = node_shader_buts_anisotropic;
break;
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 46b30f41f5b..1ef2ba4cbe4 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -915,6 +915,10 @@ typedef struct NodeSunBeams {
#define SHD_GLOSSY_ASHIKHMIN_SHIRLEY 3
#define SHD_GLOSSY_MULTI_GGX 4
+/* surface type */
+#define SHD_THIN_SURFACE 0
+#define SHD_SOLID_SURFACE 1
+
/* vector transform */
#define SHD_VECT_TRANSFORM_TYPE_VECTOR 0
#define SHD_VECT_TRANSFORM_TYPE_POINT 1
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 14e46e15343..b7752f17b89 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -4205,6 +4205,18 @@ static void def_disney(StructRNA *srna)
RNA_def_property_enum_items(prop, prop_disney_distribution_items);
RNA_def_property_ui_text(prop, "Distribution", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNodeDisney_update");
+
+ static EnumPropertyItem prop_disney_surface_type_items[] = {
+ { SHD_THIN_SURFACE, "THIN_SURFACE", 0, "Thin Surface", "" },
+ { SHD_SOLID_SURFACE, "SOLID_SURFACE", 0, "Solid Surface", "" },
+ { 0, NULL, 0, NULL, NULL }
+ };
+
+ prop = RNA_def_property(srna, "surface_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "custom2");
+ RNA_def_property_enum_items(prop, prop_disney_surface_type_items);
+ RNA_def_property_ui_text(prop, "Surface Type", "");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNodeDisney_update");
}
static void def_refraction(StructRNA *srna)
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_disney.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_disney.c
index 54af18a64a7..6c3884c3366 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_disney.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_disney.c
@@ -44,8 +44,10 @@ static bNodeSocketTemplate sh_node_bsdf_disney_in[] = {
{ SOCK_FLOAT, 1, N_("Sheen Tint"), 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
{ SOCK_FLOAT, 1, N_("Clearcoat"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
{ SOCK_FLOAT, 1, N_("Clearcoat Gloss"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_FLOAT, 1, N_("Specular Transmission"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
{ SOCK_FLOAT, 1, N_("IOR"), 1.45f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
- { SOCK_FLOAT, 1, N_("Transparency"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_FLOAT, 1, N_("Flatness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_FLOAT, 1, N_("Diffuse Transmission"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f, PROP_FACTOR},
{ SOCK_FLOAT, 1, N_("Refraction Roughness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
{ SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
{ SOCK_VECTOR, 1, N_("Clearcoat Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
@@ -61,14 +63,15 @@ static bNodeSocketTemplate sh_node_bsdf_disney_out[] = {
static void node_shader_init_disney(bNodeTree *UNUSED(ntree), bNode *node)
{
node->custom1 = SHD_GLOSSY_MULTI_GGX;
+ node->custom2 = SHD_SOLID_SURFACE;
}
static int node_shader_gpu_bsdf_disney(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
{
- if (!in[16].link)
- in[16].link = GPU_builtin(GPU_VIEW_NORMAL);
+ if (!in[18].link)
+ in[18].link = GPU_builtin(GPU_VIEW_NORMAL);
else
- GPU_link(mat, "direction_transform_m4v3", in[16].link, GPU_builtin(GPU_VIEW_MATRIX), &in[16].link);
+ GPU_link(mat, "direction_transform_m4v3", in[18].link, GPU_builtin(GPU_VIEW_MATRIX), &in[18].link);
return GPU_stack_link(mat, "node_bsdf_disney", in, out);
}
@@ -77,6 +80,7 @@ static void node_shader_update_disney(bNodeTree *UNUSED(ntree), bNode *node)
{
bNodeSocket *sock;
int distribution = node->custom1;
+ int surface_type = node->custom2;
for (sock = node->inputs.first; sock; sock = sock->next) {
if (STREQ(sock->name, "Refraction Roughness")) {
@@ -84,7 +88,36 @@ static void node_shader_update_disney(bNodeTree *UNUSED(ntree), bNode *node)
sock->flag &= ~SOCK_UNAVAIL;
else
sock->flag |= SOCK_UNAVAIL;
-
+ }
+ else if (STREQ(sock->name, "Diffuse Transmission")) {
+ if (surface_type == SHD_THIN_SURFACE)
+ sock->flag &= ~SOCK_UNAVAIL;
+ else
+ sock->flag |= SOCK_UNAVAIL;
+ }
+ else if (STREQ(sock->name, "Subsurface")) {
+ if (surface_type == SHD_SOLID_SURFACE)
+ sock->flag &= ~SOCK_UNAVAIL;
+ else
+ sock->flag |= SOCK_UNAVAIL;
+ }
+ else if (STREQ(sock->name, "Subsurface Radius")) {
+ if (surface_type == SHD_SOLID_SURFACE)
+ sock->flag &= ~SOCK_UNAVAIL;
+ else
+ sock->flag |= SOCK_UNAVAIL;
+ }
+ else if (STREQ(sock->name, "Subsurface Color")) {
+ if (surface_type == SHD_SOLID_SURFACE)
+ sock->flag &= ~SOCK_UNAVAIL;
+ else
+ sock->flag |= SOCK_UNAVAIL;
+ }
+ else if (STREQ(sock->name, "Flatness")) {
+ if (surface_type == SHD_THIN_SURFACE)
+ sock->flag &= ~SOCK_UNAVAIL;
+ else
+ sock->flag |= SOCK_UNAVAIL;
}
}
}