Implement BSDF Transparent shader #36

Merged
Bogdan Nagirniak merged 5 commits from BogdanNagirniak/blender:matx-transparent-shader into matx-export-material 2023-09-26 16:16:26 +02:00
9 changed files with 49 additions and 16 deletions

View File

@ -14,6 +14,7 @@ NodeItem::NodeItem(MaterialX::GraphElement *graph) : graph_(graph) {}
NodeItem::Type NodeItem::type(const std::string &type_str) NodeItem::Type NodeItem::type(const std::string &type_str)
{ {
/* Converting only MaterialX supported types */
if (type_str == "multioutput") { if (type_str == "multioutput") {
return Type::Multioutput; return Type::Multioutput;
} }
@ -103,6 +104,8 @@ std::string NodeItem::type(Type type)
return "surfaceshader"; return "surfaceshader";
case Type::Material: case Type::Material:
return "material"; return "material";
case Type::SurfaceOpacity:
return "opacity";
default: default:
BLI_assert_unreachable(); BLI_assert_unreachable();
} }

View File

@ -44,6 +44,9 @@ class NodeItem {
DisplacementShader, DisplacementShader,
SurfaceShader, SurfaceShader,
Material, Material,
/* Special type to retrieve opacity for <surface> */
SurfaceOpacity,
}; };
enum class CompareOp { Less = 0, LessEq, Eq, GreaterEq, Greater, NotEq }; enum class CompareOp { Less = 0, LessEq, Eq, GreaterEq, Greater, NotEq };

View File

@ -64,7 +64,7 @@ std::string NodeParser::node_name() const
if (node_->output_sockets().size() > 1) { if (node_->output_sockets().size() > 1) {
name += std::string("_") + socket_out_->name; name += std::string("_") + socket_out_->name;
} }
if (ELEM(to_type_, NodeItem::Type::BSDF, NodeItem::Type::EDF)) { if (ELEM(to_type_, NodeItem::Type::BSDF, NodeItem::Type::EDF, NodeItem::Type::SurfaceOpacity)) {
name += "_" + NodeItem::type(to_type_); name += "_" + NodeItem::type(to_type_);
} }
#ifdef USE_MATERIALX_NODEGRAPH #ifdef USE_MATERIALX_NODEGRAPH

View File

@ -25,7 +25,7 @@ static int node_shader_gpu_add_shader(GPUMaterial *mat,
NODE_SHADER_MATERIALX_BEGIN NODE_SHADER_MATERIALX_BEGIN
#ifdef WITH_MATERIALX #ifdef WITH_MATERIALX
{ {
if (!ELEM(to_type_, NodeItem::Type::BSDF, NodeItem::Type::EDF)) { if (!ELEM(to_type_, NodeItem::Type::BSDF, NodeItem::Type::EDF, NodeItem::Type::SurfaceOpacity)) {
return empty(); return empty();
} }
@ -41,6 +41,9 @@ NODE_SHADER_MATERIALX_BEGIN
if (!shader1 && shader2) { if (!shader1 && shader2) {
return shader2; return shader2;
} }
if (to_type_ == NodeItem::Type::SurfaceOpacity) {
return (shader1 + shader2) * val(0.5f);
}
return shader1 + shader2; return shader1 + shader2;
} }
#endif #endif

View File

@ -350,7 +350,7 @@ NODE_SHADER_MATERIALX_BEGIN
{"coat_tint", get_input_value("Coat Tint", NodeItem::Type::Color3)}, {"coat_tint", get_input_value("Coat Tint", NodeItem::Type::Color3)},
{"ior", get_input_value("IOR", NodeItem::Type::Float)}, {"ior", get_input_value("IOR", NodeItem::Type::Float)},
{"transmission", get_input_value("Transmission Weight", NodeItem::Type::Float)}, {"transmission", get_input_value("Transmission Weight", NodeItem::Type::Float)},
//{"alpha", get_input_value("Alpha", NodeItem::Type::Float)}, {"alpha", get_input_value("Alpha", NodeItem::Type::Float)},
{"normal", get_input_link("Normal", NodeItem::Type::Vector3)}, {"normal", get_input_link("Normal", NodeItem::Type::Vector3)},
{"coat_normal", get_input_link("Coat Normal", NodeItem::Type::Vector3)}, {"coat_normal", get_input_link("Coat Normal", NodeItem::Type::Vector3)},
{"tangent", get_input_link("Tangent", NodeItem::Type::Vector3)}, {"tangent", get_input_link("Tangent", NodeItem::Type::Vector3)},
@ -509,9 +509,6 @@ NODE_SHADER_MATERIALX_BEGIN
NodeItem n_thin_film_layer = create_node( NodeItem n_thin_film_layer = create_node(
"layer", NodeItem::Type::BSDF, {{"top", n_thin_film_bsdf}, {"base", n_metalness_mix}}); "layer", NodeItem::Type::BSDF, {{"top", n_thin_film_bsdf}, {"base", n_metalness_mix}});
NodeItem n_opacity_luminance = create_node(
"luminance", NodeItem::Type::Color3, {{"in", val(MaterialX::Color3(1.0f, 1.0f, 1.0f))}});
NodeItem n_coat_attenuation = coat.mix(val(MaterialX::Color3(1.0f, 1.0f, 1.0f)), NodeItem n_coat_attenuation = coat.mix(val(MaterialX::Color3(1.0f, 1.0f, 1.0f)),
in["coat_tint"]); in["coat_tint"]);
@ -572,9 +569,16 @@ NODE_SHADER_MATERIALX_BEGIN
{"emission", in["emission"]}, {"emission", in["emission"]},
{"emission_color", in["emission_color"]}, {"emission_color", in["emission_color"]},
{"normal", in["normal"]}, {"normal", in["normal"]},
{"tangent", in["tangent"]}}); {"tangent", in["tangent"]},
{"opacity", in["alpha"].convert(NodeItem::Type::Color3)}});
break; break;
} }
case NodeItem::Type::SurfaceOpacity: {
res = get_input_value("Alpha", NodeItem::Type::Float);
break;
}
default: default:
BLI_assert_unreachable(); BLI_assert_unreachable();
} }

