Cycles: Support Thin Film iridescence in the Glass BSDF
Supporting this on the Metallic BSDF will require some extra work, and on the Glossy BSDF it doesn't make much sense conceptually (for that kind of shader setup, we'll want to support layering in SVM), but Glass BSDF just needs to be hooked up so might as well do that. Pull Request: https://projects.blender.org/blender/blender/pulls/140832
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
};
|
||||
|
||||
|
||||
@@ -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<decl::Shader>("BSDF");
|
||||
|
||||
b.add_input<decl::Color>("Color").default_value({1.0f, 1.0f, 1.0f, 1.0f});
|
||||
b.add_input<decl::Float>("Roughness")
|
||||
.default_value(0.0f)
|
||||
@@ -17,7 +21,19 @@ static void node_declare(NodeDeclarationBuilder &b)
|
||||
b.add_input<decl::Float>("IOR").default_value(1.5f).min(0.0f).max(1000.0f);
|
||||
b.add_input<decl::Vector>("Normal").hide_value();
|
||||
b.add_input<decl::Float>("Weight").available(false);
|
||||
b.add_output<decl::Shader>("BSDF");
|
||||
|
||||
PanelDeclarationBuilder &film = b.add_panel("Thin Film").default_closed(true);
|
||||
film.add_input<decl::Float>("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<decl::Float>("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
|
||||
|
||||
Reference in New Issue
Block a user