diff --git a/intern/cycles/kernel/osl/shaders/node_glass_bsdf.osl b/intern/cycles/kernel/osl/shaders/node_glass_bsdf.osl index d9c619e59fa..280b67edca3 100644 --- a/intern/cycles/kernel/osl/shaders/node_glass_bsdf.osl +++ b/intern/cycles/kernel/osl/shaders/node_glass_bsdf.osl @@ -9,6 +9,8 @@ shader node_glass_bsdf(color Color = 0.8, string distribution = "ggx", float Roughness = 0.2, float IOR = 1.45, + float ThinFilmThickness = 0.0, + float ThinFilmIOR = 1.33, normal Normal = N, output closure color BSDF = 0) { @@ -17,9 +19,22 @@ shader node_glass_bsdf(color Color = 0.8, r2 = r2 * r2; float eta = max(IOR, 1e-5); eta = backfacing() ? 1.0 / eta : eta; + float thinfilm_ior = backfacing() ? ThinFilmIOR / eta : ThinFilmIOR; color F0 = F0_from_ior(eta); color F90 = color(1.0); - BSDF = generalized_schlick_bsdf( - Normal, vector(0.0), base_color, base_color, r2, r2, F0, F90, -eta, distribution); + BSDF = generalized_schlick_bsdf(Normal, + vector(0.0), + base_color, + base_color, + r2, + r2, + F0, + F90, + -eta, + distribution, + "thinfilm_thickness", + ThinFilmThickness, + "thinfilm_ior", + thinfilm_ior); } diff --git a/intern/cycles/kernel/svm/closure.h b/intern/cycles/kernel/svm/closure.h index 4e1e472135e..91b2da4fa26 100644 --- a/intern/cycles/kernel/svm/closure.h +++ b/intern/cycles/kernel/svm/closure.h @@ -715,6 +715,10 @@ ccl_device const bool reflective_caustics = true; const bool refractive_caustics = true; #endif + + const float thinfilm_thickness = fmaxf(stack_load_float(stack, data_node.z), 1e-5f); + const float thinfilm_ior = fmaxf(stack_load_float(stack, data_node.w), 1e-5f); + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( sd, sizeof(MicrofacetBsdf), make_spectrum(mix_weight)); ccl_private FresnelGeneralizedSchlick *fresnel = @@ -737,9 +741,8 @@ ccl_device fresnel->reflection_tint = reflective_caustics ? rgb_to_spectrum(color) : zero_spectrum(); fresnel->transmission_tint = refractive_caustics ? rgb_to_spectrum(color) : zero_spectrum(); - fresnel->thin_film.thickness = 0.0f; - fresnel->thin_film.ior = 0.0f; - + fresnel->thin_film.thickness = thinfilm_thickness; + fresnel->thin_film.ior = (sd->flag & SD_BACKFACING) ? thinfilm_ior / ior : thinfilm_ior; /* setup bsdf */ if (type == CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID) { sd->flag |= bsdf_microfacet_beckmann_glass_setup(bsdf); diff --git a/intern/cycles/scene/shader_nodes.cpp b/intern/cycles/scene/shader_nodes.cpp index f9b90de0337..d0c6365bddb 100644 --- a/intern/cycles/scene/shader_nodes.cpp +++ b/intern/cycles/scene/shader_nodes.cpp @@ -2334,6 +2334,9 @@ NODE_DEFINE(GlassBsdfNode) SOCKET_IN_FLOAT(roughness, "Roughness", 0.0f); SOCKET_IN_FLOAT(IOR, "IOR", 1.5f); + SOCKET_IN_FLOAT(thin_film_thickness, "Thin Film Thickness", 0.0f); + SOCKET_IN_FLOAT(thin_film_ior, "Thin Film IOR", 1.3f); + SOCKET_OUT_CLOSURE(BSDF, "BSDF"); return type; @@ -2347,7 +2350,12 @@ GlassBsdfNode::GlassBsdfNode() : BsdfNode(get_node_type()) void GlassBsdfNode::compile(SVMCompiler &compiler) { closure = distribution; - BsdfNode::compile(compiler, input("Roughness"), input("IOR"), input("Color")); + BsdfNode::compile(compiler, + input("Roughness"), + input("IOR"), + input("Color"), + input("Thin Film Thickness"), + input("Thin Film IOR")); } void GlassBsdfNode::compile(OSLCompiler &compiler) diff --git a/intern/cycles/scene/shader_nodes.h b/intern/cycles/scene/shader_nodes.h index dc3354f591e..823c213b66e 100644 --- a/intern/cycles/scene/shader_nodes.h +++ b/intern/cycles/scene/shader_nodes.h @@ -658,6 +658,8 @@ class GlassBsdfNode : public BsdfNode { NODE_SOCKET_API(float, roughness) NODE_SOCKET_API(float, IOR) + NODE_SOCKET_API(float, thin_film_thickness) + NODE_SOCKET_API(float, thin_film_ior) NODE_SOCKET_API(ClosureType, distribution) }; diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.cc index 1450de8e0f1..2e325a1921b 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.cc +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.cc @@ -8,6 +8,10 @@ namespace blender::nodes::node_shader_bsdf_glass_cc { static void node_declare(NodeDeclarationBuilder &b) { + b.use_custom_socket_order(); + + b.add_output("BSDF"); + b.add_input("Color").default_value({1.0f, 1.0f, 1.0f, 1.0f}); b.add_input("Roughness") .default_value(0.0f) @@ -17,7 +21,19 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_input("IOR").default_value(1.5f).min(0.0f).max(1000.0f); b.add_input("Normal").hide_value(); b.add_input("Weight").available(false); - b.add_output("BSDF"); + + PanelDeclarationBuilder &film = b.add_panel("Thin Film").default_closed(true); + film.add_input("Thin Film Thickness") + .default_value(0.0) + .min(0.0f) + .max(100000.0f) + .subtype(PROP_WAVELENGTH) + .description("Thickness of the film in nanometers"); + film.add_input("Thin Film IOR") + .default_value(1.33f) + .min(1.0f) + .max(1000.0f) + .description("Index of refraction (IOR) of the thin film"); } static void node_shader_init_glass(bNodeTree * /*ntree*/, bNode *node) @@ -53,14 +69,23 @@ NODE_SHADER_MATERIALX_BEGIN NodeItem roughness = get_input_value("Roughness", NodeItem::Type::Vector2); NodeItem ior = get_input_value("IOR", NodeItem::Type::Float); NodeItem normal = get_input_link("Normal", NodeItem::Type::Vector3); + NodeItem thin_film_thickness = get_input_value("Thin Film Thickness", NodeItem::Type::Float); + NodeItem thin_film_ior = get_input_value("Thin Film IOR", NodeItem::Type::Float); - return create_node("dielectric_bsdf", - NodeItem::Type::BSDF, - {{"normal", normal}, - {"tint", color}, - {"roughness", roughness}, - {"ior", ior}, - {"scatter_mode", val(std::string("RT"))}}); + NodeItem n_base_bsdf = create_node("dielectric_bsdf", + NodeItem::Type::BSDF, + {{"normal", normal}, + {"tint", color}, + {"roughness", roughness}, + {"ior", ior}, + {"scatter_mode", val(std::string("RT"))}}); + NodeItem n_thin_film_bsdf = create_node( + "thin_film_bsdf", + NodeItem::Type::BSDF, + {{"thickness", thin_film_thickness}, {"ior", thin_film_ior}}); + + return create_node( + "layer", NodeItem::Type::BSDF, {{"top", n_thin_film_bsdf}, {"base", n_base_bsdf}}); } #endif NODE_SHADER_MATERIALX_END