View File

@ -27,6 +27,28 @@ static int node_shader_gpu_bsdf_transparent(GPUMaterial *mat,
return GPU_stack_link(mat, node, "node_bsdf_transparent", in, out); return GPU_stack_link(mat, node, "node_bsdf_transparent", in, out);
} }
NODE_SHADER_MATERIALX_BEGIN
#ifdef WITH_MATERIALX
{
switch (to_type_) {
case NodeItem::Type::BSDF: {
NodeItem color = get_input_value("Color", NodeItem::Type::Color3);
/* Returning diffuse node as BSDF component */
return create_node("oren_nayar_diffuse_bsdf", NodeItem::Type::BSDF, {{"color", color}});
}
case NodeItem::Type::SurfaceOpacity: {
NodeItem color = get_input_value("Color", NodeItem::Type::Color3);
/* Returning: 1 - <average of color components> */
return val(1.0f) - color.dotproduct(val(1.0f / 3.0f));
}
default:
break;
}
return empty();
}
#endif
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_bsdf_transparent_cc } // namespace blender::nodes::node_shader_bsdf_transparent_cc
/* node type definition */ /* node type definition */
@ -40,6 +62,7 @@ void register_node_type_sh_bsdf_transparent()
ntype.add_ui_poll = object_shader_nodes_poll; ntype.add_ui_poll = object_shader_nodes_poll;
ntype.declare = file_ns::node_declare; ntype.declare = file_ns::node_declare;
ntype.gpu_fn = file_ns::node_shader_gpu_bsdf_transparent; ntype.gpu_fn = file_ns::node_shader_gpu_bsdf_transparent;
ntype.materialx_fn = file_ns::node_shader_materialx;
nodeRegisterType(&ntype); nodeRegisterType(&ntype);
} }

View File

@ -32,7 +32,7 @@ NODE_SHADER_MATERIALX_BEGIN
/* This node isn't supported by MaterialX. This formula was given from OSL shader code in Cycles /* This node isn't supported by MaterialX. This formula was given from OSL shader code in Cycles
* node_light_falloff.osl. Considered ray_length=1.0f. */ * node_light_falloff.osl. Considered ray_length=1.0f. */
return strength * val(1.0f) / (smooth + val(1.0f)); return strength / (smooth + val(1.0f));
} }
#endif #endif
NODE_SHADER_MATERIALX_END NODE_SHADER_MATERIALX_END

View File

@ -26,7 +26,7 @@ static int node_shader_gpu_mix_shader(GPUMaterial *mat,
NODE_SHADER_MATERIALX_BEGIN NODE_SHADER_MATERIALX_BEGIN
#ifdef WITH_MATERIALX #ifdef WITH_MATERIALX
{ {
if (!ELEM(to_type_, NodeItem::Type::BSDF, NodeItem::Type::EDF)) { if (!ELEM(to_type_, NodeItem::Type::BSDF, NodeItem::Type::EDF, NodeItem::Type::SurfaceOpacity)) {
return empty(); return empty();
} }

View File

@ -51,13 +51,10 @@ NODE_SHADER_MATERIALX_BEGIN
NodeItem bsdf = get_input_link("Surface", NodeItem::Type::BSDF); NodeItem bsdf = get_input_link("Surface", NodeItem::Type::BSDF);
NodeItem edf = get_input_link("Surface", NodeItem::Type::EDF); NodeItem edf = get_input_link("Surface", NodeItem::Type::EDF);
if (bsdf || edf) { if (bsdf || edf) {
surface = create_node("surface", NodeItem::Type::SurfaceShader); NodeItem opacity = get_input_link("Surface", NodeItem::Type::SurfaceOpacity);
if (bsdf) { surface = create_node("surface",
surface.set_input("bsdf", bsdf); NodeItem::Type::SurfaceShader,
} {{"bsdf", bsdf}, {"edf", edf}, {"opacity", opacity}});
if (edf) {
surface.set_input("edf", edf);
}
} }
} }
return create_node("surfacematerial", NodeItem::Type::Material, {{"surfaceshader", surface}}); return create_node("surfacematerial", NodeItem::Type::Material, {{"surfaceshader", surface}});