1
1
Fork 0

Move the MaterialX export code into the existing shader node files #18

Merged
Bogdan Nagirniak merged 14 commits from BogdanNagirniak/blender:matx-move-code into matx-export-material 2023-09-12 13:55:27 +02:00
77 changed files with 1321 additions and 1919 deletions

View File

@ -225,6 +225,9 @@ typedef int (*NodeGPUExecFunction)(struct GPUMaterial *mat,
struct bNodeExecData *execdata,
struct GPUNodeStack *in,
struct GPUNodeStack *out);
typedef void (*NodeMaterialXExecFunction)(void *data,
struct bNode *node,
struct bNodeSocket *out);
/**
* \brief Defines a node type.
@ -339,6 +342,8 @@ typedef struct bNodeType {
NodeExecFunction exec_fn;
/* gpu */
NodeGPUExecFunction gpu_fn;
/* MaterialX */
NodeMaterialXExecFunction materialx_fn;
/* Get an instance of this node's compositor operation. Freeing the instance is the
* responsibility of the caller. */

View File

@ -147,50 +147,12 @@ set(LIB
if(WITH_MATERIALX)
list(APPEND SRC
materialx/material.cc
materialx/nodes/add_shader.cc
materialx/nodes/blackbody.cc
materialx/nodes/brightness.cc
materialx/nodes/bsdf_diffuse.cc
materialx/nodes/bsdf_glass.cc
materialx/nodes/bsdf_glossy.cc
materialx/nodes/bsdf_principled.cc
materialx/nodes/bsdf_refraction.cc
materialx/nodes/bsdf_sheen.cc
materialx/nodes/bsdf_toon.cc
materialx/nodes/bsdf_translucent.cc
materialx/nodes/bsdf_transparent.cc
materialx/nodes/clamp.cc
materialx/nodes/color_ramp.cc
materialx/nodes/curves.cc
materialx/nodes/gamma.cc
materialx/nodes/emission.cc
materialx/nodes/huesatval.cc
materialx/nodes/invert.cc
materialx/nodes/light_falloff.cc
materialx/nodes/light_path.cc
materialx/nodes/map_range.cc
materialx/nodes/math.cc
materialx/nodes/mix_rgb.cc
materialx/nodes/mix_shader.cc
materialx/nodes/node_item.cc
materialx/nodes/node_parser.cc
materialx/nodes/normal_map.cc
materialx/nodes/output_material.cc
materialx/nodes/rgb_to_bw.cc
materialx/nodes/sepcomb_color.cc
materialx/nodes/sepcomb_xyz.cc
materialx/nodes/subsurface_scattering.cc
materialx/nodes/tex_checker.cc
materialx/nodes/tex_environment.cc
materialx/nodes/tex_image.cc
materialx/nodes/tex_noise.cc
materialx/nodes/vector_math.cc
materialx/nodes/wavelength.cc
materialx/node_item.cc
materialx/node_parser.cc
materialx/material.h
materialx/nodes/node_item.h
materialx/nodes/node_parser.h
materialx/nodes/output_material.h
materialx/node_item.h
materialx/node_parser.h
)
list(APPEND LIB
MaterialXCore

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "material.h"
#include "nodes/output_material.h"
#include "node_parser.h"
#include <MaterialXFormat/XmlIo.h>
@ -15,7 +15,42 @@
namespace blender::nodes::materialx {
CLG_LOGREF_DECLARE_GLOBAL(LOG_MATERIALX_SHADER, "materialx.shader");
class DefaultMaterialNodeParser : public NodeParser {
public:
using NodeParser::NodeParser;
NodeItem compute() override
{
NodeItem surface = create_node("standard_surface", NodeItem::Type::SurfaceShader);
surface.set_input("base_color",
val(MaterialX::Color3(material_->r, material_->g, material_->b)));
surface.set_input("diffuse_roughness", val(material_->roughness));
if (material_->metallic > 0.0f) {
surface.set_input("metalness", val(material_->metallic));
}
if (material_->spec) {
surface.set_input("specular", val(material_->spec));
surface.set_input("specular_color", val(material_->spec));
surface.set_input("specular_roughness", val(material_->roughness));
}
NodeItem res = create_node("surfacematerial", NodeItem::Type::Material);
res.node->setName("Material_Default");
res.set_input("surfaceshader", surface);
return res;
}
NodeItem compute_error()
{
NodeItem surface = create_node("standard_surface", NodeItem::Type::SurfaceShader);
surface.set_input("base_color", val(MaterialX::Color3(1.0f, 0.0f, 1.0f)));
NodeItem res = create_node("surfacematerial", NodeItem::Type::Material);
res.node->setName("Material_Error");
res.set_input("surfaceshader", surface);
return res;
}
};
MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, Material *material)
{
@ -25,10 +60,21 @@ MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, Material *mater
if (material->use_nodes) {
material->nodetree->ensure_topology_cache();
bNode *output_node = ntreeShaderOutputNode(material->nodetree, SHD_OUTPUT_ALL);
OutputMaterialNodeParser(doc.get(), depsgraph, material, output_node).compute_full();
if (output_node) {
NodeParserData data = {
doc.get(), depsgraph, material, NodeItem::Type::Material, NodeItem(doc.get())};
output_node->typeinfo->materialx_fn(&data, output_node, nullptr);
}
else {
DefaultMaterialNodeParser(
doc.get(), depsgraph, material, nullptr, nullptr, NodeItem::Type::Material)
.compute_error();
}
}
else {
OutputMaterialNodeParser(doc.get(), depsgraph, material, nullptr).compute_default();
DefaultMaterialNodeParser(
doc.get(), depsgraph, material, nullptr, nullptr, NodeItem::Type::Material)
.compute();
}
CLOG_INFO(LOG_MATERIALX_SHADER,

View File

@ -6,15 +6,11 @@
#include <MaterialXCore/Document.h>
#include "CLG_log.h"
struct Depsgraph;
struct Material;
namespace blender::nodes::materialx {
extern struct CLG_LogRef *LOG_MATERIALX_SHADER;
MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, Material *material);
} // namespace blender::nodes::materialx

View File

@ -3,7 +3,6 @@
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_item.h"
#include "../material.h"
#include "BLI_assert.h"
#include "BLI_utildefines.h"
@ -63,6 +62,8 @@ NodeItem::Type NodeItem::type(const std::string &type_str)
std::string NodeItem::type(Type type)
{
switch (type) {
case Type::Any:
return "";
case Type::String:
return "string";
case Type::Filename:

View File

@ -50,6 +50,7 @@ class NodeItem {
static Type type(const std::string &type_str);
static std::string type(Type type);
static bool is_arithmetic(Type type);
/* Operators */
operator bool() const;
@ -109,7 +110,6 @@ class NodeItem {
void add_output(const std::string &in_name, Type out_type);
private:
static bool is_arithmetic(Type type);
static Type cast_types(NodeItem &item1, NodeItem &item2);
bool is_arithmetic() const;

View File

@ -0,0 +1,188 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_parser.h"
#include "BKE_node_runtime.hh"
namespace blender::nodes::materialx {
static const std::string TEXCOORD_NODE_NAME = "node_texcoord";
CLG_LOGREF_DECLARE_GLOBAL(LOG_MATERIALX_SHADER, "materialx.shader");
NodeParser::NodeParser(MaterialX::GraphElement *graph,
const Depsgraph *depsgraph,
const Material *material,
const bNode *node,
const bNodeSocket *socket_out,
NodeItem::Type to_type)
: graph_(graph),
depsgraph_(depsgraph),
material_(material),
node_(node),
socket_out_(socket_out),
to_type_(to_type)
{
}
NodeItem NodeParser::compute_full()
{
NodeItem res = empty();
/* Checking if node was already computed */
res.node = graph_->getNode(node_name());
if (res.node) {
return res;
}
CLOG_INFO(LOG_MATERIALX_SHADER,
1,
"%s [%d] => %s",
node_->name,
node_->typeinfo->type,
NodeItem::type(to_type_).c_str());
res = compute();
if (res.node) {
res.node->setName(node_name());
}
if (NodeItem::is_arithmetic(to_type_)) {
res = res.convert(to_type_);
}
return res;
}
std::string NodeParser::node_name()
{
std::string name = node_->name;
if (node_->output_sockets().size() > 1) {
name += std::string("_") + socket_out_->name;
}
if (ELEM(to_type_, NodeItem::Type::BSDF, NodeItem::Type::EDF)) {
name += "_" + NodeItem::type(to_type_);
}
return MaterialX::createValidName(name);
}
NodeItem NodeParser::create_node(const std::string &category, NodeItem::Type type)
{
return empty().create_node(category, type);
}
NodeItem NodeParser::get_input_default(const std::string &name, NodeItem::Type to_type)
{
return get_input_default(node_->input_by_identifier(name), to_type);
}
NodeItem NodeParser::get_input_default(int index, NodeItem::Type to_type)
{
return get_input_default(node_->input_socket(index), to_type);
}
NodeItem NodeParser::get_input_link(const std::string &name, NodeItem::Type to_type)
{
return get_input_link(node_->input_by_identifier(name), to_type);
}
NodeItem NodeParser::get_input_link(int index, NodeItem::Type to_type)
{
return get_input_link(node_->input_socket(index), to_type);
}
NodeItem NodeParser::get_input_value(const std::string &name, NodeItem::Type to_type)
{
return get_input_value(node_->input_by_identifier(name), to_type);
}
NodeItem NodeParser::get_input_value(int index, NodeItem::Type to_type)
{
return get_input_value(node_->input_socket(index), to_type);
}
NodeItem NodeParser::empty() const
{
return NodeItem(graph_);
}
NodeItem NodeParser::texcoord_node()
{
NodeItem res = empty();
res.node = graph_->getNode(TEXCOORD_NODE_NAME);
if (!res.node) {
res = create_node("texcoord", NodeItem::Type::Vector2);
res.node->setName(TEXCOORD_NODE_NAME);
}
return res;
}
NodeItem NodeParser::get_input_default(const bNodeSocket &socket, NodeItem::Type to_type)
{
NodeItem res = empty();
switch (socket.type) {
case SOCK_FLOAT: {
float v = socket.default_value_typed<bNodeSocketValueFloat>()->value;
res.value = MaterialX::Value::createValue<float>(v);
break;
}
case SOCK_VECTOR: {
const float *v = socket.default_value_typed<bNodeSocketValueVector>()->value;
res.value = MaterialX::Value::createValue<MaterialX::Vector3>(
MaterialX::Vector3(v[0], v[1], v[2]));
break;
}
case SOCK_RGBA: {
const float *v = socket.default_value_typed<bNodeSocketValueRGBA>()->value;
res.value = MaterialX::Value::createValue<MaterialX::Color4>(
MaterialX::Color4(v[0], v[1], v[2], v[3]));
break;
}
default: {
CLOG_WARN(LOG_MATERIALX_SHADER, "Unsupported socket type: %d", socket.type);
}
}
return res.convert(to_type);
}
NodeItem NodeParser::get_input_link(const bNodeSocket &socket, NodeItem::Type to_type)
{
const bNodeLink *link = socket.link;
if (!(link && link->is_used())) {
return empty();
}
const bNode *from_node = link->fromnode;
/* Passing NODE_REROUTE nodes */
while (from_node->type == NODE_REROUTE) {
link = from_node->input_socket(0).link;
if (!(link && link->is_used())) {
return empty();
}
from_node = link->fromnode;
}
if (!from_node->typeinfo->materialx_fn) {
CLOG_WARN(LOG_MATERIALX_SHADER,
"Unsupported node: %s [%d]",
from_node->name,
from_node->typeinfo->type);
return empty();
}
NodeParserData data = {graph_, depsgraph_, material_, to_type, empty()};
from_node->typeinfo->materialx_fn(&data, const_cast<bNode *>(from_node), link->fromsock);
return data.result;
}
NodeItem NodeParser::get_input_value(const bNodeSocket &socket, NodeItem::Type to_type)
{
NodeItem res = get_input_link(socket, to_type);
if (!res) {
res = get_input_default(socket, to_type);
}
return res;
}
} // namespace blender::nodes::materialx

View File

@ -0,0 +1,96 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include "node_item.h"
#include "DEG_depsgraph.h"
#include "DNA_material_types.h"
#include "DNA_node_types.h"
#include "CLG_log.h"
namespace blender::nodes::materialx {
extern struct CLG_LogRef *LOG_MATERIALX_SHADER;
class NodeParser {
protected:
MaterialX::GraphElement *graph_;
const Depsgraph *depsgraph_;
const Material *material_;
const bNode *node_;
const bNodeSocket *socket_out_;
NodeItem::Type to_type_;
public:
NodeParser(MaterialX::GraphElement *graph,
const Depsgraph *depsgraph,
const Material *material,
const bNode *node,
const bNodeSocket *socket_out,
NodeItem::Type to_type);
virtual ~NodeParser() = default;
virtual NodeItem compute() = 0;
virtual NodeItem compute_full();
protected:
std::string node_name();
NodeItem create_node(const std::string &category, NodeItem::Type type);
NodeItem get_input_default(const std::string &name, NodeItem::Type to_type);
NodeItem get_input_default(int index, NodeItem::Type to_type);
NodeItem get_input_link(const std::string &name, NodeItem::Type to_type);
NodeItem get_input_link(int index, NodeItem::Type to_type);
NodeItem get_input_value(const std::string &name, NodeItem::Type to_type);
NodeItem get_input_value(int index, NodeItem::Type to_type);
NodeItem empty() const;
template<class T> NodeItem val(const T &data) const;
NodeItem texcoord_node();
private:
NodeItem get_input_default(const bNodeSocket &socket, NodeItem::Type to_type);
NodeItem get_input_link(const bNodeSocket &socket, NodeItem::Type to_type);
NodeItem get_input_value(const bNodeSocket &socket, NodeItem::Type to_type);
};
template<class T> NodeItem NodeParser::val(const T &data) const
{
return empty().val(data);
}
/*
* Defines for including MaterialX node parsing code into node_shader_<name>.cc
*/
struct NodeParserData {
MaterialX::GraphElement *graph;
const Depsgraph *depsgraph;
const Material *material;
NodeItem::Type to_type;
NodeItem result;
};
#define NODE_SHADER_MATERIALX_BEGIN \
class MaterialXNodeParser : public materialx::NodeParser { \
public: \
using materialx::NodeParser::NodeParser; \
materialx::NodeItem compute() override; \
}; \
\
materialx::NodeItem MaterialXNodeParser::compute() \
{ \
using NodeItem = materialx::NodeItem;
#define NODE_SHADER_MATERIALX_END \
} \
\
void node_shader_materialx(void *data, struct bNode *node, struct bNodeSocket *out) \
{ \
materialx::NodeParserData *d = reinterpret_cast<materialx::NodeParserData *>(data); \
d->result = MaterialXNodeParser(d->graph, d->depsgraph, d->material, node, out, d->to_type) \
.compute_full(); \
}
} // namespace blender::nodes::materialx

View File

@ -1,42 +0,0 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_parser.h"
namespace blender::nodes::materialx {
NodeItem AddShaderNodeParser::compute()
{
NodeItem res = empty();
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_);
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;
}
} // namespace blender::nodes::materialx

View File

@ -1,22 +0,0 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_parser.h"
namespace blender::nodes::materialx {
NodeItem BlackbodyNodeParser::compute()
{
/* This node doesn't have an implementation in MaterialX 1.38.6.
* It's added in MaterialX 1.38.8. Uncomment this code after switching to 1.38.8.
*
* NodeItem temperature = get_input_value("Temperature", NodeItem::Type::Float);
* NodeItem res = create_node("blackbody", NodeItem::Type::Color3);
* res.set_input("temperature", temperature);
* return res; */
return empty();
}
} // namespace blender::nodes::materialx

View File

@ -1,19 +0,0 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_parser.h"
namespace blender::nodes::materialx {
NodeItem BrightContrastNodeParser::compute()
{
NodeItem color = get_input_value("Color", NodeItem::Type::Color3);
NodeItem bright = get_input_value("Bright", NodeItem::Type::Float);
NodeItem contrast = get_input_value("Contrast", NodeItem::Type::Float);
/* This formula was given from OSL shader code in Cycles. */
return (bright + color * (contrast + val(1.0f)) - contrast * val(0.5f)).max(val(0.0f));
}
} // namespace blender::nodes::materialx

View File

@ -1,28 +0,0 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_parser.h"
namespace blender::nodes::materialx {
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);
NodeItem res = create_node("oren_nayar_diffuse_bsdf", NodeItem::Type::BSDF);
res.set_input("color", color);
res.set_input("roughness", roughness);
if (normal) {
res.set_input("normal", normal);
}
return res;
}
} // namespace blender::nodes::materialx

View File

@ -1,15 +0,0 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_parser.h"
namespace blender::nodes::materialx {
NodeItem BSDFGlassNodeParser::compute()
{
/* TODO: implement */
return empty();
}
} // namespace blender::nodes::materialx

View File

@ -1,15 +0,0 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_parser.h"
namespace blender::nodes::materialx {
NodeItem BSDFGlossyNodeParser::compute()
{
/* TODO: implement */
return empty();
}
} // namespace blender::nodes::materialx

View File

@ -1,101 +0,0 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_parser.h"
namespace blender::nodes::materialx {
NodeItem BSDFPrincipledNodeParser::compute()
{
if (shader_type_ != NodeItem::Type::SurfaceShader) {
/* TODO: implement for BSDF and EDF */
return empty();
}
NodeItem base_color = get_input_value("Base Color", NodeItem::Type::Color3);
NodeItem subsurface = get_input_value("Subsurface", NodeItem::Type::Float);
NodeItem subsurface_radius = get_input_value("Subsurface Radius", NodeItem::Type::Color3);
NodeItem subsurface_color = get_input_value("Subsurface Color", NodeItem::Type::Color3);
NodeItem metallic = get_input_value("Metallic", NodeItem::Type::Float);
NodeItem specular = get_input_value("Specular", NodeItem::Type::Float);
// NodeItem specular_tint = get_input_value("Specular Tint");
NodeItem roughness = get_input_value("Roughness", NodeItem::Type::Float);
/* TODO: use Specular Tint input */
NodeItem anisotropic = get_input_value("Anisotropic", NodeItem::Type::Float);
NodeItem anisotropic_rotation = get_input_value("Anisotropic Rotation", NodeItem::Type::Float);
// anisotropic_rotation = 0.5 - (anisotropic_rotation % 1.0)
NodeItem sheen = get_input_value("Sheen", NodeItem::Type::Float);
// sheen_tint = get_input_value("Sheen Tint");
NodeItem clearcoat = get_input_value("Clearcoat", NodeItem::Type::Float);
NodeItem clearcoat_roughness = get_input_value("Clearcoat Roughness", NodeItem::Type::Float);
NodeItem ior = get_input_value("IOR", NodeItem::Type::Float);
NodeItem transmission = get_input_value("Transmission", NodeItem::Type::Float);
NodeItem emission = get_input_value("Emission", NodeItem::Type::Color3);
NodeItem emission_strength = get_input_value("Emission Strength", NodeItem::Type::Float);
NodeItem alpha = get_input_value("Alpha", NodeItem::Type::Float);
// transparency = 1.0 - alpha
NodeItem normal = get_input_link("Normal", NodeItem::Type::Vector3);
NodeItem clearcoat_normal = get_input_link("Clearcoat Normal", NodeItem::Type::Vector3);
NodeItem tangent = get_input_link("Tangent", NodeItem::Type::Vector3);
/* Creating standard_surface */
NodeItem res = create_node("standard_surface", NodeItem::Type::SurfaceShader);
res.set_input("base", val(1.0f));
res.set_input("base_color", base_color);
res.set_input("diffuse_roughness", roughness);
if (normal) {
res.set_input("normal", normal);
}
if (tangent) {
res.set_input("tangent", tangent);
}
res.set_input("metalness", metallic);
res.set_input("specular", specular);
res.set_input("specular_color", base_color);
res.set_input("specular_roughness", roughness);
res.set_input("specular_IOR", ior);
res.set_input("specular_anisotropy", anisotropic);
res.set_input("specular_rotation", anisotropic_rotation);
res.set_input("transmission", transmission);
res.set_input("transmission_color", base_color);
res.set_input("transmission_extra_roughness", roughness);
res.set_input("subsurface", subsurface);
res.set_input("subsurface_color", subsurface_color);
res.set_input("subsurface_radius", subsurface_radius);
res.set_input("subsurface_anisotropy", anisotropic);
res.set_input("sheen", sheen);
res.set_input("sheen_color", base_color);
res.set_input("sheen_roughness", roughness);
res.set_input("coat", clearcoat);
res.set_input("coat_color", base_color);
res.set_input("coat_roughness", clearcoat_roughness);
res.set_input("coat_IOR", ior);
res.set_input("coat_anisotropy", anisotropic);
res.set_input("coat_rotation", anisotropic_rotation);
if (clearcoat_normal) {
res.set_input("coat_normal", clearcoat_normal);
}
res.set_input("emission", emission_strength);
res.set_input("emission_color", emission);
return res;
}
} // namespace blender::nodes::materialx

View File

@ -1,15 +0,0 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_parser.h"
namespace blender::nodes::materialx {
NodeItem BSDFRefractionNodeParser::compute()
{
/* TODO: implement */
return empty();
}
} // namespace blender::nodes::materialx

View File

@ -1,15 +0,0 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_parser.h"
namespace blender::nodes::materialx {
NodeItem BSDFSheenNodeParser::compute()
{
/* TODO: implement */
return empty();
}
} // namespace blender::nodes::materialx

View File

@ -1,15 +0,0 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_parser.h"
namespace blender::nodes::materialx {
NodeItem BSDFToonNodeParser::compute()
{
/* TODO: implement */
return empty();
}
} // namespace blender::nodes::materialx

View File

@ -1,15 +0,0 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_parser.h"
namespace blender::nodes::materialx {
NodeItem BSDFTranslucentNodeParser::compute()
{
/* TODO: implement */
return empty();
}
} // namespace blender::nodes::materialx

View File

@ -1,15 +0,0 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_parser.h"
namespace blender::nodes::materialx {
NodeItem BSDFTransparentNodeParser::compute()
{
/* TODO: implement */
return empty();
}
} // namespace blender::nodes::materialx

View File

@ -1,27 +0,0 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_parser.h"
namespace blender::nodes::materialx {
NodeItem ClampNodeParser::compute()
{
auto type = node_->custom1;
NodeItem value = get_input_value("Value", NodeItem::Type::Float);
NodeItem min = get_input_value("Min", NodeItem::Type::Float);
NodeItem max = get_input_value("Max", NodeItem::Type::Float);
NodeItem res = empty();
if (type == NODE_CLAMP_RANGE) {
res = min.if_else(
NodeItem::CompareOp::Less, max, value.clamp(min, max), value.clamp(max, min));
}
else {
res = value.clamp(min, max);
}
return res;
}
} // namespace blender::nodes::materialx

View File

@ -1,15 +0,0 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_parser.h"
namespace blender::nodes::materialx {
NodeItem ColorRampNodeParser::compute()
{
/* TODO: implement */
return empty();
}
} // namespace blender::nodes::materialx

View File

@ -1,21 +0,0 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_parser.h"
namespace blender::nodes::materialx {
NodeItem CurvesRGBNodeParser::compute()
{
/* TODO: implement */
return get_input_value("Color", NodeItem::Type::Color4);
}
NodeItem CurvesFloatNodeParser::compute()
{
/* TODO: implement */
return get_input_value("Value", NodeItem::Type::Float);
}
} // namespace blender::nodes::materialx

View File

@ -1,23 +0,0 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_parser.h"
namespace blender::nodes::materialx {
NodeItem EmissionNodeParser::compute()
{
if (shader_type_ != NodeItem::Type::EDF) {
return empty();
}
NodeItem color = get_input_value("Color", NodeItem::Type::Color3);
NodeItem strength = get_input_value("Strength", NodeItem::Type::Float);
NodeItem res = create_node("uniform_edf", NodeItem::Type::EDF);
res.set_input("color", color * strength);
return res;
}
} // namespace blender::nodes::materialx

View File

@ -1,17 +0,0 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_parser.h"
namespace blender::nodes::materialx {
NodeItem GammaNodeParser::compute()
{
NodeItem color = get_input_value("Color", NodeItem::Type::Color4);
NodeItem gamma = get_input_value("Gamma", NodeItem::Type::Float);
return color ^ gamma;
}
} // namespace blender::nodes::materialx

View File

@ -1,33 +0,0 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_parser.h"
namespace blender::nodes::materialx {
NodeItem HueSatValNodeParser::compute()
{
/* TODO: implement fac, see do_hue_sat_fac in
* source\blender\nodes\texture\nodes\node_texture_hueSatVal.cc */
NodeItem hue = get_input_value("Hue", NodeItem::Type::Float);
NodeItem saturation = get_input_value("Saturation", NodeItem::Type::Float);
NodeItem value = get_input_value("Value", NodeItem::Type::Float);
NodeItem fac = get_input_value("Fac", NodeItem::Type::Float);
NodeItem color = get_input_value("Color", NodeItem::Type::Color3);
/* Modifier to follow Cycles result */
hue = hue - val(0.5f);
NodeItem combine = create_node("combine3", NodeItem::Type::Vector3);
combine.set_input("in1", hue);
combine.set_input("in2", saturation);
combine.set_input("in3", value);
NodeItem res = create_node("hsvadjust", NodeItem::Type::Color3);
res.set_input("in", color);
res.set_input("amount", combine);
return res;
}
} // namespace blender::nodes::materialx

View File

@ -1,16 +0,0 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_parser.h"
namespace blender::nodes::materialx {
NodeItem InvertNodeParser::compute()
{
NodeItem fac = get_input_value("Fac", NodeItem::Type::Float);
NodeItem color = get_input_value("Color", NodeItem::Type::Color3);
return fac.blend(color, fac.val(1.0f) - color);
}
} // namespace blender::nodes::materialx

View File

@ -1,21 +0,0 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_parser.h"
namespace blender::nodes::materialx {
NodeItem LightFalloffNodeParser::compute()
{
NodeItem strength = get_input_value("Strength", NodeItem::Type::Float);
NodeItem smooth = get_input_value("Smooth", NodeItem::Type::Float);
/* 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. */
strength = strength * val(1.0f) / (smooth + val(1.0f));
return strength;
}
} // namespace blender::nodes::materialx

View File

@ -1,21 +0,0 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_parser.h"
namespace blender::nodes::materialx {
NodeItem LightPathNodeParser::compute()
{
/* This node isn't supported by MaterialX. Only default values returned. */
if (STREQ(socket_out_->name, "Is Camera Ray")) {
return val(1.0f);
}
if (STREQ(socket_out_->name, "Ray Length")) {
return val(1.0f);
}
return val(0.0f);
}
} // namespace blender::nodes::materialx

View File

@ -1,51 +0,0 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_parser.h"
namespace blender::nodes::materialx {
NodeItem MapRangeNodeParser::compute()
{
/* Interpolation isn't supported by MaterialX. */
const NodeMapRange *map_range = static_cast<NodeMapRange *>(node_->storage);
NodeItem::Type type;
NodeItem value = empty();
NodeItem from_min = empty();
NodeItem from_max = empty();
NodeItem to_min = empty();
NodeItem to_max = empty();
switch (map_range->data_type) {
case CD_PROP_FLOAT:
type = NodeItem::Type::Float;
value = get_input_value("Value", type);
from_min = get_input_value(1, type);
from_max = get_input_value(2, type);
to_min = get_input_value(3, type);
to_max = get_input_value(4, type);
break;
case CD_PROP_FLOAT3:
type = NodeItem::Type::Vector3;
value = get_input_value("Vector", type);
from_min = get_input_value(7, type);
from_max = get_input_value(8, type);
to_min = get_input_value(9, type);
to_max = get_input_value(10, type);
break;
default:
BLI_assert_unreachable();
}
NodeItem res = create_node("range", type);
res.set_input("in", value);
res.set_input("inlow", from_min);
res.set_input("inhigh", from_max);
res.set_input("outlow", to_min);
res.set_input("outhigh", to_max);
res.set_input("doclamp", val(bool(map_range->clamp)));
return res;
}
} // namespace blender::nodes::materialx

View File

@ -1,171 +0,0 @@
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "../material.h"
#include "node_parser.h"
namespace blender::nodes::materialx {
NodeItem MathNodeParser::compute()
{
/* TODO: finish some math operations */
NodeMathOperation op = NodeMathOperation(node_->custom1);
NodeItem res = empty();
/* Single operand operations */
NodeItem x = get_input_value(0, NodeItem::Type::Float);
/* TODO: Seems we have to use average if Vector or Color are added */
switch (op) {
case NODE_MATH_SINE:
res = x.sin();
break;
case NODE_MATH_COSINE:
res = x.cos();
break;
case NODE_MATH_TANGENT:
res = x.tan();
break;
case NODE_MATH_ARCSINE:
res = x.asin();
break;
case NODE_MATH_ARCCOSINE:
res = x.acos();
break;
case NODE_MATH_ARCTANGENT:
res = x.atan();
break;
case NODE_MATH_ROUND:
res = (x + val(0.5f)).floor();
break;
case NODE_MATH_ABSOLUTE:
res = x.abs();
break;
case NODE_MATH_FLOOR:
res = x.floor();
break;
case NODE_MATH_CEIL:
res = x.ceil();
break;
case NODE_MATH_FRACTION:
res = x % val(1.0f);
break;
case NODE_MATH_SQRT:
res = x.sqrt();
break;
case NODE_MATH_INV_SQRT:
res = val(1.0f) / x.sqrt();
break;
case NODE_MATH_SIGN:
res = x.sign();
break;
case NODE_MATH_EXPONENT:
res = x.exp();
break;
case NODE_MATH_RADIANS:
res = x * val(float(M_PI) / 180.0f);
break;
case NODE_MATH_DEGREES:
res = x * val(180.0f * float(M_1_PI));
break;
case NODE_MATH_SINH:
res = x.sinh();
break;
case NODE_MATH_COSH:
res = x.cosh();
break;
case NODE_MATH_TANH:
res = x.tanh();
break;
case NODE_MATH_TRUNC:
res = x.sign() * x.abs().floor();
break;
default: {
/* 2-operand operations */
NodeItem y = get_input_value(1, NodeItem::Type::Float);
switch (op) {
case NODE_MATH_ADD:
res = x + y;
break;
case NODE_MATH_SUBTRACT:
res = x - y;
break;
case NODE_MATH_MULTIPLY:
res = x * y;
break;
case NODE_MATH_DIVIDE:
res = x / y;
break;
case NODE_MATH_POWER:
res = x ^ y;
break;
case NODE_MATH_LOGARITHM:
res = x.ln() / y.ln();
break;
case NODE_MATH_MINIMUM:
res = x.min(y);
break;
case NODE_MATH_MAXIMUM:
res = x.max(y);
break;
case NODE_MATH_LESS_THAN:
res = x.if_else(NodeItem::CompareOp::Less, y, val(1.0f), val(0.0f));
break;
case NODE_MATH_GREATER_THAN:
res = x.if_else(NodeItem::CompareOp::Greater, y, val(1.0f), val(0.0f));
break;
case NODE_MATH_MODULO:
res = x % y;
break;
case NODE_MATH_ARCTAN2:
res = x.atan2(y);
break;
case NODE_MATH_SNAP:
CLOG_WARN(LOG_MATERIALX_SHADER, "Unimplemented math operation %d", op);
break;
case NODE_MATH_PINGPONG:
CLOG_WARN(LOG_MATERIALX_SHADER, "Unimplemented math operation %d", op);
break;
case NODE_MATH_FLOORED_MODULO:
CLOG_WARN(LOG_MATERIALX_SHADER, "Unimplemented math operation %d", op);
break;
default: {
/* 3-operand operations */
NodeItem z = get_input_value(2, NodeItem::Type::Float);
switch (op) {
case NODE_MATH_WRAP:
CLOG_WARN(LOG_MATERIALX_SHADER, "Unimplemented math operation %d", op);
break;
case NODE_MATH_COMPARE:
res = z.if_else(NodeItem::CompareOp::Less, (x - y).abs(), val(1.0f), val(0.0f));
break;
case NODE_MATH_MULTIPLY_ADD:
res = x * y + z;
break;
case NODE_MATH_SMOOTH_MIN:
CLOG_WARN(LOG_MATERIALX_SHADER, "Unimplemented math operation %d", op);
break;
case NODE_MATH_SMOOTH_MAX:
CLOG_WARN(LOG_MATERIALX_SHADER, "Unimplemented math operation %d", op);
break;