Implement export of Shader BSDF nodes #13

Merged
Bogdan Nagirniak merged 13 commits from BogdanNagirniak/blender:matx-shader-bsdf-nodes into matx-export-material 2023-09-07 11:22:44 +02:00
18 changed files with 118 additions and 269 deletions
Showing only changes of commit e42c1f7607 - Show all commits

View File

@ -6,10 +6,14 @@
namespace blender::nodes::materialx { namespace blender::nodes::materialx {
NodeItem AddShaderNodeParser::compute_bsdf() NodeItem AddShaderNodeParser::compute()
{ {
NodeItem shader1 = get_input_shader(0, NodeItem::Type::BSDF); NodeItem res = empty();
NodeItem shader2 = get_input_shader(1, NodeItem::Type::BSDF); switch (shader_type_) {
case NodeItem::Type::BSDF:
case NodeItem::Type::EDF: {
NodeItem shader1 = get_input_shader(0, shader_type_);
NodeItem shader2 = get_input_shader(1, shader_type_);
NodeItem res = empty(); NodeItem res = empty();
if (shader1 && !shader2) { if (shader1 && !shader2) {
@ -19,38 +23,19 @@ NodeItem AddShaderNodeParser::compute_bsdf()
res = shader2; res = shader2;
} }
else if (shader1 && shader2) { else if (shader1 && shader2) {
res = create_node("add", "BSDF"); res = shader1 + shader2;
res.set_input("in1", shader1);
res.set_input("in2", shader2);
} }
return res; break;
} }
case NodeItem::Type::SurfaceShader: {
NodeItem AddShaderNodeParser::compute_edf() res = get_input_shader(0, shader_type_);
{
NodeItem shader1 = get_input_shader(0, NodeItem::Type::EDF);
NodeItem shader2 = get_input_shader(1, NodeItem::Type::EDF);
NodeItem res = empty();
if (shader1 && !shader2) {
res = shader1;
}
else if (!shader1 && shader2) {
res = shader2;
}
else if (shader1 && shader2) {
res = create_node("add", "EDF");
res.set_input("in1", shader1);
res.set_input("in2", shader2);
}
return res;
}
NodeItem AddShaderNodeParser::compute_surface()
{
NodeItem res = get_input_shader(0, NodeItem::Type::SurfaceShader);
if (!res) { if (!res) {
res = get_input_shader(1, NodeItem::Type::SurfaceShader); res = get_input_shader(1, shader_type_);
}
break;
}
default:
BLI_assert_unreachable();
} }
return res; return res;
} }

View File

@ -6,8 +6,12 @@
namespace blender::nodes::materialx { namespace blender::nodes::materialx {
NodeItem BSDFDiffuseNodeParser::compute_bsdf() NodeItem BSDFDiffuseNodeParser::compute()
{ {
if (shader_type_ != NodeItem::Type::BSDF) {
return empty();
}
NodeItem color = get_input_value("Color", NodeItem::Type::Color3); NodeItem color = get_input_value("Color", NodeItem::Type::Color3);
NodeItem roughness = get_input_value("Roughness", NodeItem::Type::Float); NodeItem roughness = get_input_value("Roughness", NodeItem::Type::Float);
NodeItem normal = get_input_link("Normal", NodeItem::Type::Vector3); NodeItem normal = get_input_link("Normal", NodeItem::Type::Vector3);
@ -21,14 +25,4 @@ NodeItem BSDFDiffuseNodeParser::compute_bsdf()
return res; return res;
} }
NodeItem BSDFDiffuseNodeParser::compute_edf()
{
return empty();
}
NodeItem BSDFDiffuseNodeParser::compute_surface()
{
return empty();
}
} // namespace blender::nodes::materialx } // namespace blender::nodes::materialx

View File

@ -6,19 +6,7 @@
namespace blender::nodes::materialx { namespace blender::nodes::materialx {
NodeItem BSDFGlassNodeParser::compute_bsdf() NodeItem BSDFGlassNodeParser::compute()
{
/* TODO: implement */
return empty();
}
NodeItem BSDFGlassNodeParser::compute_edf()
{
/* TODO: implement */
return empty();
}
NodeItem BSDFGlassNodeParser::compute_surface()
{ {
/* TODO: implement */ /* TODO: implement */
return empty(); return empty();

View File

@ -6,19 +6,7 @@
namespace blender::nodes::materialx { namespace blender::nodes::materialx {
NodeItem BSDFGlossyNodeParser::compute_bsdf() NodeItem BSDFGlossyNodeParser::compute()
{
/* TODO: implement */
return empty();
}
NodeItem BSDFGlossyNodeParser::compute_edf()
{
/* TODO: implement */
return empty();
}
NodeItem BSDFGlossyNodeParser::compute_surface()
{ {
/* TODO: implement */ /* TODO: implement */
return empty(); return empty();

View File

@ -6,20 +6,13 @@
namespace blender::nodes::materialx { namespace blender::nodes::materialx {
NodeItem BSDFPrincipledNodeParser::compute_bsdf() NodeItem BSDFPrincipledNodeParser::compute()
{ {
/* TODO: implement */ if (shader_type_ != NodeItem::Type::SurfaceShader) {
/* TODO: implement for BSDF and EDF */
return empty(); return empty();
} }
NodeItem BSDFPrincipledNodeParser::compute_edf()
{
/* TODO: implement */
return empty();
}
NodeItem BSDFPrincipledNodeParser::compute_surface()
{
NodeItem base_color = get_input_value("Base Color", NodeItem::Type::Color3); NodeItem base_color = get_input_value("Base Color", NodeItem::Type::Color3);
NodeItem subsurface = get_input_value("Subsurface", NodeItem::Type::Float); NodeItem subsurface = get_input_value("Subsurface", NodeItem::Type::Float);

View File

@ -6,19 +6,7 @@
namespace blender::nodes::materialx { namespace blender::nodes::materialx {
NodeItem BSDFRefractionNodeParser::compute_bsdf() NodeItem BSDFRefractionNodeParser::compute()
{
/* TODO: implement */
return empty();
}
NodeItem BSDFRefractionNodeParser::compute_edf()
{
/* TODO: implement */
return empty();
}
NodeItem BSDFRefractionNodeParser::compute_surface()
{ {
/* TODO: implement */ /* TODO: implement */
return empty(); return empty();

View File

@ -6,19 +6,7 @@
namespace blender::nodes::materialx { namespace blender::nodes::materialx {
NodeItem BSDFSheenNodeParser::compute_bsdf() NodeItem BSDFSheenNodeParser::compute()
{
/* TODO: implement */
return empty();
}
NodeItem BSDFSheenNodeParser::compute_edf()
{
/* TODO: implement */
return empty();
}
NodeItem BSDFSheenNodeParser::compute_surface()
{ {
/* TODO: implement */ /* TODO: implement */
return empty(); return empty();

View File

@ -6,19 +6,7 @@
namespace blender::nodes::materialx { namespace blender::nodes::materialx {
NodeItem BSDFToonNodeParser::compute_bsdf() NodeItem BSDFToonNodeParser::compute()
{
/* TODO: implement */
return empty();
}
NodeItem BSDFToonNodeParser::compute_edf()
{
/* TODO: implement */
return empty();
}
NodeItem BSDFToonNodeParser::compute_surface()
{ {
/* TODO: implement */ /* TODO: implement */
return empty(); return empty();

View File

@ -6,19 +6,7 @@
namespace blender::nodes::materialx { namespace blender::nodes::materialx {
NodeItem BSDFTranslucentNodeParser::compute_bsdf() NodeItem BSDFTranslucentNodeParser::compute()
{
/* TODO: implement */
return empty();
}
NodeItem BSDFTranslucentNodeParser::compute_edf()
{
/* TODO: implement */
return empty();
}
NodeItem BSDFTranslucentNodeParser::compute_surface()
{ {
/* TODO: implement */ /* TODO: implement */
return empty(); return empty();

View File

@ -6,19 +6,7 @@
namespace blender::nodes::materialx { namespace blender::nodes::materialx {
NodeItem BSDFTransparentNodeParser::compute_bsdf() NodeItem BSDFTransparentNodeParser::compute()
{
/* TODO: implement */
return empty();
}
NodeItem BSDFTransparentNodeParser::compute_edf()
{
/* TODO: implement */
return empty();
}
NodeItem BSDFTransparentNodeParser::compute_surface()
{ {
/* TODO: implement */ /* TODO: implement */
return empty(); return empty();

View File

@ -6,13 +6,12 @@
namespace blender::nodes::materialx { namespace blender::nodes::materialx {
NodeItem EmissionNodeParser::compute_bsdf() NodeItem EmissionNodeParser::compute()
{ {
if (shader_type_ != NodeItem::Type::EDF) {
return empty(); return empty();
} }
NodeItem EmissionNodeParser::compute_edf()
{
NodeItem color = get_input_value("Color", NodeItem::Type::Color3); NodeItem color = get_input_value("Color", NodeItem::Type::Color3);
NodeItem strength = get_input_value("Strength", NodeItem::Type::Float); NodeItem strength = get_input_value("Strength", NodeItem::Type::Float);
@ -21,9 +20,4 @@ NodeItem EmissionNodeParser::compute_edf()
return res; return res;
} }
NodeItem EmissionNodeParser::compute_surface()
{
return empty();
}
} // namespace blender::nodes::materialx } // namespace blender::nodes::materialx

View File

@ -6,55 +6,40 @@
namespace blender::nodes::materialx { namespace blender::nodes::materialx {
NodeItem MixShaderNodeParser::compute_bsdf() NodeItem MixShaderNodeParser::compute()
{ {
NodeItem res = empty();
switch (shader_type_) {
case NodeItem::Type::BSDF:
case NodeItem::Type::EDF: {
NodeItem fac = get_input_value(0, NodeItem::Type::Float); NodeItem fac = get_input_value(0, NodeItem::Type::Float);
NodeItem shader1 = get_input_shader(1, NodeItem::Type::BSDF); NodeItem shader1 = get_input_shader(1, shader_type_);
NodeItem shader2 = get_input_shader(2, NodeItem::Type::BSDF); NodeItem shader2 = get_input_shader(2, shader_type_);
NodeItem res = empty(); NodeItem res = empty();
if (shader1 && !shader2) { if (shader1 && !shader2) {
res = shader1; res = shader1 * fac;
} }
else if (!shader1 && shader2) { else if (!shader1 && shader2) {
res = shader2; res = shader2 * (value(1.0f) - fac);
} }
else if (shader1 && shader2) { else if (shader1 && shader2) {
res = create_node("mix", "BSDF"); res = create_node("mix", NodeItem::type(shader_type_));
res.set_input("fg", shader1); res.set_input("fg", shader1);
res.set_input("bg", shader2); res.set_input("bg", shader2);
res.set_input("mix", fac); res.set_input("mix", fac);
} }
return res; break;
} }
case NodeItem::Type::SurfaceShader: {
NodeItem MixShaderNodeParser::compute_edf() res = get_input_shader(1, shader_type_);
{
NodeItem fac = get_input_value(0, NodeItem::Type::Float);
NodeItem shader1 = get_input_shader(1, NodeItem::Type::EDF);
NodeItem shader2 = get_input_shader(2, NodeItem::Type::EDF);
NodeItem res = empty();
if (shader1 && !shader2) {
res = shader1;
}
else if (!shader1 && shader2) {
res = shader2;
}
else if (shader1 && shader2) {
res = create_node("mix", "EDF");
res.set_input("fg", shader1);
res.set_input("bg", shader2);
res.set_input("mix", fac);
}
return res;
}
NodeItem MixShaderNodeParser::compute_surface()
{
NodeItem res = get_input_shader(0, NodeItem::Type::SurfaceShader);
if (!res) { if (!res) {
res = get_input_shader(1, NodeItem::Type::SurfaceShader); res = get_input_shader(2, shader_type_);
}
break;
}
default:
BLI_assert_unreachable();
} }
return res; return res;
} }

View File

@ -99,6 +99,20 @@ NodeItem::operator bool() const
NodeItem NodeItem::operator+(const NodeItem &other) const NodeItem NodeItem::operator+(const NodeItem &other) const
{ {
Type type = this->type();
if (ELEM(type, Type::BSDF, Type::EDF)) {
NodeItem res = empty();
if (other.type() == type) {
res.node = graph_->addNode("add", MaterialX::EMPTY_STRING, this->type(type));
res.set_input("in1", *this);
res.set_input("in2", other);
}
else {
BLI_assert_unreachable();
}
return res;
}
return arithmetic(other, "add", [](float a, float b) { return a + b; }); return arithmetic(other, "add", [](float a, float b) { return a + b; });
} }
@ -114,6 +128,20 @@ NodeItem NodeItem::operator-() const
NodeItem NodeItem::operator*(const NodeItem &other) const NodeItem NodeItem::operator*(const NodeItem &other) const
{ {
Type type = this->type();
if (ELEM(type, Type::BSDF, Type::EDF)) {
NodeItem res = empty();
if (ELEM(other.type(), Type::Float, Type::Color3)) {
res.node = graph_->addNode("multiply", MaterialX::EMPTY_STRING, this->type(type));
res.set_input("in1", *this);
res.set_input("in2", other);
}
else {
BLI_assert_unreachable();
}
return res;
}
return arithmetic(other, "multiply", [](float a, float b) { return a * b; }); return arithmetic(other, "multiply", [](float a, float b) { return a * b; });
} }
@ -332,6 +360,10 @@ NodeItem NodeItem::convert(Type to_type) const
return *this; return *this;
} }
if (!is_arithmetic(from_type) || !is_arithmetic(to_type)) { if (!is_arithmetic(from_type) || !is_arithmetic(to_type)) {
CLOG_WARN(LOG_MATERIALX_SHADER,
"Cannot convert: %s -> %s",
type(from_type).c_str(),
type(to_type).c_str());
return empty(); return empty();
} }
@ -647,6 +679,8 @@ NodeItem::Type NodeItem::adjust_types(NodeItem &item1, NodeItem &item2)
return t1; return t1;
} }
if (!is_arithmetic(t1) || !is_arithmetic(t2)) { if (!is_arithmetic(t1) || !is_arithmetic(t2)) {
CLOG_WARN(
LOG_MATERIALX_SHADER, "Can't adjust types: %s <-> %s", type(t1).c_str(), type(t2).c_str());
return Type::Empty; return Type::Empty;
} }
if (t1 < t2) { if (t1 < t2) {

View File

@ -191,21 +191,6 @@ ShaderNodeParser::ShaderNodeParser(MaterialX::GraphElement *graph,
{ {
} }
NodeItem ShaderNodeParser::compute()
{
switch (shader_type_) {
case NodeItem::Type::BSDF:
return compute_bsdf();
case NodeItem::Type::EDF:
return compute_edf();
case NodeItem::Type::SurfaceShader:
return compute_surface();
default:
BLI_assert_unreachable();
}
return empty();
}
NodeItem ShaderNodeParser::compute_full() NodeItem ShaderNodeParser::compute_full()
{ {
CLOG_INFO(LOG_MATERIALX_SHADER, CLOG_INFO(LOG_MATERIALX_SHADER,

View File

@ -61,11 +61,6 @@ class ShaderNodeParser : public NodeParser {
const bNodeSocket *socket_out, const bNodeSocket *socket_out,
NodeItem::Type shader_type); NodeItem::Type shader_type);
NodeItem compute() override;
virtual NodeItem compute_bsdf() = 0;
virtual NodeItem compute_edf() = 0;
virtual NodeItem compute_surface() = 0;
protected: protected:
NodeItem compute_full() override; NodeItem compute_full() override;
std::string node_name() override; std::string node_name() override;
@ -92,9 +87,7 @@ template<class T> NodeItem NodeParser::value(const T &data) const
class T : public ShaderNodeParser { \ class T : public ShaderNodeParser { \
public: \ public: \
using ShaderNodeParser::ShaderNodeParser; \ using ShaderNodeParser::ShaderNodeParser; \
NodeItem compute_bsdf() override; \ NodeItem compute() override; \
NodeItem compute_edf() override; \
NodeItem compute_surface() override; \
}; };
DECLARE_NODE_PARSER(BrightContrastNodeParser) DECLARE_NODE_PARSER(BrightContrastNodeParser)

View File

@ -17,8 +17,8 @@ NodeItem OutputMaterialNodeParser::compute()
{ {
NodeItem surface = empty(); NodeItem surface = empty();
if (node_) { if (node_) {
NodeItem bsdf = compute_bsdf(); NodeItem bsdf = get_input_shader("Surface", NodeItem::Type::BSDF);
NodeItem edf = compute_edf(); NodeItem edf = get_input_shader("Surface", NodeItem::Type::EDF);
if (bsdf || edf) { if (bsdf || edf) {
surface = create_node("surface", "surfaceshader"); surface = create_node("surface", "surfaceshader");
if (bsdf) { if (bsdf) {
@ -29,7 +29,7 @@ NodeItem OutputMaterialNodeParser::compute()
} }
} }
else { else {
surface = compute_surface(); surface = get_input_shader("Surface", NodeItem::Type::SurfaceShader);
} }
} }
else { else {
@ -41,21 +41,6 @@ NodeItem OutputMaterialNodeParser::compute()
return res; return res;
} }
NodeItem OutputMaterialNodeParser::compute_bsdf()
{
return get_input_shader("Surface", NodeItem::Type::BSDF);
}
NodeItem OutputMaterialNodeParser::compute_edf()
{
return get_input_shader("Surface", NodeItem::Type::EDF);
}
NodeItem OutputMaterialNodeParser::compute_surface()
{
return get_input_shader("Surface", NodeItem::Type::SurfaceShader);
}
NodeItem OutputMaterialNodeParser::compute_default() NodeItem OutputMaterialNodeParser::compute_default()
{ {
NodeItem surface = create_node("standard_surface", "surfaceshader"); NodeItem surface = create_node("standard_surface", "surfaceshader");

View File

@ -15,9 +15,6 @@ class OutputMaterialNodeParser : public ShaderNodeParser {
const Material *material, const Material *material,
const bNode *node); const bNode *node);
NodeItem compute() override; NodeItem compute() override;
NodeItem compute_bsdf() override;
NodeItem compute_edf() override;
NodeItem compute_surface() override;
using ShaderNodeParser::compute_full; using ShaderNodeParser::compute_full;
NodeItem compute_default(); NodeItem compute_default();

View File

@ -6,19 +6,7 @@
namespace blender::nodes::materialx { namespace blender::nodes::materialx {
NodeItem SubsurfaceScatteringNodeParser::compute_bsdf() NodeItem SubsurfaceScatteringNodeParser::compute()
{
/* TODO: implement */
return empty();
}
NodeItem SubsurfaceScatteringNodeParser::compute_edf()
{
/* TODO: implement */
return empty();
}
NodeItem SubsurfaceScatteringNodeParser::compute_surface()
{ {
/* TODO: implement */ /* TODO: implement */
return empty(); return empty();