From 005822fe7938a8e29c899d955b3f2f6132ea8284 Mon Sep 17 00:00:00 2001 From: Niklas Harrysson Date: Sun, 31 Jul 2022 12:34:35 +0200 Subject: [PATCH 1/5] Initial changes to support new OSL closures in MaterialXGenOsl --- CMakeLists.txt | 4 ++ .../genosl/legacy/mx_anisotropic_vdf.osl | 5 ++ .../{ => legacy}/mx_burley_diffuse_bsdf.osl | 0 .../genosl/{ => legacy}/mx_conductor_bsdf.osl | 0 .../genosl/legacy/mx_dielectric_bsdf.osl | 36 +++++++++++++ .../legacy/mx_generalized_schlick_bsdf.osl | 38 +++++++++++++ .../mx_oren_nayar_diffuse_bsdf.osl | 0 .../genosl/{ => legacy}/mx_sheen_bsdf.osl | 0 .../genosl/legacy/mx_subsurface_bsdf.osl | 5 ++ libraries/pbrlib/genosl/legacy/mx_surface.osl | 5 ++ .../{ => legacy}/mx_translucent_bsdf.osl | 0 .../pbrlib/genosl/mx_anisotropic_vdf.osl | 5 +- .../pbrlib/genosl/mx_dielectric_bsdf.osl | 31 ++--------- .../genosl/mx_generalized_schlick_bsdf.osl | 39 +++----------- .../pbrlib/genosl/mx_subsurface_bsdf.osl | 3 +- libraries/pbrlib/genosl/mx_surface.osl | 2 +- libraries/pbrlib/genosl/mx_uniform_edf.inline | 1 - .../pbrlib/genosl/pbrlib_genosl_impl.mtlx | 54 +++++++++++++++++-- .../Nodes/ClosureLayerNodeOsl.cpp | 41 +++++++++++++- source/MaterialXGenOsl/OslShaderGenerator.cpp | 3 ++ source/MaterialXGenOsl/OslSyntax.cpp | 16 ++++++ 21 files changed, 219 insertions(+), 69 deletions(-) create mode 100644 libraries/pbrlib/genosl/legacy/mx_anisotropic_vdf.osl rename libraries/pbrlib/genosl/{ => legacy}/mx_burley_diffuse_bsdf.osl (100%) rename libraries/pbrlib/genosl/{ => legacy}/mx_conductor_bsdf.osl (100%) create mode 100644 libraries/pbrlib/genosl/legacy/mx_dielectric_bsdf.osl create mode 100644 libraries/pbrlib/genosl/legacy/mx_generalized_schlick_bsdf.osl rename libraries/pbrlib/genosl/{ => legacy}/mx_oren_nayar_diffuse_bsdf.osl (100%) rename libraries/pbrlib/genosl/{ => legacy}/mx_sheen_bsdf.osl (100%) create mode 100644 libraries/pbrlib/genosl/legacy/mx_subsurface_bsdf.osl create mode 100644 libraries/pbrlib/genosl/legacy/mx_surface.osl rename libraries/pbrlib/genosl/{ => legacy}/mx_translucent_bsdf.osl (100%) delete mode 100644 libraries/pbrlib/genosl/mx_uniform_edf.inline diff --git a/CMakeLists.txt b/CMakeLists.txt index 07a4a782b4..3176993844 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,6 +51,8 @@ option(MATERIALX_TEST_RENDER "Run rendering tests for MaterialX Render module. G option(MATERIALX_WARNINGS_AS_ERRORS "Interpret all compiler warnings as errors." OFF) option(MATERIALX_DYNAMIC_ANALYSIS "Build MaterialX libraries with dynamic analysis on supporting platforms." OFF) +option(MATERIALX_OSL_LEGACY_CLOSURES "Code generation support for the old legacy OSL closures." OFF) + set(MATERIALX_PYTHON_VERSION "" CACHE STRING "Python version to be used in building the MaterialX Python package (e.g. '2.7').") set(MATERIALX_PYTHON_EXECUTABLE "" CACHE FILEPATH @@ -119,6 +121,7 @@ mark_as_advanced(MATERIALX_PYTHON_EXECUTABLE) mark_as_advanced(MATERIALX_PYTHON_OCIO_DIR) mark_as_advanced(MATERIALX_PYTHON_PYBIND11_DIR) mark_as_advanced(MATERIALX_OIIO_DIR) +mark_as_advanced(MATERIALX_OSL_LEGACY_CLOSURES) mark_as_advanced(MATERIALX_OSL_BINARY_OSLC) mark_as_advanced(MATERIALX_OSL_BINARY_TESTRENDER) mark_as_advanced(MATERIALX_OSL_INCLUDE_PATH) @@ -136,6 +139,7 @@ if (MATERIALX_BUILD_GEN_MDL) endif() # Add global definitions +add_definitions(-DMATERIALX_OSL_LEGACY_CLOSURES=${MATERIALX_OSL_LEGACY_CLOSURES}) add_definitions(-DMATERIALX_OSL_BINARY_OSLC=\"${MATERIALX_OSL_BINARY_OSLC}\") add_definitions(-DMATERIALX_OSL_BINARY_TESTRENDER=\"${MATERIALX_OSL_BINARY_TESTRENDER}\") add_definitions(-DMATERIALX_OSL_INCLUDE_PATH=\"${MATERIALX_OSL_INCLUDE_PATH}\") diff --git a/libraries/pbrlib/genosl/legacy/mx_anisotropic_vdf.osl b/libraries/pbrlib/genosl/legacy/mx_anisotropic_vdf.osl new file mode 100644 index 0000000000..6d52e08509 --- /dev/null +++ b/libraries/pbrlib/genosl/legacy/mx_anisotropic_vdf.osl @@ -0,0 +1,5 @@ +void mx_anisotropic_vdf(vector absorption, vector scattering, float anisotropy, output VDF vdf) +{ + // Not implemented in vanilla OSL + vdf = 0; // volume_henyey_greenstein(color(absorption), color(scattering), color(0.0), anisotropy); +} diff --git a/libraries/pbrlib/genosl/mx_burley_diffuse_bsdf.osl b/libraries/pbrlib/genosl/legacy/mx_burley_diffuse_bsdf.osl similarity index 100% rename from libraries/pbrlib/genosl/mx_burley_diffuse_bsdf.osl rename to libraries/pbrlib/genosl/legacy/mx_burley_diffuse_bsdf.osl diff --git a/libraries/pbrlib/genosl/mx_conductor_bsdf.osl b/libraries/pbrlib/genosl/legacy/mx_conductor_bsdf.osl similarity index 100% rename from libraries/pbrlib/genosl/mx_conductor_bsdf.osl rename to libraries/pbrlib/genosl/legacy/mx_conductor_bsdf.osl diff --git a/libraries/pbrlib/genosl/legacy/mx_dielectric_bsdf.osl b/libraries/pbrlib/genosl/legacy/mx_dielectric_bsdf.osl new file mode 100644 index 0000000000..15b4291546 --- /dev/null +++ b/libraries/pbrlib/genosl/legacy/mx_dielectric_bsdf.osl @@ -0,0 +1,36 @@ +#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) +{ + if (scatter_mode == "T") + { + bsdf.response = tint * weight * microfacet(distribution, N, U, roughness.x, roughness.y, ior, 1); + bsdf.throughput = tint * weight; + return; + } + + float NdotV = clamp(dot(N,-I), M_FLOAT_EPS, 1.0); + float F0 = mx_ior_to_f0(ior); + float F = mx_fresnel_schlick(NdotV, F0); + + // Calculate compensation for multiple scattering. + // This should normally be done inside the closure + // but since vanilla OSL doesen't support this we + // add it here in shader code instead. + vector2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0); + float avgAlpha = mx_average_alpha(safeAlpha); + float comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F); + + // Calculate throughput from directional albedo. + float dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, ior) * comp; + bsdf.throughput = 1.0 - dirAlbedo * weight; + + if (scatter_mode == "R") + { + bsdf.response = tint * weight * comp * microfacet(distribution, N, U, safeAlpha.x, safeAlpha.y, ior, 0); + } + else + { + bsdf.response = tint * weight * comp * microfacet(distribution, N, U, safeAlpha.x, safeAlpha.y, ior, 2); + } +} diff --git a/libraries/pbrlib/genosl/legacy/mx_generalized_schlick_bsdf.osl b/libraries/pbrlib/genosl/legacy/mx_generalized_schlick_bsdf.osl new file mode 100644 index 0000000000..0fac609523 --- /dev/null +++ b/libraries/pbrlib/genosl/legacy/mx_generalized_schlick_bsdf.osl @@ -0,0 +1,38 @@ +#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) +{ + float avgF0 = dot(color0, color(1.0 / 3.0)); + float ior = mx_f0_to_ior(avgF0); + + if (scatter_mode == "T") + { + bsdf.response = weight * microfacet(distribution, N, U, roughness.x, roughness.y, ior, 1); + bsdf.throughput = weight; + return; + } + + float NdotV = fabs(dot(N,-I)); + color F = mx_fresnel_schlick(NdotV, color0, color90, exponent); + + // Calculate compensation for multiple scattering. + // This should normally be done inside the closure + // but since vanilla OSL doesen't support this we + // add it here in shader code instead. + vector2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0); + float avgAlpha = mx_average_alpha(safeAlpha); + color comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F); + + // Calculate throughput from directional albedo. + color dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, color0, color90) * comp; + float avgDirAlbedo = dot(dirAlbedo, color(1.0 / 3.0)); + bsdf.throughput = 1.0 - avgDirAlbedo * weight; + + // Calculate the reflection response, setting IOR to zero to disable internal Fresnel. + bsdf.response = F * comp * weight * microfacet(distribution, N, U, safeAlpha.x, safeAlpha.y, 0.0, 0); + + if (scatter_mode == "RT") + { + bsdf.response += bsdf.throughput * microfacet(distribution, N, U, safeAlpha.x, safeAlpha.y, ior, 1); + } +} diff --git a/libraries/pbrlib/genosl/mx_oren_nayar_diffuse_bsdf.osl b/libraries/pbrlib/genosl/legacy/mx_oren_nayar_diffuse_bsdf.osl similarity index 100% rename from libraries/pbrlib/genosl/mx_oren_nayar_diffuse_bsdf.osl rename to libraries/pbrlib/genosl/legacy/mx_oren_nayar_diffuse_bsdf.osl diff --git a/libraries/pbrlib/genosl/mx_sheen_bsdf.osl b/libraries/pbrlib/genosl/legacy/mx_sheen_bsdf.osl similarity index 100% rename from libraries/pbrlib/genosl/mx_sheen_bsdf.osl rename to libraries/pbrlib/genosl/legacy/mx_sheen_bsdf.osl diff --git a/libraries/pbrlib/genosl/legacy/mx_subsurface_bsdf.osl b/libraries/pbrlib/genosl/legacy/mx_subsurface_bsdf.osl new file mode 100644 index 0000000000..826eee2bd6 --- /dev/null +++ b/libraries/pbrlib/genosl/legacy/mx_subsurface_bsdf.osl @@ -0,0 +1,5 @@ +void mx_subsurface_bsdf(float weight, color _color, vector radius, float anisotropy, normal N, output BSDF bsdf) +{ + // TODO: Subsurface closure is not supported by vanilla OSL. + bsdf = _color * weight * diffuse(N); +} diff --git a/libraries/pbrlib/genosl/legacy/mx_surface.osl b/libraries/pbrlib/genosl/legacy/mx_surface.osl new file mode 100644 index 0000000000..b9a3c443d8 --- /dev/null +++ b/libraries/pbrlib/genosl/legacy/mx_surface.osl @@ -0,0 +1,5 @@ +void mx_surface(BSDF bsdf, EDF edf, float opacity, output surfaceshader result) +{ + float opacity_weight = clamp(opacity, 0.0, 1.0); + result = (bsdf.response + edf) * opacity_weight + transparent() * (1.0 - opacity_weight); +} diff --git a/libraries/pbrlib/genosl/mx_translucent_bsdf.osl b/libraries/pbrlib/genosl/legacy/mx_translucent_bsdf.osl similarity index 100% rename from libraries/pbrlib/genosl/mx_translucent_bsdf.osl rename to libraries/pbrlib/genosl/legacy/mx_translucent_bsdf.osl diff --git a/libraries/pbrlib/genosl/mx_anisotropic_vdf.osl b/libraries/pbrlib/genosl/mx_anisotropic_vdf.osl index 6d52e08509..6b2a7d5298 100644 --- a/libraries/pbrlib/genosl/mx_anisotropic_vdf.osl +++ b/libraries/pbrlib/genosl/mx_anisotropic_vdf.osl @@ -1,5 +1,6 @@ void mx_anisotropic_vdf(vector absorption, vector scattering, float anisotropy, output VDF vdf) { - // Not implemented in vanilla OSL - vdf = 0; // volume_henyey_greenstein(color(absorption), color(scattering), color(0.0), anisotropy); + // TODO: Need to remap parameters to match the new closure, + // or change the MaterialX spec to OSL parameterization. + vdf = 0; } diff --git a/libraries/pbrlib/genosl/mx_dielectric_bsdf.osl b/libraries/pbrlib/genosl/mx_dielectric_bsdf.osl index 15b4291546..69773b3ced 100644 --- a/libraries/pbrlib/genosl/mx_dielectric_bsdf.osl +++ b/libraries/pbrlib/genosl/mx_dielectric_bsdf.osl @@ -1,36 +1,15 @@ -#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) { - if (scatter_mode == "T") + if (scatter_mode == "R") { - bsdf.response = tint * weight * microfacet(distribution, N, U, roughness.x, roughness.y, ior, 1); - bsdf.throughput = tint * weight; - return; + bsdf = weight * dielectric_bsdf(N, U, tint, color(0.0), roughness.x, roughness.y, ior, distribution); } - - float NdotV = clamp(dot(N,-I), M_FLOAT_EPS, 1.0); - float F0 = mx_ior_to_f0(ior); - float F = mx_fresnel_schlick(NdotV, F0); - - // Calculate compensation for multiple scattering. - // This should normally be done inside the closure - // but since vanilla OSL doesen't support this we - // add it here in shader code instead. - vector2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0); - float avgAlpha = mx_average_alpha(safeAlpha); - float comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F); - - // Calculate throughput from directional albedo. - float dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, ior) * comp; - bsdf.throughput = 1.0 - dirAlbedo * weight; - - if (scatter_mode == "R") + else if (scatter_mode == "T") { - bsdf.response = tint * weight * comp * microfacet(distribution, N, U, safeAlpha.x, safeAlpha.y, ior, 0); + bsdf = weight * dielectric_bsdf(N, U, color(0.0), tint, roughness.x, roughness.y, ior, distribution); } else { - bsdf.response = tint * weight * comp * microfacet(distribution, N, U, safeAlpha.x, safeAlpha.y, ior, 2); + bsdf = weight * dielectric_bsdf(N, U, tint, tint, roughness.x, roughness.y, ior, distribution); } } diff --git a/libraries/pbrlib/genosl/mx_generalized_schlick_bsdf.osl b/libraries/pbrlib/genosl/mx_generalized_schlick_bsdf.osl index 0fac609523..a8f74de0a3 100644 --- a/libraries/pbrlib/genosl/mx_generalized_schlick_bsdf.osl +++ b/libraries/pbrlib/genosl/mx_generalized_schlick_bsdf.osl @@ -1,38 +1,15 @@ -#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) { - float avgF0 = dot(color0, color(1.0 / 3.0)); - float ior = mx_f0_to_ior(avgF0); - - if (scatter_mode == "T") + if (scatter_mode == "R") { - bsdf.response = weight * microfacet(distribution, N, U, roughness.x, roughness.y, ior, 1); - bsdf.throughput = weight; - return; + bsdf = weight * generalized_schlick_bsdf(N, U, tint, color(0.0), roughness.x, roughness.y, color0, color90, exponent, distribution); } - - float NdotV = fabs(dot(N,-I)); - color F = mx_fresnel_schlick(NdotV, color0, color90, exponent); - - // Calculate compensation for multiple scattering. - // This should normally be done inside the closure - // but since vanilla OSL doesen't support this we - // add it here in shader code instead. - vector2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0); - float avgAlpha = mx_average_alpha(safeAlpha); - color comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F); - - // Calculate throughput from directional albedo. - color dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, color0, color90) * comp; - float avgDirAlbedo = dot(dirAlbedo, color(1.0 / 3.0)); - bsdf.throughput = 1.0 - avgDirAlbedo * weight; - - // Calculate the reflection response, setting IOR to zero to disable internal Fresnel. - bsdf.response = F * comp * weight * microfacet(distribution, N, U, safeAlpha.x, safeAlpha.y, 0.0, 0); - - if (scatter_mode == "RT") + else if (scatter_mode == "T") { - bsdf.response += bsdf.throughput * microfacet(distribution, N, U, safeAlpha.x, safeAlpha.y, ior, 1); + bsdf = weight * generalized_schlick_bsdf(N, U, color(0.0), tint, roughness.x, roughness.y, color0, color90, exponent, distribution); + } + else + { + bsdf = weight * generalized_schlick_bsdf(N, U, tint, tint, roughness.x, roughness.y, color0, color90, exponent, distribution); } } diff --git a/libraries/pbrlib/genosl/mx_subsurface_bsdf.osl b/libraries/pbrlib/genosl/mx_subsurface_bsdf.osl index 17a4aff2cb..826eee2bd6 100644 --- a/libraries/pbrlib/genosl/mx_subsurface_bsdf.osl +++ b/libraries/pbrlib/genosl/mx_subsurface_bsdf.osl @@ -1,6 +1,5 @@ void mx_subsurface_bsdf(float weight, color _color, vector radius, float anisotropy, normal N, output BSDF bsdf) { // TODO: Subsurface closure is not supported by vanilla OSL. - bsdf.response = _color * weight * diffuse(N); - bsdf.throughput = color(0.0); + bsdf = _color * weight * diffuse(N); } diff --git a/libraries/pbrlib/genosl/mx_surface.osl b/libraries/pbrlib/genosl/mx_surface.osl index b9a3c443d8..a997b47fe4 100644 --- a/libraries/pbrlib/genosl/mx_surface.osl +++ b/libraries/pbrlib/genosl/mx_surface.osl @@ -1,5 +1,5 @@ void mx_surface(BSDF bsdf, EDF edf, float opacity, output surfaceshader result) { float opacity_weight = clamp(opacity, 0.0, 1.0); - result = (bsdf.response + edf) * opacity_weight + transparent() * (1.0 - opacity_weight); + result = (bsdf + edf) * opacity_weight + transparent() * (1.0 - opacity_weight); } diff --git a/libraries/pbrlib/genosl/mx_uniform_edf.inline b/libraries/pbrlib/genosl/mx_uniform_edf.inline deleted file mode 100644 index aabebe91ab..0000000000 --- a/libraries/pbrlib/genosl/mx_uniform_edf.inline +++ /dev/null @@ -1 +0,0 @@ -{{color}} * emission() diff --git a/libraries/pbrlib/genosl/pbrlib_genosl_impl.mtlx b/libraries/pbrlib/genosl/pbrlib_genosl_impl.mtlx index f2748f7cba..5c995b4caf 100644 --- a/libraries/pbrlib/genosl/pbrlib_genosl_impl.mtlx +++ b/libraries/pbrlib/genosl/pbrlib_genosl_impl.mtlx @@ -2,57 +2,101 @@ - + + - + + - + + + - + + + + + + - + + + + + + + + + + + + + + diff --git a/source/MaterialXGenOsl/Nodes/ClosureLayerNodeOsl.cpp b/source/MaterialXGenOsl/Nodes/ClosureLayerNodeOsl.cpp index 051360eeb8..79f1be8ffc 100644 --- a/source/MaterialXGenOsl/Nodes/ClosureLayerNodeOsl.cpp +++ b/source/MaterialXGenOsl/Nodes/ClosureLayerNodeOsl.cpp @@ -19,7 +19,6 @@ ShaderNodeImplPtr ClosureLayerNodeOsl::create() void ClosureLayerNodeOsl::emitFunctionCall(const ShaderNode& _node, GenContext& context, ShaderStage& stage) const { const ShaderGenerator& shadergen = context.getShaderGenerator(); - ClosureContext* cct = context.getClosureContext(); ShaderNode& node = const_cast(_node); @@ -38,6 +37,8 @@ void ClosureLayerNodeOsl::emitFunctionCall(const ShaderNode& _node, GenContext& ShaderNode* top = topInput->getConnection()->getNode(); ShaderNode* base = baseInput->getConnection()->getNode(); +#if MATERIALX_OSL_LEGACY_CLOSURES + if (top->hasClassification(ShaderNode::Classification::THINFILM)) { // This is a layer node with thin-film as top layer. @@ -49,6 +50,8 @@ void ClosureLayerNodeOsl::emitFunctionCall(const ShaderNode& _node, GenContext& throw ExceptionShaderGenError("Thin-film can only be applied to a sibling node, not through a graph interface"); } + ClosureContext* cct = context.getClosureContext(); + // Set the extra parameters for thin-film. ClosureContext::ClosureParams params; params[THICKNESS] = top->getInput(THICKNESS); @@ -102,6 +105,42 @@ void ClosureLayerNodeOsl::emitFunctionCall(const ShaderNode& _node, GenContext& shadergen.emitLine(output->getVariable() + ".throughput = " + topResult + ".throughput * " + baseResult + ".throughput", stage); } } + +#else + + if (top->hasClassification(ShaderNode::Classification::THINFILM)) + { + // 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); + } + else + { + // Emit the function call for top and base layer. + shadergen.emitFunctionCall(*top, context, 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 + } MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenOsl/OslShaderGenerator.cpp b/source/MaterialXGenOsl/OslShaderGenerator.cpp index 1d4c6834aa..170e430ad7 100644 --- a/source/MaterialXGenOsl/OslShaderGenerator.cpp +++ b/source/MaterialXGenOsl/OslShaderGenerator.cpp @@ -165,6 +165,8 @@ OslShaderGenerator::OslShaderGenerator() : // registerImplementation("IM_layer_bsdf_" + OslShaderGenerator::TARGET, ClosureLayerNodeOsl::create); registerImplementation("IM_layer_vdf_" + OslShaderGenerator::TARGET, ClosureLayerNodeOsl::create); + +#if MATERIALX_OSL_LEGACY_CLOSURES // registerImplementation("IM_mix_bsdf_" + OslShaderGenerator::TARGET, ClosureMixNode::create); registerImplementation("IM_mix_edf_" + OslShaderGenerator::TARGET, ClosureMixNode::create); @@ -176,6 +178,7 @@ OslShaderGenerator::OslShaderGenerator() : registerImplementation("IM_multiply_bsdfF_" + OslShaderGenerator::TARGET, ClosureMultiplyNode::create); registerImplementation("IM_multiply_edfC_" + OslShaderGenerator::TARGET, ClosureMultiplyNode::create); registerImplementation("IM_multiply_edfF_" + OslShaderGenerator::TARGET, ClosureMultiplyNode::create); +#endif // MATERIALX_OSL_LEGACY_CLOSURES // registerImplementation("IM_thin_film_bsdf_" + OslShaderGenerator::TARGET, NopNode::create); diff --git a/source/MaterialXGenOsl/OslSyntax.cpp b/source/MaterialXGenOsl/OslSyntax.cpp index 8a68b06561..c0d3848a35 100644 --- a/source/MaterialXGenOsl/OslSyntax.cpp +++ b/source/MaterialXGenOsl/OslSyntax.cpp @@ -457,6 +457,8 @@ OslSyntax::OslSyntax() "struct textureresource { string filename; string colorspace; };") ); +#if MATERIALX_OSL_LEGACY_CLOSURES + registerTypeSyntax ( Type::BSDF, @@ -468,6 +470,20 @@ OslSyntax::OslSyntax() "struct BSDF { closure color response; color throughput; float thickness; float ior; };") ); +#else + + registerTypeSyntax + ( + Type::BSDF, + std::make_shared( + "BSDF", + "null_closure", + "0", + "closure color") + ); + +#endif // MATERIALX_OSL_LEGACY_CLOSURES + registerTypeSyntax ( Type::EDF, From 207dea82ca252dc1cac7a7c82c9cc6fa84edee4d Mon Sep 17 00:00:00 2001 From: Niklas Harrysson Date: Sun, 31 Jul 2022 22:19:19 +0200 Subject: [PATCH 2/5] Fix closure mix node --- libraries/pbrlib/genosl/pbrlib_genosl_impl.mtlx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/pbrlib/genosl/pbrlib_genosl_impl.mtlx b/libraries/pbrlib/genosl/pbrlib_genosl_impl.mtlx index 5c995b4caf..694e6da74b 100644 --- a/libraries/pbrlib/genosl/pbrlib_genosl_impl.mtlx +++ b/libraries/pbrlib/genosl/pbrlib_genosl_impl.mtlx @@ -70,8 +70,8 @@ --> - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/pbrlib/genosl/pbrlib_genosl_impl.mtlx b/libraries/pbrlib/genosl/pbrlib_genosl_impl.mtlx index 694e6da74b..d0ef04c048 100644 --- a/libraries/pbrlib/genosl/pbrlib_genosl_impl.mtlx +++ b/libraries/pbrlib/genosl/pbrlib_genosl_impl.mtlx @@ -2,63 +2,36 @@ - - - - - - - - - @@ -66,37 +39,20 @@ - - - - diff --git a/source/MaterialXGenOsl/Nodes/ClosureLayerNodeOsl.cpp b/source/MaterialXGenOsl/Nodes/ClosureLayerNodeOsl.cpp index 79f1be8ffc..f11ad6a54f 100644 --- a/source/MaterialXGenOsl/Nodes/ClosureLayerNodeOsl.cpp +++ b/source/MaterialXGenOsl/Nodes/ClosureLayerNodeOsl.cpp @@ -37,7 +37,9 @@ void ClosureLayerNodeOsl::emitFunctionCall(const ShaderNode& _node, GenContext& ShaderNode* top = topInput->getConnection()->getNode(); ShaderNode* base = baseInput->getConnection()->getNode(); -#if MATERIALX_OSL_LEGACY_CLOSURES +#ifdef MATERIALX_OSL_LEGACY_CLOSURES + + ClosureContext* cct = context.getClosureContext(); if (top->hasClassification(ShaderNode::Classification::THINFILM)) { @@ -50,8 +52,6 @@ void ClosureLayerNodeOsl::emitFunctionCall(const ShaderNode& _node, GenContext& throw ExceptionShaderGenError("Thin-film can only be applied to a sibling node, not through a graph interface"); } - ClosureContext* cct = context.getClosureContext(); - // Set the extra parameters for thin-film. ClosureContext::ClosureParams params; params[THICKNESS] = top->getInput(THICKNESS); @@ -125,8 +125,15 @@ void ClosureLayerNodeOsl::emitFunctionCall(const ShaderNode& _node, GenContext& else { // Emit the function call for top and base layer. - shadergen.emitFunctionCall(*top, context, stage); - shadergen.emitFunctionCall(*base, context, stage); + // 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(); diff --git a/source/MaterialXGenOsl/OslShaderGenerator.cpp b/source/MaterialXGenOsl/OslShaderGenerator.cpp index 170e430ad7..b7eddaba34 100644 --- a/source/MaterialXGenOsl/OslShaderGenerator.cpp +++ b/source/MaterialXGenOsl/OslShaderGenerator.cpp @@ -166,7 +166,8 @@ OslShaderGenerator::OslShaderGenerator() : registerImplementation("IM_layer_bsdf_" + OslShaderGenerator::TARGET, ClosureLayerNodeOsl::create); registerImplementation("IM_layer_vdf_" + OslShaderGenerator::TARGET, ClosureLayerNodeOsl::create); -#if MATERIALX_OSL_LEGACY_CLOSURES +#ifdef MATERIALX_OSL_LEGACY_CLOSURES + // registerImplementation("IM_mix_bsdf_" + OslShaderGenerator::TARGET, ClosureMixNode::create); registerImplementation("IM_mix_edf_" + OslShaderGenerator::TARGET, ClosureMixNode::create); @@ -178,6 +179,7 @@ OslShaderGenerator::OslShaderGenerator() : registerImplementation("IM_multiply_bsdfF_" + OslShaderGenerator::TARGET, ClosureMultiplyNode::create); registerImplementation("IM_multiply_edfC_" + OslShaderGenerator::TARGET, ClosureMultiplyNode::create); registerImplementation("IM_multiply_edfF_" + OslShaderGenerator::TARGET, ClosureMultiplyNode::create); + #endif // MATERIALX_OSL_LEGACY_CLOSURES // diff --git a/source/MaterialXGenOsl/OslSyntax.cpp b/source/MaterialXGenOsl/OslSyntax.cpp index c0d3848a35..abc92e756e 100644 --- a/source/MaterialXGenOsl/OslSyntax.cpp +++ b/source/MaterialXGenOsl/OslSyntax.cpp @@ -457,7 +457,7 @@ OslSyntax::OslSyntax() "struct textureresource { string filename; string colorspace; };") ); -#if MATERIALX_OSL_LEGACY_CLOSURES +#ifdef MATERIALX_OSL_LEGACY_CLOSURES registerTypeSyntax ( From 7df75902ce89b6807f16bc842cf03969ddb5b423 Mon Sep 17 00:00:00 2001 From: Niklas Harrysson Date: Mon, 1 Aug 2022 22:38:53 +0200 Subject: [PATCH 4/5] Fix bug in OSL shader code snippet --- libraries/pbrlib/genosl/legacy/mx_subsurface_bsdf.osl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/pbrlib/genosl/legacy/mx_subsurface_bsdf.osl b/libraries/pbrlib/genosl/legacy/mx_subsurface_bsdf.osl index 826eee2bd6..17a4aff2cb 100644 --- a/libraries/pbrlib/genosl/legacy/mx_subsurface_bsdf.osl +++ b/libraries/pbrlib/genosl/legacy/mx_subsurface_bsdf.osl @@ -1,5 +1,6 @@ void mx_subsurface_bsdf(float weight, color _color, vector radius, float anisotropy, normal N, output BSDF bsdf) { // TODO: Subsurface closure is not supported by vanilla OSL. - bsdf = _color * weight * diffuse(N); + bsdf.response = _color * weight * diffuse(N); + bsdf.throughput = color(0.0); } From aad506a50f30b37a67e28ad9a55889174a097d0b Mon Sep 17 00:00:00 2001 From: Niklas Harrysson Date: Mon, 1 Aug 2022 23:29:54 +0200 Subject: [PATCH 5/5] Update a doc string --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a5759e92dc..651c1b4eb6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,7 +50,7 @@ option(MATERIALX_INSTALL_PYTHON "Install the MaterialX Python package as a third option(MATERIALX_TEST_RENDER "Run rendering tests for MaterialX Render module. GPU required for graphics validation." ON) option(MATERIALX_WARNINGS_AS_ERRORS "Interpret all compiler warnings as errors." OFF) option(MATERIALX_DYNAMIC_ANALYSIS "Build MaterialX libraries with dynamic analysis on supporting platforms." OFF) -option(MATERIALX_OSL_LEGACY_CLOSURES "Code generation support for the old legacy OSL closures." ON) +option(MATERIALX_OSL_LEGACY_CLOSURES "Build OSL shader generation supporting the legacy OSL closures." ON) set(MATERIALX_PYTHON_VERSION "" CACHE STRING "Python version to be used in building the MaterialX Python package (e.g. '2.7').")