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,51 +6,36 @@
namespace blender::nodes::materialx {
NodeItem AddShaderNodeParser::compute_bsdf()
NodeItem AddShaderNodeParser::compute()
{
NodeItem shader1 = get_input_shader(0, NodeItem::Type::BSDF);
NodeItem shader2 = get_input_shader(1, NodeItem::Type::BSDF);
NodeItem res = empty();
if (shader1 && !shader2) {
res = shader1;
}
else if (!shader1 && shader2) {
res = shader2;
}
else if (shader1 && shader2) {
res = create_node("add", "BSDF");
res.set_input("in1", shader1);
res.set_input("in2", shader2);
}
return res;
}
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 AddShaderNodeParser::compute_edf()
{
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) {
res = get_input_shader(1, NodeItem::Type::SurfaceShader);
NodeItem res = empty();
if (shader1 && !shader2) {
res = shader1;
}
else if (!shader1 && shader2) {
res = shader2;
}
else if (shader1 && shader2) {
res = shader1 + shader2;
}
break;
}
case NodeItem::Type::SurfaceShader: {
res = get_input_shader(0, shader_type_);
if (!res) {
res = get_input_shader(1, shader_type_);
}
break;
}
default:
BLI_assert_unreachable();
}
return res;
}

View File

@ -6,8 +6,12 @@
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 roughness = get_input_value("Roughness", NodeItem::Type::Float);
NodeItem normal = get_input_link("Normal", NodeItem::Type::Vector3);
@ -21,14 +25,4 @@ NodeItem BSDFDiffuseNodeParser::compute_bsdf()
return res;
}
NodeItem BSDFDiffuseNodeParser::compute_edf()
{
return empty();
}
NodeItem BSDFDiffuseNodeParser::compute_surface()
{
return empty();
}
} // namespace blender::nodes::materialx

View File

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

View File

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

View File

@ -6,20 +6,13 @@
namespace blender::nodes::materialx {
NodeItem BSDFPrincipledNodeParser::compute_bsdf()
NodeItem BSDFPrincipledNodeParser::compute()
{
/* TODO: implement */
return empty();
}
if (shader_type_ != NodeItem::Type::SurfaceShader) {
/* TODO: implement for BSDF and EDF */
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 subsurface = get_input_value("Subsurface", NodeItem::Type::Float);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -99,6 +99,20 @@ NodeItem::operator bool() 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; });
}
@ -114,6 +128,20 @@ NodeItem NodeItem::operator-() 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; });
}
@ -332,6 +360,10 @@ NodeItem NodeItem::convert(Type to_type) const
return *this;
}
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();
}
@ -647,6 +679,8 @@ NodeItem::Type NodeItem::adjust_types(NodeItem &item1, NodeItem &item2)
return t1;
}
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;
}
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()
{
CLOG_INFO(LOG_MATERIALX_SHADER,

View File

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

View File

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

View File

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

View File

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