diff --git a/libraries/pbrlib/genglsl/mx_conductor_bsdf.glsl b/libraries/pbrlib/genglsl/mx_conductor_bsdf.glsl
index 532550554a..04bbe42dbb 100644
--- a/libraries/pbrlib/genglsl/mx_conductor_bsdf.glsl
+++ b/libraries/pbrlib/genglsl/mx_conductor_bsdf.glsl
@@ -1,6 +1,6 @@
#include "lib/mx_microfacet_specular.glsl"
-void mx_conductor_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlusion, float weight, vec3 ior_n, vec3 ior_k, vec2 roughness, vec3 N, vec3 X, int distribution, inout BSDF bsdf)
+void mx_conductor_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlusion, float weight, vec3 ior_n, vec3 ior_k, vec2 roughness, float thinfilm_thickness, float thinfilm_ior, vec3 N, vec3 X, int distribution, inout BSDF bsdf)
{
bsdf.throughput = vec3(0.0);
@@ -24,8 +24,8 @@ void mx_conductor_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlusion, float
vec3 Ht = vec3(dot(H, X), dot(H, Y), dot(H, N));
FresnelData fd;
- if (bsdf.thickness > 0.0)
- fd = mx_init_fresnel_conductor_airy(ior_n, ior_k, bsdf.thickness, bsdf.ior);
+ if (thinfilm_thickness > 0.0)
+ fd = mx_init_fresnel_conductor_airy(ior_n, ior_k, thinfilm_thickness, thinfilm_ior);
else
fd = mx_init_fresnel_conductor(ior_n, ior_k);
@@ -39,7 +39,7 @@ void mx_conductor_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlusion, float
bsdf.response = D * F * G * comp * occlusion * weight / (4.0 * NdotV);
}
-void mx_conductor_bsdf_indirect(vec3 V, float weight, vec3 ior_n, vec3 ior_k, vec2 roughness, vec3 N, vec3 X, int distribution, inout BSDF bsdf)
+void mx_conductor_bsdf_indirect(vec3 V, float weight, vec3 ior_n, vec3 ior_k, vec2 roughness, float thinfilm_thickness, float thinfilm_ior, vec3 N, vec3 X, int distribution, inout BSDF bsdf)
{
bsdf.throughput = vec3(0.0);
@@ -53,8 +53,8 @@ void mx_conductor_bsdf_indirect(vec3 V, float weight, vec3 ior_n, vec3 ior_k, ve
float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
FresnelData fd;
- if (bsdf.thickness > 0.0)
- fd = mx_init_fresnel_conductor_airy(ior_n, ior_k, bsdf.thickness, bsdf.ior);
+ if (thinfilm_thickness > 0.0)
+ fd = mx_init_fresnel_conductor_airy(ior_n, ior_k, thinfilm_thickness, thinfilm_ior);
else
fd = mx_init_fresnel_conductor(ior_n, ior_k);
diff --git a/libraries/pbrlib/genglsl/mx_dielectric_bsdf.glsl b/libraries/pbrlib/genglsl/mx_dielectric_bsdf.glsl
index dcaaadf1fa..826b9c24e5 100644
--- a/libraries/pbrlib/genglsl/mx_dielectric_bsdf.glsl
+++ b/libraries/pbrlib/genglsl/mx_dielectric_bsdf.glsl
@@ -1,6 +1,6 @@
#include "lib/mx_microfacet_specular.glsl"
-void mx_dielectric_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlusion, float weight, vec3 tint, float ior, vec2 roughness, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf)
+void mx_dielectric_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlusion, float weight, vec3 tint, float ior, vec2 roughness, float thinfilm_thickness, float thinfilm_ior, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf)
{
if (weight < M_FLOAT_EPS)
{
@@ -22,9 +22,9 @@ void mx_dielectric_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlusion, floa
vec3 Ht = vec3(dot(H, X), dot(H, Y), dot(H, N));
FresnelData fd;
- if (bsdf.thickness > 0.0)
+ if (thinfilm_thickness > 0.0)
{
- fd = mx_init_fresnel_dielectric_airy(ior, bsdf.thickness, bsdf.ior);
+ fd = mx_init_fresnel_dielectric_airy(ior, thinfilm_thickness, thinfilm_ior);
}
else
{
@@ -43,7 +43,7 @@ void mx_dielectric_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlusion, floa
bsdf.response = D * F * G * comp * tint * occlusion * weight / (4.0 * NdotV);
}
-void mx_dielectric_bsdf_transmission(vec3 V, float weight, vec3 tint, float ior, vec2 roughness, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf)
+void mx_dielectric_bsdf_transmission(vec3 V, float weight, vec3 tint, float ior, vec2 roughness, float thinfilm_thickness, float thinfilm_ior, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf)
{
if (weight < M_FLOAT_EPS)
{
@@ -54,9 +54,9 @@ void mx_dielectric_bsdf_transmission(vec3 V, float weight, vec3 tint, float ior,
float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
FresnelData fd;
- if (bsdf.thickness > 0.0)
+ if (thinfilm_thickness > 0.0)
{
- fd = mx_init_fresnel_dielectric_airy(ior, bsdf.thickness, bsdf.ior);
+ fd = mx_init_fresnel_dielectric_airy(ior, thinfilm_thickness, thinfilm_ior);
}
else
{
@@ -78,7 +78,7 @@ void mx_dielectric_bsdf_transmission(vec3 V, float weight, vec3 tint, float ior,
}
}
-void mx_dielectric_bsdf_indirect(vec3 V, float weight, vec3 tint, float ior, vec2 roughness, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf)
+void mx_dielectric_bsdf_indirect(vec3 V, float weight, vec3 tint, float ior, vec2 roughness, float thinfilm_thickness, float thinfilm_ior, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf)
{
if (weight < M_FLOAT_EPS)
{
@@ -90,9 +90,9 @@ void mx_dielectric_bsdf_indirect(vec3 V, float weight, vec3 tint, float ior, vec
float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
FresnelData fd;
- if (bsdf.thickness > 0.0)
+ if (thinfilm_thickness > 0.0)
{
- fd = mx_init_fresnel_dielectric_airy(ior, bsdf.thickness, bsdf.ior);
+ fd = mx_init_fresnel_dielectric_airy(ior, thinfilm_thickness, thinfilm_ior);
}
else
{
diff --git a/libraries/pbrlib/genglsl/mx_generalized_schlick_bsdf.glsl b/libraries/pbrlib/genglsl/mx_generalized_schlick_bsdf.glsl
index ebeaa66f7a..4aa7e9efe6 100644
--- a/libraries/pbrlib/genglsl/mx_generalized_schlick_bsdf.glsl
+++ b/libraries/pbrlib/genglsl/mx_generalized_schlick_bsdf.glsl
@@ -1,6 +1,6 @@
#include "lib/mx_microfacet_specular.glsl"
-void mx_generalized_schlick_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlusion, float weight, vec3 color0, vec3 color90, float exponent, vec2 roughness, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf)
+void mx_generalized_schlick_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlusion, float weight, vec3 color0, vec3 color90, float exponent, vec2 roughness, float thinfilm_thickness, float thinfilm_ior, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf)
{
if (weight < M_FLOAT_EPS)
{
@@ -22,9 +22,9 @@ void mx_generalized_schlick_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlus
vec3 Ht = vec3(dot(H, X), dot(H, Y), dot(H, N));
FresnelData fd;
- if (bsdf.thickness > 0.0)
+ if (thinfilm_thickness > 0.0)
{
- fd = mx_init_fresnel_schlick_airy(color0, color90, exponent, bsdf.thickness, bsdf.ior);
+ fd = mx_init_fresnel_schlick_airy(color0, color90, exponent, thinfilm_thickness, thinfilm_ior);
}
else
{
@@ -43,7 +43,7 @@ void mx_generalized_schlick_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlus
bsdf.response = D * F * G * comp * occlusion * weight / (4.0 * NdotV);
}
-void mx_generalized_schlick_bsdf_transmission(vec3 V, float weight, vec3 color0, vec3 color90, float exponent, vec2 roughness, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf)
+void mx_generalized_schlick_bsdf_transmission(vec3 V, float weight, vec3 color0, vec3 color90, float exponent, vec2 roughness, float thinfilm_thickness, float thinfilm_ior, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf)
{
if (weight < M_FLOAT_EPS)
{
@@ -54,9 +54,9 @@ void mx_generalized_schlick_bsdf_transmission(vec3 V, float weight, vec3 color0,
float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
FresnelData fd;
- if (bsdf.thickness > 0.0)
+ if (thinfilm_thickness > 0.0)
{
- fd = mx_init_fresnel_schlick_airy(color0, color90, exponent, bsdf.thickness, bsdf.ior);
+ fd = mx_init_fresnel_schlick_airy(color0, color90, exponent, thinfilm_thickness, thinfilm_thickness);
}
else
{
@@ -80,7 +80,7 @@ void mx_generalized_schlick_bsdf_transmission(vec3 V, float weight, vec3 color0,
}
}
-void mx_generalized_schlick_bsdf_indirect(vec3 V, float weight, vec3 color0, vec3 color90, float exponent, vec2 roughness, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf)
+void mx_generalized_schlick_bsdf_indirect(vec3 V, float weight, vec3 color0, vec3 color90, float exponent, vec2 roughness, float thinfilm_thickness, float thinfilm_ior, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf)
{
if (weight < M_FLOAT_EPS)
{
@@ -91,9 +91,9 @@ void mx_generalized_schlick_bsdf_indirect(vec3 V, float weight, vec3 color0, vec
float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
FresnelData fd;
- if (bsdf.thickness > 0.0)
+ if (thinfilm_thickness > 0.0)
{
- fd = mx_init_fresnel_schlick_airy(color0, color90, exponent, bsdf.thickness, bsdf.ior);
+ fd = mx_init_fresnel_schlick_airy(color0, color90, exponent, thinfilm_thickness, thinfilm_ior);
}
else
{
diff --git a/libraries/pbrlib/genglsl/pbrlib_genglsl_impl.mtlx b/libraries/pbrlib/genglsl/pbrlib_genglsl_impl.mtlx
index fa4617375f..5980b1f02c 100644
--- a/libraries/pbrlib/genglsl/pbrlib_genglsl_impl.mtlx
+++ b/libraries/pbrlib/genglsl/pbrlib_genglsl_impl.mtlx
@@ -28,9 +28,6 @@
-
-
-
diff --git a/libraries/pbrlib/genmdl/pbrlib_genmdl_impl.mtlx b/libraries/pbrlib/genmdl/pbrlib_genmdl_impl.mtlx
index 800e32edd0..429e103b84 100644
--- a/libraries/pbrlib/genmdl/pbrlib_genmdl_impl.mtlx
+++ b/libraries/pbrlib/genmdl/pbrlib_genmdl_impl.mtlx
@@ -11,13 +11,13 @@
-
+
-
+
-
+
@@ -25,9 +25,6 @@
-
-
-
diff --git a/libraries/pbrlib/genmsl/pbrlib_genmsl_impl.mtlx b/libraries/pbrlib/genmsl/pbrlib_genmsl_impl.mtlx
index 8d1d2a4729..51f0ba14b8 100644
--- a/libraries/pbrlib/genmsl/pbrlib_genmsl_impl.mtlx
+++ b/libraries/pbrlib/genmsl/pbrlib_genmsl_impl.mtlx
@@ -28,9 +28,6 @@
-
-
-
diff --git a/libraries/pbrlib/genosl/legacy/mx_conductor_bsdf.osl b/libraries/pbrlib/genosl/legacy/mx_conductor_bsdf.osl
index 850ff58f62..82cb6f32be 100644
--- a/libraries/pbrlib/genosl/legacy/mx_conductor_bsdf.osl
+++ b/libraries/pbrlib/genosl/legacy/mx_conductor_bsdf.osl
@@ -1,6 +1,6 @@
#include "../lib/mx_microfacet_specular.osl"
-void mx_conductor_bsdf(float weight, color ior_n, color ior_k, vector2 roughness, normal N, vector U, string distribution, output BSDF bsdf)
+void mx_conductor_bsdf(float weight, color ior_n, color ior_k, vector2 roughness, float thinfilm_thickness, float thinfilm_ior, normal N, vector U, string distribution, output BSDF bsdf)
{
bsdf.throughput = color(0.0);
diff --git a/libraries/pbrlib/genosl/legacy/mx_dielectric_bsdf.osl b/libraries/pbrlib/genosl/legacy/mx_dielectric_bsdf.osl
index a17fdd40cf..5e50834746 100644
--- a/libraries/pbrlib/genosl/legacy/mx_dielectric_bsdf.osl
+++ b/libraries/pbrlib/genosl/legacy/mx_dielectric_bsdf.osl
@@ -1,6 +1,6 @@
#include "../lib/mx_microfacet_specular.osl"
-void mx_dielectric_bsdf(float weight, color tint, float ior, vector2 roughness, normal N, vector U, string distribution, string scatter_mode, output BSDF bsdf)
+void mx_dielectric_bsdf(float weight, color tint, float ior, vector2 roughness, float thinfilm_thickness, float thinfilm_ior, normal N, vector U, string distribution, string scatter_mode, output BSDF bsdf)
{
if (scatter_mode == "T")
{
diff --git a/libraries/pbrlib/genosl/legacy/mx_generalized_schlick_bsdf.osl b/libraries/pbrlib/genosl/legacy/mx_generalized_schlick_bsdf.osl
index ee34727ec1..59fc64bfd4 100644
--- a/libraries/pbrlib/genosl/legacy/mx_generalized_schlick_bsdf.osl
+++ b/libraries/pbrlib/genosl/legacy/mx_generalized_schlick_bsdf.osl
@@ -1,6 +1,6 @@
#include "../lib/mx_microfacet_specular.osl"
-void mx_generalized_schlick_bsdf(float weight, color color0, color color90, float exponent, vector2 roughness, normal N, vector U, string distribution, string scatter_mode, output BSDF bsdf)
+void mx_generalized_schlick_bsdf(float weight, color color0, color color90, float exponent, vector2 roughness, float thinfilm_thickness, float thinfilm_ior, normal N, vector U, string distribution, string scatter_mode, output BSDF bsdf)
{
float avgF0 = dot(color0, color(1.0 / 3.0));
float ior = mx_f0_to_ior(avgF0);
diff --git a/libraries/pbrlib/genosl/mx_dielectric_bsdf.osl b/libraries/pbrlib/genosl/mx_dielectric_bsdf.osl
index 69773b3ced..fe570e1546 100644
--- a/libraries/pbrlib/genosl/mx_dielectric_bsdf.osl
+++ b/libraries/pbrlib/genosl/mx_dielectric_bsdf.osl
@@ -1,15 +1,15 @@
-void mx_dielectric_bsdf(float weight, color tint, float ior, vector2 roughness, normal N, vector U, string distribution, string scatter_mode, output BSDF bsdf)
+void mx_dielectric_bsdf(float weight, color tint, float ior, vector2 roughness, float thinfilm_thickness, float thinfilm_ior, normal N, vector U, string distribution, string scatter_mode, output BSDF bsdf)
{
if (scatter_mode == "R")
{
- bsdf = weight * dielectric_bsdf(N, U, tint, color(0.0), roughness.x, roughness.y, ior, distribution);
+ bsdf = weight * dielectric_bsdf(N, U, tint, color(0.0), roughness.x, roughness.y, ior, distribution, "thinfilm_thickness", thinfilm_thickness, "thinfilm_ior", thinfilm_ior);
}
else if (scatter_mode == "T")
{
- bsdf = weight * dielectric_bsdf(N, U, color(0.0), tint, roughness.x, roughness.y, ior, distribution);
+ bsdf = weight * dielectric_bsdf(N, U, color(0.0), tint, roughness.x, roughness.y, ior, distribution, "thinfilm_thickness", thinfilm_thickness, "thinfilm_ior", thinfilm_ior);
}
else
{
- bsdf = weight * dielectric_bsdf(N, U, tint, tint, roughness.x, roughness.y, ior, distribution);
+ bsdf = weight * dielectric_bsdf(N, U, tint, tint, roughness.x, roughness.y, ior, distribution, "thinfilm_thickness", thinfilm_thickness, "thinfilm_ior", thinfilm_ior);
}
}
diff --git a/libraries/pbrlib/genosl/mx_generalized_schlick_bsdf.osl b/libraries/pbrlib/genosl/mx_generalized_schlick_bsdf.osl
index 955de3c1fa..80431b5af2 100644
--- a/libraries/pbrlib/genosl/mx_generalized_schlick_bsdf.osl
+++ b/libraries/pbrlib/genosl/mx_generalized_schlick_bsdf.osl
@@ -1,15 +1,15 @@
-void mx_generalized_schlick_bsdf(float weight, color color0, color color90, float exponent, vector2 roughness, normal N, vector U, string distribution, string scatter_mode, output BSDF bsdf)
+void mx_generalized_schlick_bsdf(float weight, color color0, color color90, float exponent, vector2 roughness, float thinfilm_thickness, float thinfilm_ior, normal N, vector U, string distribution, string scatter_mode, output BSDF bsdf)
{
if (scatter_mode == "R")
{
- bsdf = weight * generalized_schlick_bsdf(N, U, color(1.0), color(0.0), roughness.x, roughness.y, color0, color90, exponent, distribution);
+ bsdf = weight * generalized_schlick_bsdf(N, U, color(1.0), color(0.0), roughness.x, roughness.y, color0, color90, exponent, distribution, "thinfilm_thickness", thinfilm_thickness, "thinfilm_ior", thinfilm_ior);
}
else if (scatter_mode == "T")
{
- bsdf = weight * generalized_schlick_bsdf(N, U, color(0.0), color(1.0), roughness.x, roughness.y, color0, color90, exponent, distribution);
+ bsdf = weight * generalized_schlick_bsdf(N, U, color(0.0), color(1.0), roughness.x, roughness.y, color0, color90, exponent, distribution, "thinfilm_thickness", thinfilm_thickness, "thinfilm_ior", thinfilm_ior);
}
else
{
- bsdf = weight * generalized_schlick_bsdf(N, U, color(1.0), color(1.0), roughness.x, roughness.y, color0, color90, exponent, distribution);
+ bsdf = weight * generalized_schlick_bsdf(N, U, color(1.0), color(1.0), roughness.x, roughness.y, color0, color90, exponent, distribution, "thinfilm_thickness", thinfilm_thickness, "thinfilm_ior", thinfilm_ior);
}
}
diff --git a/libraries/pbrlib/genosl/pbrlib_genosl_impl.legacy b/libraries/pbrlib/genosl/pbrlib_genosl_impl.legacy
index 6ab7cc9e61..e4a424e1ac 100644
--- a/libraries/pbrlib/genosl/pbrlib_genosl_impl.legacy
+++ b/libraries/pbrlib/genosl/pbrlib_genosl_impl.legacy
@@ -28,9 +28,6 @@
-
-
-
diff --git a/libraries/pbrlib/genosl/pbrlib_genosl_impl.mtlx b/libraries/pbrlib/genosl/pbrlib_genosl_impl.mtlx
index 7a38f0fb12..69e4574e45 100644
--- a/libraries/pbrlib/genosl/pbrlib_genosl_impl.mtlx
+++ b/libraries/pbrlib/genosl/pbrlib_genosl_impl.mtlx
@@ -14,7 +14,7 @@
-
+
@@ -28,9 +28,6 @@
-
-
-
diff --git a/libraries/pbrlib/pbrlib_defs.mtlx b/libraries/pbrlib/pbrlib_defs.mtlx
index e63625a45d..47fa249b08 100644
--- a/libraries/pbrlib/pbrlib_defs.mtlx
+++ b/libraries/pbrlib/pbrlib_defs.mtlx
@@ -63,6 +63,8 @@
+
+
@@ -79,6 +81,8 @@
+
+
@@ -95,6 +99,8 @@
+
+
@@ -127,16 +133,6 @@
-
-
-
-
-
-
-
diff --git a/resources/Materials/TestSuite/pbrlib/bsdf/thin_film_bsdf.mtlx b/resources/Materials/TestSuite/pbrlib/bsdf/thin_film_bsdf.mtlx
index a6bc23bfa2..68bd46b52f 100644
--- a/resources/Materials/TestSuite/pbrlib/bsdf/thin_film_bsdf.mtlx
+++ b/resources/Materials/TestSuite/pbrlib/bsdf/thin_film_bsdf.mtlx
@@ -1,5 +1,10 @@
+
+
+
diff --git a/resources/Materials/TestSuite/pbrlib/bsdf/vertical_layering.mtlx b/resources/Materials/TestSuite/pbrlib/bsdf/vertical_layering.mtlx
index 206f6b1f00..657b9a6462 100644
--- a/resources/Materials/TestSuite/pbrlib/bsdf/vertical_layering.mtlx
+++ b/resources/Materials/TestSuite/pbrlib/bsdf/vertical_layering.mtlx
@@ -17,129 +17,36 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -183,7 +90,7 @@
-
+
@@ -205,7 +112,7 @@
-
+
@@ -234,7 +141,7 @@
-
+
@@ -274,7 +181,7 @@
-
+
diff --git a/source/MaterialXCore/Document.cpp b/source/MaterialXCore/Document.cpp
index a5ecbf733b..46d0552250 100644
--- a/source/MaterialXCore/Document.cpp
+++ b/source/MaterialXCore/Document.cpp
@@ -46,6 +46,44 @@ NodeDefPtr getShaderNodeDef(ElementPtr shaderRef)
return NodeDefPtr();
}
+void copyConnectionOrValue(NodePtr srcNode, const string& srcInput, NodePtr dstNode, const string& dstInput)
+{
+ InputPtr src = srcNode->getInput(srcInput);
+ if (src)
+ {
+ InputPtr dst = dstNode->getInput(dstInput);
+ if (!dst)
+ {
+ dst = dstNode->addInput(dstInput, src->getType());
+ }
+
+ if (src->hasNodeName())
+ {
+ dst->setNodeName(src->getNodeName());
+ if (src->hasOutputString())
+ {
+ dst->setOutputString(src->getOutputString());
+ }
+ }
+ else if (src->hasNodeGraphString())
+ {
+ dst->setNodeGraphString(src->getNodeGraphString());
+ if (src->hasOutputString())
+ {
+ dst->setOutputString(src->getOutputString());
+ }
+ }
+ else if (src->hasInterfaceName())
+ {
+ dst->setInterfaceName(src->getInterfaceName());
+ }
+ else if (src->hasValueString())
+ {
+ dst->setValueString(src->getValueString());
+ }
+ }
+}
+
} // anonymous namespace
//
@@ -1396,6 +1434,53 @@ void Document::upgradeVersion()
// Upgrade from 1.38 to 1.39
if (majorVersion == 1 && minorVersion == 38)
{
+ const StringSet BSDF_WITH_THINFILM = { "dielectric_bsdf", "conductor_bsdf", "generalized_schlick_bsdf" };
+ const string LAYER = "layer";
+ const string TOP = "top";
+ const string BASE = "base";
+ const string THIN_FILM_BSDF = "thin_film_bsdf";
+ const string THICKNESS = "thickness";
+ const string IOR = "ior";
+ const string THINFILM_THICKNESS = "thinfilm_thickness";
+ const string THINFILM_IOR = "thinfilm_ior";
+
+ // Convert layering of thin_film_bsdf nodes to thin-film parameters on the affected BSDF nodes.
+ for (ElementPtr elem : traverseTree())
+ {
+ if (elem->isA(LAYER))
+ {
+ NodePtr layer = elem->asA();
+ NodePtr top = layer->getConnectedNode(TOP);
+ NodePtr base = layer->getConnectedNode(BASE);
+ if (top && base && top->getCategory() == THIN_FILM_BSDF)
+ {
+ // Apply thin-film parameters to all supported BSDF's upstream.
+ for (Edge edge : layer->traverseGraph())
+ {
+ NodePtr upstream = edge.getUpstreamElement()->asA();
+ if (upstream && BSDF_WITH_THINFILM.count(upstream->getCategory()))
+ {
+ copyConnectionOrValue(top, THICKNESS, upstream, THINFILM_THICKNESS);
+ copyConnectionOrValue(top, IOR, upstream, THINFILM_IOR);
+ }
+ }
+
+ // Bypass the thin-film layer operator.
+ vector downstreamPorts = layer->getDownstreamPorts();
+ for (auto port : downstreamPorts)
+ {
+ port->setNodeName(base->getName());
+ }
+
+ // Remove the now unused nodes.
+ removeNode(layer->getName());
+ removeNode(top->getName());
+ }
+ }
+ }
+
+ removeNodeDef("ND_thin_film_bsdf");
+
minorVersion = 39;
}
diff --git a/source/MaterialXGenGlsl/GlslSyntax.cpp b/source/MaterialXGenGlsl/GlslSyntax.cpp
index afd6f033dc..bf9964642e 100644
--- a/source/MaterialXGenGlsl/GlslSyntax.cpp
+++ b/source/MaterialXGenGlsl/GlslSyntax.cpp
@@ -281,10 +281,10 @@ GlslSyntax::GlslSyntax()
Type::BSDF,
std::make_shared(
"BSDF",
- "BSDF(vec3(0.0),vec3(1.0), 0.0, 0.0)",
+ "BSDF(vec3(0.0),vec3(1.0))",
EMPTY_STRING,
EMPTY_STRING,
- "struct BSDF { vec3 response; vec3 throughput; float thickness; float ior; };"));
+ "struct BSDF { vec3 response; vec3 throughput; };"));
registerTypeSyntax(
Type::EDF,
@@ -299,7 +299,7 @@ GlslSyntax::GlslSyntax()
Type::VDF,
std::make_shared(
"BSDF",
- "BSDF(vec3(0.0),vec3(1.0), 0.0, 0.0)",
+ "BSDF(vec3(0.0),vec3(1.0))",
EMPTY_STRING));
registerTypeSyntax(
diff --git a/source/MaterialXGenMdl/MdlShaderGenerator.cpp b/source/MaterialXGenMdl/MdlShaderGenerator.cpp
index dddf1f2f13..2977f83f56 100644
--- a/source/MaterialXGenMdl/MdlShaderGenerator.cpp
+++ b/source/MaterialXGenMdl/MdlShaderGenerator.cpp
@@ -168,22 +168,11 @@ MdlShaderGenerator::MdlShaderGenerator() :
registerImplementation("IM_layer_bsdf_" + MdlShaderGenerator::TARGET, ClosureLayerNodeMdl::create);
registerImplementation("IM_layer_vdf_" + MdlShaderGenerator::TARGET, ClosureLayerNodeMdl::create);
- registerImplementation("IM_mix_bsdf_" + MdlShaderGenerator::TARGET, MixBsdfNodeMdl::create);
- registerImplementation("IM_add_bsdf_" + MdlShaderGenerator::TARGET, AddOrMultiplyBsdfNodeMdl::create);
- registerImplementation("IM_multiply_bsdfC_" + MdlShaderGenerator::TARGET, AddOrMultiplyBsdfNodeMdl::create);
- registerImplementation("IM_multiply_bsdfF_" + MdlShaderGenerator::TARGET, AddOrMultiplyBsdfNodeMdl::create);
-
- //
- registerImplementation("IM_thin_film_bsdf_" + MdlShaderGenerator::TARGET, ClosureLayerNodeMdl::create);
-
//
- registerImplementation("IM_dielectric_bsdf_" + MdlShaderGenerator::TARGET, ThinFilmReceiverNodeMdl::create);
-
- //
- registerImplementation("IM_conductor_bsdf_" + MdlShaderGenerator::TARGET, ThinFilmReceiverNodeMdl::create);
+ registerImplementation("IM_dielectric_bsdf_" + MdlShaderGenerator::TARGET, LayerableNodeMdl::create);
//
- registerImplementation("IM_generalized_schlick_bsdf_" + MdlShaderGenerator::TARGET, ThinFilmReceiverNodeMdl::create);
+ registerImplementation("IM_generalized_schlick_bsdf_" + MdlShaderGenerator::TARGET, LayerableNodeMdl::create);
//
registerImplementation("IM_sheen_bsdf_" + MdlShaderGenerator::TARGET, LayerableNodeMdl::create);
diff --git a/source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.cpp b/source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.cpp
index fd27d5e547..1dfa45317f 100644
--- a/source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.cpp
+++ b/source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.cpp
@@ -16,17 +16,6 @@ MATERIALX_NAMESPACE_BEGIN
const string StringConstantsMdl::TOP = "top";
const string StringConstantsMdl::BASE = "base";
-const string StringConstantsMdl::FG = "fg";
-const string StringConstantsMdl::BG = "bg";
-const string StringConstantsMdl::IN1 = "in1";
-const string StringConstantsMdl::IN2 = "in2";
-
-const string StringConstantsMdl::THICKNESS = "thickness";
-const string StringConstantsMdl::IOR = "ior";
-const string StringConstantsMdl::THIN_FILM_THICKNESS = "thinfilm_thickness";
-const string StringConstantsMdl::THIN_FILM_IOR = "thinfilm_ior";
-
-const string StringConstantsMdl::EMPTY = "";
ShaderNodeImplPtr ClosureLayerNodeMdl::create()
{
@@ -109,69 +98,11 @@ void ClosureLayerNodeMdl::emitFunctionCall(const ShaderNode& _node, GenContext&
return;
}
- // Special composition based on the layers.
-
- // Handle the layering of thin film onto another node separately.
- // This reads the parameters from the thin film bsdf and passes them to base.
- if (top->hasClassification(ShaderNode::Classification::THINFILM))
- {
- emitBsdfOverBsdfFunctionCalls_thinFilm(node, context, stage, shadergen, top, base, output);
- return;
- }
-
- // Otherwise, if the layer is carrying thin film parameters already,
- // they are pushed further down to the top and base node if they supported it.
- ShaderInput* layerNodeThicknessInput = node.getInput(StringConstantsMdl::THIN_FILM_THICKNESS);
- ShaderInput* layerNodeIorInput = node.getInput(StringConstantsMdl::THIN_FILM_IOR);
-
- ShaderInput* topNodeThicknessInput = top->getInput(StringConstantsMdl::THIN_FILM_THICKNESS);
- ShaderInput* topNodeIorInput = top->getInput(StringConstantsMdl::THIN_FILM_IOR);
- bool breakTopConnection = false;
- if (layerNodeThicknessInput && layerNodeIorInput && topNodeThicknessInput && topNodeIorInput)
- {
- topNodeThicknessInput->makeConnection(layerNodeThicknessInput->getConnection());
- topNodeIorInput->makeConnection(layerNodeIorInput->getConnection());
- breakTopConnection = true;
- }
- ShaderInput* baseNodeThicknessInput = base->getInput(StringConstantsMdl::THIN_FILM_THICKNESS);
- ShaderInput* baseNodeIorInput = base->getInput(StringConstantsMdl::THIN_FILM_IOR);
- bool breakBaseConnection = false;
- if (layerNodeThicknessInput && layerNodeIorInput && baseNodeThicknessInput && baseNodeIorInput)
- {
- baseNodeThicknessInput->makeConnection(layerNodeThicknessInput->getConnection());
- baseNodeIorInput->makeConnection(layerNodeIorInput->getConnection());
- breakBaseConnection = true;
- }
-
- // note, this called for all layering operations independent of thin film
- emitBsdfOverBsdfFunctionCalls(node, context, stage, shadergen, top, base, output);
-
- if (breakTopConnection)
- {
- topNodeThicknessInput->breakConnection();
- topNodeIorInput->breakConnection();
- }
- if (breakBaseConnection)
- {
- baseNodeThicknessInput->breakConnection();
- baseNodeIorInput->breakConnection();
- }
-}
-
-void ClosureLayerNodeMdl::emitBsdfOverBsdfFunctionCalls(
- const ShaderNode& node,
- GenContext& context,
- ShaderStage& stage,
- const ShaderGenerator& shadergen,
- ShaderNode* top,
- ShaderNode* base,
- ShaderOutput* output) const
-{
- // transport the base bsdf further than one layer
+ // Transport the base bsdf further than one layer
ShaderNode* baseReceiverNode = top;
while (true)
{
- // if the top node is again a layer, we don't want to override the base
+ // If the top node is again a layer, we don't want to override the base
// parameter but instead aim for the base parameter of layers base
if (baseReceiverNode->hasClassification(ShaderNode::Classification::LAYER))
{
@@ -230,58 +161,6 @@ void ClosureLayerNodeMdl::emitBsdfOverBsdfFunctionCalls(
topNodeBaseInput->breakConnection();
}
-void ClosureLayerNodeMdl::emitBsdfOverBsdfFunctionCalls_thinFilm(
- const ShaderNode& node,
- GenContext& context,
- ShaderStage& stage,
- const ShaderGenerator& shadergen,
- ShaderNode* top,
- ShaderNode* base,
- ShaderOutput* output) const
-{
- ShaderInput* thinFilmThicknessInput = top->getInput(StringConstantsMdl::THICKNESS);
- ShaderInput* thinFilmIorInput = top->getInput(StringConstantsMdl::IOR);
-
- ShaderInput* baseNodeThicknessInput = base->getInput(StringConstantsMdl::THIN_FILM_THICKNESS);
- ShaderInput* baseNodeIorInput = base->getInput(StringConstantsMdl::THIN_FILM_IOR);
-
- // Make sure the base node has thickness and IOR inputs for thin film.
- if (!baseNodeThicknessInput || !baseNodeIorInput)
- {
- shadergen.emitComment("Warning: The base node does not have parameters to transport thin-film thickness and IOR.", stage);
-
- // Change the state so we emit the base BSDF function without thin film
- // with output variable name from the layer node itself.
- ScopedSetVariableName setVariable(output->getVariable(), base->getOutput());
-
- // Make the call.
- if (base->getParent() == node.getParent())
- {
- base->getImplementation().emitFunctionCall(*base, context, stage);
- }
- return;
- }
-
- // Emit the base operation with the thin-film parameters of the top node
- // pushed down to the base node.
- baseNodeThicknessInput->makeConnection(thinFilmThicknessInput->getConnection());
- baseNodeIorInput->makeConnection(thinFilmIorInput->getConnection());
-
- // Change the output of this node to the output of base.
- // This basically removes the top as it is not needed anymore.
- ScopedSetVariableName setVariable(output->getVariable(), base->getOutput());
-
- // Make the call.
- if (base->getParent() == node.getParent())
- {
- base->getImplementation().emitFunctionCall(*base, context, stage);
- }
-
- // Restore state.
- baseNodeThicknessInput->breakConnection();
- baseNodeIorInput->breakConnection();
-}
-
ShaderNodeImplPtr LayerableNodeMdl::create()
{
return std::make_shared();
@@ -293,106 +172,4 @@ void LayerableNodeMdl::addInputs(ShaderNode& node, GenContext& /*context*/) cons
node.addInput(StringConstantsMdl::BASE, Type::BSDF);
}
-ShaderNodeImplPtr ThinFilmReceiverNodeMdl::create()
-{
- return std::make_shared();
-}
-
-void ThinFilmCombineNodeMdl::emitFunctionCall(const ShaderNode& _node, GenContext& context, ShaderStage& stage) const
-{
- const ShaderGenerator& shadergen = context.getShaderGenerator();
- ShaderNode& node = const_cast(_node);
-
- ShaderInput* topInput = node.getInput(getOperatorName(0));
- ShaderInput* baseInput = node.getInput(getOperatorName(1));
-
- ShaderNode* top = topInput->getConnection()->getNode();
- ShaderNode* base = baseInput->getConnection()->getNode();
-
- // Otherwise, if the combine node is carrying thin film parameters already,
- // they are pushed further down to the top and base node if they supported it.
- ShaderInput* layerNodeThicknessInput = node.getInput(StringConstantsMdl::THIN_FILM_THICKNESS);
- ShaderInput* layerNodeIorInput = node.getInput(StringConstantsMdl::THIN_FILM_IOR);
-
- ShaderInput* topNodeThicknessInput = top->getInput(StringConstantsMdl::THIN_FILM_THICKNESS);
- ShaderInput* topNodeIorInput = top->getInput(StringConstantsMdl::THIN_FILM_IOR);
- bool breakTopConnection = false;
- if (layerNodeThicknessInput && layerNodeIorInput && topNodeThicknessInput && topNodeIorInput)
- {
- topNodeThicknessInput->makeConnection(layerNodeThicknessInput->getConnection());
- topNodeIorInput->makeConnection(layerNodeIorInput->getConnection());
- breakTopConnection = true;
- }
- ShaderInput* baseNodeThicknessInput = base->getInput(StringConstantsMdl::THIN_FILM_THICKNESS);
- ShaderInput* baseNodeIorInput = base->getInput(StringConstantsMdl::THIN_FILM_IOR);
- bool breakBaseConnection = false;
- if (layerNodeThicknessInput && layerNodeIorInput && baseNodeThicknessInput && baseNodeIorInput)
- {
- baseNodeThicknessInput->makeConnection(layerNodeThicknessInput->getConnection());
- baseNodeIorInput->makeConnection(layerNodeIorInput->getConnection());
- breakBaseConnection = true;
- }
-
- // Emit the fore and background calls.
- // Make sure it's a sibling node and not the graph interface.
- if (top->getParent() == node.getParent())
- {
- shadergen.emitFunctionCall(*top, context, stage);
- }
- if (base->getParent() == node.getParent())
- {
- shadergen.emitFunctionCall(*base, context, stage);
- }
-
- // Note, this is called for all combine operations independent of thin film.
- Base::emitFunctionCall(_node, context, stage);
-
- if (breakTopConnection)
- {
- topNodeThicknessInput->breakConnection();
- topNodeIorInput->breakConnection();
- }
- if (breakBaseConnection)
- {
- baseNodeThicknessInput->breakConnection();
- baseNodeIorInput->breakConnection();
- }
-}
-
-ShaderNodeImplPtr MixBsdfNodeMdl::create()
-{
- return std::make_shared();
-}
-
-const string& MixBsdfNodeMdl::getOperatorName(size_t index) const
-{
- switch (index)
- {
- case 0:
- return StringConstantsMdl::FG;
- case 1:
- return StringConstantsMdl::BG;
- default:
- return StringConstantsMdl::EMPTY;
- }
-}
-
-ShaderNodeImplPtr AddOrMultiplyBsdfNodeMdl::create()
-{
- return std::make_shared();
-}
-
-const string& AddOrMultiplyBsdfNodeMdl::getOperatorName(size_t index) const
-{
- switch (index)
- {
- case 0:
- return StringConstantsMdl::IN1;
- case 1:
- return StringConstantsMdl::IN2;
- default:
- return StringConstantsMdl::EMPTY;
- }
-}
-
MATERIALX_NAMESPACE_END
diff --git a/source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.h b/source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.h
index 75ea46046c..729b835560 100644
--- a/source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.h
+++ b/source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.h
@@ -23,75 +23,15 @@ class MX_GENMDL_API StringConstantsMdl
/// String constants
static const string TOP; ///< layer parameter name of the top component
static const string BASE; ///< layer parameter name of the base component
- static const string FG; ///< parameter of the mix node
- static const string BG; ///< parameter of the mix node
- static const string IN1; ///< parameter of the add and multiply nodes
- static const string IN2; ///< parameter of the add and multiply nodes
-
- static const string THICKNESS; ///< thickness parameter name of the thin_film_bsdf
- static const string IOR; ///< ior parameter name of the thin_film_bsdf
-
- static const string THIN_FILM_THICKNESS; ///< helper parameter name for transporting thickness
- static const string THIN_FILM_IOR; ///< helper parameter name for transporting ior
-
- static const string EMPTY; ///< the empty string ""
-};
-
-/// Helper class to be injected into nodes that need to carry thin film parameters from the
-/// thin_film_bsdf through layers and mixers, etc., to the elemental bsdfs that support thin film.
-/// Because thin-film can not be layered on any BSDF in MDL, we try to push down the parameters to
-/// the nodes that support thin-film.
-template class CarryThinFilmParameters : public TBase
-{
- public:
- /// Add the thin film inputs for transporting the parameter.
- /// `addInputs` for the injected base class is called first.
- void addInputs(ShaderNode& node, GenContext& context) const override
- {
- TBase::addInputs(node, context);
- node.addInput(StringConstantsMdl::THIN_FILM_THICKNESS, Type::FLOAT);
- node.addInput(StringConstantsMdl::THIN_FILM_IOR, Type::FLOAT);
- }
-
- /// Mark the thin film parameters as not editable because connections are
- /// created while emitting the MDL code and the default values should not
- /// get exposed to the public material interface.
- bool isEditable(const ShaderInput& input) const override
- {
- if (input.getName() == StringConstantsMdl::THIN_FILM_THICKNESS ||
- input.getName() == StringConstantsMdl::THIN_FILM_IOR)
- {
- return false;
- }
- return TBase::isEditable(input);
- }
};
/// Closure layer node implementation for MDL.
-class MX_GENMDL_API ClosureLayerNodeMdl : public CarryThinFilmParameters
+class MX_GENMDL_API ClosureLayerNodeMdl : public ShaderNodeImpl
{
public:
static ShaderNodeImplPtr create();
void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override;
-
- void emitBsdfOverBsdfFunctionCalls(
- const ShaderNode& node,
- GenContext& context,
- ShaderStage& stage,
- const ShaderGenerator& shadergen,
- ShaderNode* top,
- ShaderNode* base,
- ShaderOutput* output) const;
-
- void emitBsdfOverBsdfFunctionCalls_thinFilm(
- const ShaderNode& node,
- GenContext& context,
- ShaderStage& stage,
- const ShaderGenerator& shadergen,
- ShaderNode* top,
- ShaderNode* base,
- ShaderOutput* output) const;
};
/// Layerable BSDF node.
@@ -107,49 +47,6 @@ class MX_GENMDL_API LayerableNodeMdl : public SourceCodeNodeMdl
void addInputs(ShaderNode& node, GenContext&) const override;
};
-/// Used for elemental nodes that can consume thin film.
-class MX_GENMDL_API ThinFilmReceiverNodeMdl : public CarryThinFilmParameters
-{
- using Base = CarryThinFilmParameters;
-
- public:
- static ShaderNodeImplPtr create();
-};
-
-/// Base class for operators that on bsdfs that need to transport the thin film parameters
-class ThinFilmCombineNodeMdl : public CarryThinFilmParameters
-{
- using Base = CarryThinFilmParameters;
-
- public:
- virtual ~ThinFilmCombineNodeMdl() = default;
-
- void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override;
-
- protected:
- virtual const string& getOperatorName(size_t index) const = 0;
-};
-
-/// Used for mix_bsdf nodes.
-class MX_GENMDL_API MixBsdfNodeMdl : public ThinFilmCombineNodeMdl
-{
- public:
- static ShaderNodeImplPtr create();
-
- protected:
- virtual const string& getOperatorName(size_t index) const final;
-};
-
-/// Used for add_bsdf and multpli_bsdf nodes.
-class MX_GENMDL_API AddOrMultiplyBsdfNodeMdl : public ThinFilmCombineNodeMdl
-{
- public:
- static ShaderNodeImplPtr create();
-
- protected:
- virtual const string& getOperatorName(size_t index) const final;
-};
-
MATERIALX_NAMESPACE_END
#endif
diff --git a/source/MaterialXGenMdl/mdl/materialx/pbrlib.mdl b/source/MaterialXGenMdl/mdl/materialx/pbrlib.mdl
index 61234c4037..3f285890bd 100644
--- a/source/MaterialXGenMdl/mdl/materialx/pbrlib.mdl
+++ b/source/MaterialXGenMdl/mdl/materialx/pbrlib.mdl
@@ -147,13 +147,13 @@ export material mx_dielectric_bsdf(
color mxp_tint = color(1.0),
float mxp_ior = 1.5,
float2 mxp_roughness = float2(0.0),
+ float mxp_thinfilm_thickness = 0.0,
+ float mxp_thinfilm_ior = 1.0,
float3 mxp_normal = state::normal(),
float3 mxp_tangent = state::texture_tangent_u(0),
uniform mx_distribution_type mxp_distribution = mx_distribution_type_ggx [[ anno::unused() ]],
uniform mx_scatter_mode mxp_scatter_mode = mx_scatter_mode_R,
- material mxp_base = material() [[ anno::usage( "materialx:bsdf") ]],
- float mxp_thinfilm_thickness = 0.0,
- float mxp_thinfilm_ior = 1.0
+ material mxp_base = material() [[ anno::usage( "materialx:bsdf") ]]
) [[
anno::usage( "materialx:bsdf")
]]
@@ -220,11 +220,11 @@ export material mx_conductor_bsdf(
color mxp_ior = color(0.18, 0.42, 1.37),
color mxp_extinction = color(3.42, 2.35, 1.77),
float2 mxp_roughness = float2(0.0),
+ float mxp_thinfilm_thickness = 0.0,
+ float mxp_thinfilm_ior = 1.0,
float3 mxp_normal = state::normal(),
float3 mxp_tangent = state::texture_tangent_u(0),
- uniform mx_distribution_type mxp_distribution = mx_distribution_type_ggx [[ anno::unused() ]],
- float mxp_thinfilm_thickness = 0.0,
- float mxp_thinfilm_ior = 1.0
+ uniform mx_distribution_type mxp_distribution = mx_distribution_type_ggx [[ anno::unused() ]]
) [[
anno::usage( "materialx:bsdf")
]]
@@ -261,13 +261,13 @@ export material mx_generalized_schlick_bsdf(
color mxp_color90 = color(1.0),
float mxp_exponent = 5.0,
float2 mxp_roughness = float2(0.05),
+ float mxp_thinfilm_thickness = 0.0,
+ float mxp_thinfilm_ior = 1.0,
float3 mxp_normal = state::normal(),
float3 mxp_tangent = state::texture_tangent_u(0),
uniform mx_distribution_type mxp_distribution = mx_distribution_type_ggx [[ anno::unused() ]],
uniform mx_scatter_mode mxp_scatter_mode = mx_scatter_mode_R,
- material mxp_base = material() [[ anno::usage( "materialx:bsdf") ]],
- float mxp_thinfilm_thickness = 0.0,
- float mxp_thinfilm_ior = 1.0
+ material mxp_base = material() [[ anno::usage( "materialx:bsdf") ]]
) [[
anno::usage( "materialx:bsdf")
]]
@@ -399,26 +399,6 @@ export material mx_sheen_bsdf(
volume: mxp_base.volume
);
-export material mx_thin_film_bsdf(
- float mxp_thickness = 1000.0,
- float mxp_ior = 1.5,
- material mxp_base = material() [[ anno::usage( "materialx:bsdf") ]]
-) [[
- anno::usage( "materialx:bsdf")
-]]
-= material(
- surface: material_surface(
- scattering: df::thin_film(
- thickness: mxp_thickness,
- ior: color(mxp_ior),
- base: mxp_base.surface.scattering
- )
- ),
- // we need to carry volume properties along for SSS
- ior: mxp_base.ior,
- volume: mxp_base.volume
-);
-
// EDF Nodes
export material mx_uniform_edf(
diff --git a/source/MaterialXGenOsl/Nodes/ClosureLayerNodeOsl.cpp b/source/MaterialXGenOsl/Nodes/ClosureLayerNodeOsl.cpp
index 7c3f9d460c..b77eebbd86 100644
--- a/source/MaterialXGenOsl/Nodes/ClosureLayerNodeOsl.cpp
+++ b/source/MaterialXGenOsl/Nodes/ClosureLayerNodeOsl.cpp
@@ -41,111 +41,68 @@ void ClosureLayerNodeOsl::emitFunctionCall(const ShaderNode& _node, GenContext&
ClosureContext* cct = context.getClosureContext();
- if (top->hasClassification(ShaderNode::Classification::THINFILM))
+ // Evaluate top and base nodes and combine their result
+ // according to throughput.
+ //
+ // TODO: In the BSDF over BSDF case should we emit code
+ // to check the top throughput amount before calling
+ // the base BSDF?
+
+ // Make sure the connections are sibling nodes and not the graph interface.
+ if (top->getParent() == node.getParent())
{
- // This is a layer node with thin-film as top layer.
- // Call only the base BSDF but with thin-film parameters set.
-
- // Make sure the connection to base is a sibling node and not the graph interface.
- if (base->getParent() != node.getParent())
- {
- throw ExceptionShaderGenError("Thin-film can only be applied to a sibling node, not through a graph interface");
- }
-
- // Set the extra parameters for thin-film.
- ClosureContext::ClosureParams params;
- params[THICKNESS] = top->getInput(THICKNESS);
- params[IOR] = top->getInput(IOR);
- ScopedSetClosureParams setParams(¶ms, base, cct);
+ // If this layer node has closure parameters set,
+ // we pass this on to the top component only.
+ ScopedSetClosureParams setParams(&node, top, cct);
+ shadergen.emitFunctionCall(*top, context, stage);
+ }
+ if (base->getParent() == node.getParent())
+ {
+ shadergen.emitFunctionCall(*base, context, stage);
+ }
- // Store the base result in the layer result variable.
- ScopedSetVariableName setVariable(output->getVariable(), base->getOutput());
+ // Get the result variables.
+ const string& topResult = topInput->getConnection()->getVariable();
+ const string& baseResult = baseInput->getConnection()->getVariable();
- // Emit the function call.
- shadergen.emitFunctionCall(*base, context, stage);
+ // Calculate the layering result.
+ emitOutputVariables(node, context, stage);
+ if (base->getOutput()->getType() == Type::VDF)
+ {
+ // Combining a surface closure with a volumetric closure is simply done with the add operator in OSL.
+ shadergen.emitLine(output->getVariable() + ".response = " + topResult + ".response + " + baseResult, stage);
+ // Just pass the throughput along.
+ shadergen.emitLine(output->getVariable() + ".throughput = " + topResult + ".throughput", stage);
}
else
{
- // Evaluate top and base nodes and combine their result
- // according to throughput.
- //
- // TODO: In the BSDF over BSDF case should we emit code
- // to check the top throughput amount before calling
- // the base BSDF?
-
- // Make sure the connections are sibling nodes and not the graph interface.
- if (top->getParent() == node.getParent())
- {
- // If this layer node has closure parameters set,
- // we pass this on to the top component only.
- ScopedSetClosureParams setParams(&node, top, cct);
- shadergen.emitFunctionCall(*top, context, stage);
- }
- if (base->getParent() == node.getParent())
- {
- shadergen.emitFunctionCall(*base, context, stage);
- }
-
- // Get the result variables.
- const string& topResult = topInput->getConnection()->getVariable();
- const string& baseResult = baseInput->getConnection()->getVariable();
-
- // Calculate the layering result.
- emitOutputVariables(node, context, stage);
- if (base->getOutput()->getType() == Type::VDF)
- {
- // Combining a surface closure with a volumetric closure is simply done with the add operator in OSL.
- shadergen.emitLine(output->getVariable() + ".response = " + topResult + ".response + " + baseResult, stage);
- // Just pass the throughput along.
- shadergen.emitLine(output->getVariable() + ".throughput = " + topResult + ".throughput", stage);
- }
- else
- {
- shadergen.emitLine(output->getVariable() + ".response = " + topResult + ".response + " + baseResult + ".response * " + topResult + ".throughput", stage);
- shadergen.emitLine(output->getVariable() + ".throughput = " + topResult + ".throughput * " + baseResult + ".throughput", stage);
- }
+ shadergen.emitLine(output->getVariable() + ".response = " + topResult + ".response + " + baseResult + ".response * " + topResult + ".throughput", stage);
+ shadergen.emitLine(output->getVariable() + ".throughput = " + topResult + ".throughput * " + baseResult + ".throughput", stage);
}
#else
- if (top->hasClassification(ShaderNode::Classification::THINFILM))
+ // Emit the function call for top and base layer.
+ // Make sure the connections are sibling nodes and not the graph interface.
+ if (top->getParent() == node.getParent())
{
- // Make sure the connection to base is a sibling node and not the graph interface.
- if (base->getParent() != node.getParent())
- {
- throw ExceptionShaderGenError("Thin-film can only be applied to a sibling node, not through a graph interface");
- }
-
- // TODO: Thin-film is not supported yet.
- // Emit the function call for base layer but
- // store the base result in the layer result variable.
- ScopedSetVariableName setVariable(output->getVariable(), base->getOutput());
- shadergen.emitFunctionCall(*base, context, stage);
+ shadergen.emitFunctionCall(*top, context, stage);
}
- else
+ if (base->getParent() == node.getParent())
{
- // Emit the function call for top and base layer.
- // Make sure the connections are sibling nodes and not the graph interface.
- if (top->getParent() == node.getParent())
- {
- shadergen.emitFunctionCall(*top, context, stage);
- }
- if (base->getParent() == node.getParent())
- {
- shadergen.emitFunctionCall(*base, context, stage);
- }
-
- // Get the result variables.
- const string& topResult = topInput->getConnection()->getVariable();
- const string& baseResult = baseInput->getConnection()->getVariable();
-
- // Emit the layer closure call.
- shadergen.emitLineBegin(stage);
- shadergen.emitOutput(output, true, false, context, stage);
- shadergen.emitString(" = layer(" + topResult + ", " + baseResult + ")", stage);
- shadergen.emitLineEnd(stage);
+ shadergen.emitFunctionCall(*base, context, stage);
}
+ // Get the result variables.
+ const string& topResult = topInput->getConnection()->getVariable();
+ const string& baseResult = baseInput->getConnection()->getVariable();
+
+ // Emit the layer closure call.
+ shadergen.emitLineBegin(stage);
+ shadergen.emitOutput(output, true, false, context, stage);
+ shadergen.emitString(" = layer(" + topResult + ", " + baseResult + ")", stage);
+ shadergen.emitLineEnd(stage);
+
#endif // MATERIALX_OSL_LEGACY_CLOSURES
}
diff --git a/source/MaterialXGenOsl/OslSyntax.cpp b/source/MaterialXGenOsl/OslSyntax.cpp
index d421c5e3d9..68888c6440 100644
--- a/source/MaterialXGenOsl/OslSyntax.cpp
+++ b/source/MaterialXGenOsl/OslSyntax.cpp
@@ -451,10 +451,10 @@ OslSyntax::OslSyntax()
Type::BSDF,
std::make_shared(
"BSDF",
- "BSDF(null_closure, color(1.0), 0.0, 0.0)",
- "{ 0, color(1.0), 0.0, 0.0 }",
+ "BSDF(null_closure, color(1.0))",
+ "{ 0, color(1.0) }",
"closure color",
- "struct BSDF { closure color response; color throughput; float thickness; float ior; };"));
+ "struct BSDF { closure color response; color throughput; };"));
#else
diff --git a/source/MaterialXGenShader/Nodes/ClosureLayerNode.cpp b/source/MaterialXGenShader/Nodes/ClosureLayerNode.cpp
index a2554365c1..32127de997 100644
--- a/source/MaterialXGenShader/Nodes/ClosureLayerNode.cpp
+++ b/source/MaterialXGenShader/Nodes/ClosureLayerNode.cpp
@@ -12,8 +12,6 @@ MATERIALX_NAMESPACE_BEGIN
const string ClosureLayerNode::TOP = "top";
const string ClosureLayerNode::BASE = "base";
-const string ClosureLayerNode::THICKNESS = "thickness";
-const string ClosureLayerNode::IOR = "ior";
ShaderNodeImplPtr ClosureLayerNode::create()
{
@@ -44,67 +42,41 @@ void ClosureLayerNode::emitFunctionCall(const ShaderNode& _node, GenContext& con
ShaderNode* top = topInput->getConnection()->getNode();
ShaderNode* base = baseInput->getConnection()->getNode();
- if (top->hasClassification(ShaderNode::Classification::THINFILM))
- {
- // This is a layer node with thin-film as top layer.
- // Call only the base BSDF but with thin-film parameters set.
-
- // Make sure the connection to base is a sibling node and not the graph interface.
- if (base->getParent() != node.getParent())
- {
- throw ExceptionShaderGenError("Thin-film can only be applied to a sibling node, not through a graph interface");
- }
+ // Evaluate top and base nodes and combine their result
+ // according to throughput.
+ //
+ // TODO: In the BSDF over BSDF case should we emit code
+ // to check the top throughput amount before calling
+ // the base BSDF?
- // Set the extra parameters for thin-film.
- ClosureContext::ClosureParams params;
- params[THICKNESS] = top->getInput(THICKNESS);
- params[IOR] = top->getInput(IOR);
- ScopedSetClosureParams setParams(¶ms, base, cct);
+ // Make sure the connections are sibling nodes and not the graph interface.
+ if (top->getParent() == node.getParent())
+ {
+ // If this layer node has closure parameters set,
+ // we pass this on to the top component only.
+ ScopedSetClosureParams setParams(&node, top, cct);
+ shadergen.emitFunctionCall(*top, context, stage);
+ }
+ if (base->getParent() == node.getParent())
+ {
+ shadergen.emitFunctionCall(*base, context, stage);
+ }
- // Store the base result in the layer result variable.
- ScopedSetVariableName setVariable(output->getVariable(), base->getOutput());
+ // Get the result variables.
+ const string& topResult = topInput->getConnection()->getVariable();
+ const string& baseResult = baseInput->getConnection()->getVariable();
- // Emit the function call.
- shadergen.emitFunctionCall(*base, context, stage);
+ // Calculate the layering result.
+ emitOutputVariables(node, context, stage);
+ if (base->getOutput()->getType() == Type::VDF)
+ {
+ shadergen.emitLine(output->getVariable() + ".response = " + topResult + ".response * " + baseResult + ".throughput", stage);
+ shadergen.emitLine(output->getVariable() + ".throughput = " + topResult + ".throughput * " + baseResult + ".throughput", stage);
}
else
{
- // Evaluate top and base nodes and combine their result
- // according to throughput.
- //
- // TODO: In the BSDF over BSDF case should we emit code
- // to check the top throughput amount before calling
- // the base BSDF?
-
- // Make sure the connections are sibling nodes and not the graph interface.
- if (top->getParent() == node.getParent())
- {
- // If this layer node has closure parameters set,
- // we pass this on to the top component only.
- ScopedSetClosureParams setParams(&node, top, cct);
- shadergen.emitFunctionCall(*top, context, stage);
- }
- if (base->getParent() == node.getParent())
- {
- shadergen.emitFunctionCall(*base, context, stage);
- }
-
- // Get the result variables.
- const string& topResult = topInput->getConnection()->getVariable();
- const string& baseResult = baseInput->getConnection()->getVariable();
-
- // Calculate the layering result.
- emitOutputVariables(node, context, stage);
- if (base->getOutput()->getType() == Type::VDF)
- {
- shadergen.emitLine(output->getVariable() + ".response = " + topResult + ".response * " + baseResult + ".throughput", stage);
- shadergen.emitLine(output->getVariable() + ".throughput = " + topResult + ".throughput * " + baseResult + ".throughput", stage);
- }
- else
- {
- shadergen.emitLine(output->getVariable() + ".response = " + topResult + ".response + " + baseResult + ".response * " + topResult + ".throughput", stage);
- shadergen.emitLine(output->getVariable() + ".throughput = " + topResult + ".throughput * " + baseResult + ".throughput", stage);
- }
+ shadergen.emitLine(output->getVariable() + ".response = " + topResult + ".response + " + baseResult + ".response * " + topResult + ".throughput", stage);
+ shadergen.emitLine(output->getVariable() + ".throughput = " + topResult + ".throughput * " + baseResult + ".throughput", stage);
}
}
}