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
21 changed files with 494 additions and 92 deletions
Showing only changes of commit f0e894b2ad - Show all commits

View File

@ -147,28 +147,9 @@ set(LIB
if(WITH_MATERIALX) if(WITH_MATERIALX)
list(APPEND SRC list(APPEND SRC
materialx/material.cc materialx/material.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_item.cc
materialx/nodes/node_parser.cc materialx/nodes/node_parser.cc
materialx/nodes/normal_map.cc
materialx/nodes/output_material.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_environment.cc
materialx/nodes/tex_noise.cc
materialx/nodes/vector_math.cc
materialx/nodes/wavelength.cc
materialx/material.h materialx/material.h
materialx/nodes/node_item.h materialx/nodes/node_item.h

View File

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

View File

@ -10,8 +10,12 @@
#include "DNA_material_types.h" #include "DNA_material_types.h"
#include "DNA_node_types.h" #include "DNA_node_types.h"
#include "CLG_log.h"
namespace blender::nodes::materialx { namespace blender::nodes::materialx {
extern struct CLG_LogRef *LOG_MATERIALX_SHADER;
class NodeParser { class NodeParser {
protected: protected:
MaterialX::GraphElement *graph_; MaterialX::GraphElement *graph_;
@ -59,54 +63,6 @@ template<class T> NodeItem NodeParser::val(const T &data) const
return empty().val(data); return empty().val(data);
} }
#define DECLARE_NODE_PARSER(T) \
class T : public NodeParser { \
public: \
using NodeParser::NodeParser; \
NodeItem compute() override; \
};
DECLARE_NODE_PARSER(BlackbodyNodeParser)
DECLARE_NODE_PARSER(BrightContrastNodeParser)
DECLARE_NODE_PARSER(ClampNodeParser)
DECLARE_NODE_PARSER(ColorRampNodeParser)
DECLARE_NODE_PARSER(CurvesFloatNodeParser)
DECLARE_NODE_PARSER(CurvesRGBNodeParser)
DECLARE_NODE_PARSER(CombineColorNodeParser)
DECLARE_NODE_PARSER(CombineXYZNodeParser)
DECLARE_NODE_PARSER(GammaNodeParser)
DECLARE_NODE_PARSER(HueSatValNodeParser)
DECLARE_NODE_PARSER(InvertNodeParser)
DECLARE_NODE_PARSER(LightFalloffNodeParser)
DECLARE_NODE_PARSER(LightPathNodeParser)
DECLARE_NODE_PARSER(MapRangeNodeParser)
DECLARE_NODE_PARSER(MathNodeParser)
DECLARE_NODE_PARSER(MixRGBNodeParser)
DECLARE_NODE_PARSER(NormalMapNodeParser)
DECLARE_NODE_PARSER(RGBToBWNodeParser)
DECLARE_NODE_PARSER(SeparateColorNodeParser)
DECLARE_NODE_PARSER(SeparateXYZNodeParser)
DECLARE_NODE_PARSER(TexCheckerNodeParser)
DECLARE_NODE_PARSER(TexEnvironmentNodeParser)
DECLARE_NODE_PARSER(TexImageNodeParser)
DECLARE_NODE_PARSER(TexNoiseNodeParser)
DECLARE_NODE_PARSER(VectorMathNodeParser)
DECLARE_NODE_PARSER(WavelengthNodeParser)
DECLARE_NODE_PARSER(AddShaderNodeParser)
DECLARE_NODE_PARSER(BSDFDiffuseNodeParser)
DECLARE_NODE_PARSER(BSDFGlassNodeParser)
DECLARE_NODE_PARSER(BSDFGlossyNodeParser)
DECLARE_NODE_PARSER(BSDFPrincipledNodeParser)
DECLARE_NODE_PARSER(BSDFRefractionNodeParser)
DECLARE_NODE_PARSER(BSDFSheenNodeParser)
DECLARE_NODE_PARSER(BSDFToonNodeParser)
DECLARE_NODE_PARSER(BSDFTranslucentNodeParser)
DECLARE_NODE_PARSER(BSDFTransparentNodeParser)
DECLARE_NODE_PARSER(EmissionNodeParser)
DECLARE_NODE_PARSER(MixShaderNodeParser)
DECLARE_NODE_PARSER(SubsurfaceScatteringNodeParser)
struct NodeParserData { struct NodeParserData {
MaterialX::GraphElement *graph; MaterialX::GraphElement *graph;
const Depsgraph *depsgraph; const Depsgraph *depsgraph;

View File

@ -43,6 +43,7 @@ NODE_SHADER_MATERIALX_BEGIN
break; break;
} }
case NodeItem::Type::SurfaceShader: { case NodeItem::Type::SurfaceShader: {
/* SurfaceShaders can't be added, returning the first one connected */
res = get_input_shader(0, to_type_); res = get_input_shader(0, to_type_);
if (!res) { if (!res) {
res = get_input_shader(1, to_type_); res = get_input_shader(1, to_type_);

View File

@ -22,6 +22,13 @@ static int node_shader_gpu_gamma(GPUMaterial *mat,
{ {
return GPU_stack_link(mat, node, "node_gamma", in, out); return GPU_stack_link(mat, node, "node_gamma", in, out);
} }
NODE_SHADER_MATERIALX_BEGIN
{
NodeItem color = get_input_value("Color", NodeItem::Type::Color4);
NodeItem gamma = get_input_value("Gamma", NodeItem::Type::Float);
return color ^ gamma;
}
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_gamma_cc } // namespace blender::nodes::node_shader_gamma_cc
@ -34,6 +41,7 @@ void register_node_type_sh_gamma()
sh_node_type_base(&ntype, SH_NODE_GAMMA, "Gamma", NODE_CLASS_OP_COLOR); sh_node_type_base(&ntype, SH_NODE_GAMMA, "Gamma", NODE_CLASS_OP_COLOR);
ntype.declare = file_ns::node_declare; ntype.declare = file_ns::node_declare;
ntype.gpu_fn = file_ns::node_shader_gpu_gamma; ntype.gpu_fn = file_ns::node_shader_gpu_gamma;
ntype.materialx_fn = file_ns::node_shader_materialx;
nodeRegisterType(&ntype); nodeRegisterType(&ntype);
} }

View File

@ -30,6 +30,30 @@ static int gpu_shader_hue_sat(GPUMaterial *mat,
return GPU_stack_link(mat, node, "hue_sat", in, out); return GPU_stack_link(mat, node, "hue_sat", in, out);
} }
NODE_SHADER_MATERIALX_BEGIN
{
/* TODO: implement fac */
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;
}
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_hueSatVal_cc } // namespace blender::nodes::node_shader_hueSatVal_cc
void register_node_type_sh_hue_sat() void register_node_type_sh_hue_sat()
@ -42,6 +66,7 @@ void register_node_type_sh_hue_sat()
ntype.declare = file_ns::node_declare; ntype.declare = file_ns::node_declare;
blender::bke::node_type_size_preset(&ntype, blender::bke::eNodeSizePreset::MIDDLE); blender::bke::node_type_size_preset(&ntype, blender::bke::eNodeSizePreset::MIDDLE);
ntype.gpu_fn = file_ns::gpu_shader_hue_sat; ntype.gpu_fn = file_ns::gpu_shader_hue_sat;
ntype.materialx_fn = file_ns::node_shader_materialx;
nodeRegisterType(&ntype); nodeRegisterType(&ntype);
} }

View File

@ -26,6 +26,14 @@ static int gpu_shader_invert(GPUMaterial *mat,
return GPU_stack_link(mat, node, "invert", in, out); return GPU_stack_link(mat, node, "invert", in, out);
} }
NODE_SHADER_MATERIALX_BEGIN
{
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);
}
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_invert_cc } // namespace blender::nodes::node_shader_invert_cc
void register_node_type_sh_invert() void register_node_type_sh_invert()
@ -37,6 +45,7 @@ void register_node_type_sh_invert()
sh_node_type_base(&ntype, SH_NODE_INVERT, "Invert Color", NODE_CLASS_OP_COLOR); sh_node_type_base(&ntype, SH_NODE_INVERT, "Invert Color", NODE_CLASS_OP_COLOR);
ntype.declare = file_ns::node_declare; ntype.declare = file_ns::node_declare;
ntype.gpu_fn = file_ns::gpu_shader_invert; ntype.gpu_fn = file_ns::gpu_shader_invert;
ntype.materialx_fn = file_ns::node_shader_materialx;
nodeRegisterType(&ntype); nodeRegisterType(&ntype);
} }

View File

@ -24,6 +24,17 @@ static int node_shader_gpu_light_falloff(GPUMaterial *mat,
return GPU_stack_link(mat, node, "node_light_falloff", in, out); return GPU_stack_link(mat, node, "node_light_falloff", in, out);
} }
NODE_SHADER_MATERIALX_BEGIN
{
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. */
return strength * val(1.0f) / (smooth + val(1.0f));
}
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_light_falloff_cc } // namespace blender::nodes::node_shader_light_falloff_cc
/* node type definition */ /* node type definition */
@ -37,6 +48,7 @@ void register_node_type_sh_light_falloff()
ntype.declare = file_ns::node_declare; ntype.declare = file_ns::node_declare;
blender::bke::node_type_size_preset(&ntype, blender::bke::eNodeSizePreset::MIDDLE); blender::bke::node_type_size_preset(&ntype, blender::bke::eNodeSizePreset::MIDDLE);
ntype.gpu_fn = file_ns::node_shader_gpu_light_falloff; ntype.gpu_fn = file_ns::node_shader_gpu_light_falloff;
ntype.materialx_fn = file_ns::node_shader_materialx;
nodeRegisterType(&ntype); nodeRegisterType(&ntype);
} }

View File

@ -32,6 +32,19 @@ static int node_shader_gpu_light_path(GPUMaterial *mat,
return GPU_stack_link(mat, node, "node_light_path", in, out); return GPU_stack_link(mat, node, "node_light_path", in, out);
} }
NODE_SHADER_MATERIALX_BEGIN
{
/* 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);
}
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_light_path_cc } // namespace blender::nodes::node_shader_light_path_cc
/* node type definition */ /* node type definition */
@ -44,6 +57,7 @@ void register_node_type_sh_light_path()
sh_node_type_base(&ntype, SH_NODE_LIGHT_PATH, "Light Path", NODE_CLASS_INPUT); sh_node_type_base(&ntype, SH_NODE_LIGHT_PATH, "Light Path", NODE_CLASS_INPUT);
ntype.declare = file_ns::node_declare; ntype.declare = file_ns::node_declare;
ntype.gpu_fn = file_ns::node_shader_gpu_light_path; ntype.gpu_fn = file_ns::node_shader_gpu_light_path;
ntype.materialx_fn = file_ns::node_shader_materialx;
nodeRegisterType(&ntype); nodeRegisterType(&ntype);
} }

View File

@ -442,6 +442,49 @@ static void sh_node_map_range_build_multi_function(NodeMultiFunctionBuilder &bui
} }
} }
NODE_SHADER_MATERIALX_BEGIN
{
/* TODO: Implement steps */
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;
}
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_map_range_cc } // namespace blender::nodes::node_shader_map_range_cc
void register_node_type_sh_map_range() void register_node_type_sh_map_range()
@ -461,5 +504,6 @@ void register_node_type_sh_map_range()
ntype.gpu_fn = file_ns::gpu_shader_map_range; ntype.gpu_fn = file_ns::gpu_shader_map_range;
ntype.build_multi_function = file_ns::sh_node_map_range_build_multi_function; ntype.build_multi_function = file_ns::sh_node_map_range_build_multi_function;
ntype.gather_link_search_ops = file_ns::node_map_range_gather_link_searches; ntype.gather_link_search_ops = file_ns::node_map_range_gather_link_searches;
ntype.materialx_fn = file_ns::node_shader_materialx;
nodeRegisterType(&ntype); nodeRegisterType(&ntype);
} }

View File

@ -177,6 +177,170 @@ static void sh_node_math_build_multi_function(NodeMultiFunctionBuilder &builder)
} }
} }
NODE_SHADER_MATERIALX_BEGIN
{
CLG_LogRef *LOG_MATERIALX_SHADER = materialx::LOG_MATERIALX_SHADER;
/* 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;
default:
BLI_assert_unreachable();
}
}
}
}
}
bool clamp_output = node_->custom2 != 0;
if (clamp_output && res) {
res = res.clamp();
}
return res;
}
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_math_cc } // namespace blender::nodes::node_shader_math_cc
void register_node_type_sh_math() void register_node_type_sh_math()
@ -192,6 +356,7 @@ void register_node_type_sh_math()
ntype.updatefunc = node_math_update; ntype.updatefunc = node_math_update;
ntype.build_multi_function = file_ns::sh_node_math_build_multi_function; ntype.build_multi_function = file_ns::sh_node_math_build_multi_function;
ntype.gather_link_search_ops = file_ns::sh_node_math_gather_link_searches; ntype.gather_link_search_ops = file_ns::sh_node_math_gather_link_searches;
ntype.materialx_fn = file_ns::node_shader_materialx;
nodeRegisterType(&ntype); nodeRegisterType(&ntype);
} }

View File

@ -150,6 +150,13 @@ static void sh_node_mix_rgb_build_multi_function(NodeMultiFunctionBuilder &build
builder.construct_and_set_matching_fn<MixRGBFunction>(clamp, mix_type); builder.construct_and_set_matching_fn<MixRGBFunction>(clamp, mix_type);
} }
NODE_SHADER_MATERIALX_BEGIN
{
/* TODO: Implement */
return empty();
}
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_mix_rgb_cc } // namespace blender::nodes::node_shader_mix_rgb_cc
void register_node_type_sh_mix_rgb() void register_node_type_sh_mix_rgb()
@ -165,5 +172,6 @@ void register_node_type_sh_mix_rgb()
ntype.build_multi_function = file_ns::sh_node_mix_rgb_build_multi_function; ntype.build_multi_function = file_ns::sh_node_mix_rgb_build_multi_function;
ntype.gather_link_search_ops = nullptr; ntype.gather_link_search_ops = nullptr;
ntype.gather_add_node_search_ops = nullptr; ntype.gather_add_node_search_ops = nullptr;
ntype.materialx_fn = file_ns::node_shader_materialx;
nodeRegisterType(&ntype); nodeRegisterType(&ntype);
} }

View File

@ -23,6 +23,45 @@ static int node_shader_gpu_mix_shader(GPUMaterial *mat,
return GPU_stack_link(mat, node, "node_mix_shader", in, out); return GPU_stack_link(mat, node, "node_mix_shader", in, out);
} }
NODE_SHADER_MATERIALX_BEGIN
{
NodeItem res = empty();
switch (to_type_) {
case NodeItem::Type::BSDF:
case NodeItem::Type::EDF: {
NodeItem fac = get_input_value(0, NodeItem::Type::Float);
NodeItem shader1 = get_input_shader(1, to_type_);
NodeItem shader2 = get_input_shader(2, to_type_);
if (shader1 && !shader2) {
res = shader1 * (val(1.0f) - fac);
}
else if (!shader1 && shader2) {
res = shader2 * fac;
}
else if (shader1 && shader2) {
res = create_node("mix", to_type_);
res.set_input("fg", shader1);
res.set_input("bg", shader2);
res.set_input("mix", fac);
}
break;
}
case NodeItem::Type::SurfaceShader: {
/* SurfaceShaders can't be mixed, returning the first one connected */
res = get_input_shader(1, NodeItem::Type::SurfaceShader);
if (!res) {
res = get_input_shader(2, NodeItem::Type::SurfaceShader);
}
break;
}
default:
BLI_assert_unreachable();
}
return res;
}
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_mix_shader_cc } // namespace blender::nodes::node_shader_mix_shader_cc
/* node type definition */ /* node type definition */
@ -35,6 +74,7 @@ void register_node_type_sh_mix_shader()
sh_node_type_base(&ntype, SH_NODE_MIX_SHADER, "Mix Shader", NODE_CLASS_SHADER); sh_node_type_base(&ntype, SH_NODE_MIX_SHADER, "Mix Shader", NODE_CLASS_SHADER);
ntype.declare = file_ns::node_declare; ntype.declare = file_ns::node_declare;
ntype.gpu_fn = file_ns::node_shader_gpu_mix_shader; ntype.gpu_fn = file_ns::node_shader_gpu_mix_shader;
ntype.materialx_fn = file_ns::node_shader_materialx;
nodeRegisterType(&ntype); nodeRegisterType(&ntype);
} }

View File

@ -122,6 +122,38 @@ static int gpu_shader_normal_map(GPUMaterial *mat,
return true; return true;
} }
NODE_SHADER_MATERIALX_BEGIN
{
NodeShaderNormalMap *normal_map_node = static_cast<NodeShaderNormalMap *>(node_->storage);
NodeItem color = get_input_value("Color", NodeItem::Type::Color3);
NodeItem strength = get_input_value("Strength", NodeItem::Type::Float);
std::string space;
switch (normal_map_node->space) {
case SHD_SPACE_TANGENT:
space = "tangent";
break;
case SHD_SPACE_OBJECT:
case SHD_SPACE_BLENDER_OBJECT:
space = "object";
break;
case SHD_SPACE_WORLD:
case SHD_SPACE_BLENDER_WORLD:
/* World isn't supported, tangent space will be used */
space = "tangent";
break;
default:
BLI_assert_unreachable();
}
NodeItem res = create_node("normalmap", NodeItem::Type::Vector3);
res.set_input("in", color);
res.set_input("scale", strength);
res.set_input("space", val(space));
return res;
}
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_normal_map_cc } // namespace blender::nodes::node_shader_normal_map_cc
/* node type definition */ /* node type definition */
@ -139,6 +171,7 @@ void register_node_type_sh_normal_map()
node_type_storage( node_type_storage(
&ntype, "NodeShaderNormalMap", node_free_standard_storage, node_copy_standard_storage); &ntype, "NodeShaderNormalMap", node_free_standard_storage, node_copy_standard_storage);
ntype.gpu_fn = file_ns::gpu_shader_normal_map; ntype.gpu_fn = file_ns::gpu_shader_normal_map;
ntype.materialx_fn = file_ns::node_shader_materialx;
nodeRegisterType(&ntype); nodeRegisterType(&ntype);
} }

View File

@ -45,26 +45,20 @@ static int node_shader_gpu_output_material(GPUMaterial *mat,
NODE_SHADER_MATERIALX_BEGIN NODE_SHADER_MATERIALX_BEGIN
{ {
NodeItem bsdf = get_input_shader("Surface", NodeItem::Type::BSDF);
NodeItem edf = get_input_shader("Surface", NodeItem::Type::EDF);
NodeItem surface = empty(); NodeItem surface = empty();
if (node_) { if (bsdf || edf) {
NodeItem bsdf = get_input_shader("Surface", NodeItem::Type::BSDF); surface = create_node("surface", NodeItem::Type::SurfaceShader);
NodeItem edf = get_input_shader("Surface", NodeItem::Type::EDF); if (bsdf) {
if (bsdf || edf) { surface.set_input("bsdf", bsdf);
surface = create_node("surface", NodeItem::Type::SurfaceShader);
if (bsdf) {
surface.set_input("bsdf", bsdf);
}
if (edf) {
surface.set_input("edf", edf);
}
} }
else { if (edf) {
surface = get_input_shader("Surface", NodeItem::Type::SurfaceShader); surface.set_input("edf", edf);
} }
} }
else { else {
surface = create_node("standard_surface", NodeItem::Type::SurfaceShader); surface = get_input_shader("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); NodeItem res = create_node("surfacematerial", NodeItem::Type::Material);
res.set_input("surfaceshader", surface); res.set_input("surfaceshader", surface);

View File

@ -27,6 +27,16 @@ static int gpu_shader_rgbtobw(GPUMaterial *mat,
return GPU_stack_link(mat, node, "rgbtobw", in, out); return GPU_stack_link(mat, node, "rgbtobw", in, out);
} }
NODE_SHADER_MATERIALX_BEGIN
{
NodeItem color = get_input_value("Color", NodeItem::Type::Color4);
NodeItem res = create_node("luminance", NodeItem::Type::Color4);
res.set_input("in", color);
return res;
}
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_rgb_to_bw_cc } // namespace blender::nodes::node_shader_rgb_to_bw_cc
void register_node_type_sh_rgbtobw() void register_node_type_sh_rgbtobw()
@ -38,6 +48,7 @@ void register_node_type_sh_rgbtobw()
sh_node_type_base(&ntype, SH_NODE_RGBTOBW, "RGB to BW", NODE_CLASS_CONVERTER); sh_node_type_base(&ntype, SH_NODE_RGBTOBW, "RGB to BW", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::sh_node_rgbtobw_declare; ntype.declare = file_ns::sh_node_rgbtobw_declare;
ntype.gpu_fn = file_ns::gpu_shader_rgbtobw; ntype.gpu_fn = file_ns::gpu_shader_rgbtobw;
ntype.materialx_fn = file_ns::node_shader_materialx;
nodeRegisterType(&ntype); nodeRegisterType(&ntype);
} }

View File

@ -68,6 +68,31 @@ static int gpu_shader_sepcolor(GPUMaterial *mat,
return 0; return 0;
} }
NODE_SHADER_MATERIALX_BEGIN
{
int mode = static_cast<NodeCombSepColor *>(node_->storage)->mode;
NodeItem color = get_input_value("Color", NodeItem::Type::Color3);
NodeItem convert = empty();
switch (mode) {
case NODE_COMBSEP_COLOR_RGB:
convert = color;
break;
case NODE_COMBSEP_COLOR_HSV:
case NODE_COMBSEP_COLOR_HSL:
/* NOTE: HSL is unsupported color model, using HSV instead */
convert = create_node("rgbtohsv", NodeItem::Type::Color3);
convert.set_input("in", color);
break;
default:
BLI_assert_unreachable();
}
int index = STREQ(socket_out_->name, "Red") ? 0 : STREQ(socket_out_->name, "Green") ? 1 : 2;
return convert.extract(index);
}
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_separate_color_cc } // namespace blender::nodes::node_shader_separate_color_cc
void register_node_type_sh_sepcolor() void register_node_type_sh_sepcolor()
@ -83,6 +108,7 @@ void register_node_type_sh_sepcolor()
node_type_storage( node_type_storage(
&ntype, "NodeCombSepColor", node_free_standard_storage, node_copy_standard_storage); &ntype, "NodeCombSepColor", node_free_standard_storage, node_copy_standard_storage);
ntype.gpu_fn = file_ns::gpu_shader_sepcolor; ntype.gpu_fn = file_ns::gpu_shader_sepcolor;
ntype.materialx_fn = file_ns::node_shader_materialx;
nodeRegisterType(&ntype); nodeRegisterType(&ntype);
} }
@ -136,6 +162,36 @@ static int gpu_shader_combcolor(GPUMaterial *mat,
return 0; return 0;
} }
NODE_SHADER_MATERIALX_BEGIN
{
int mode = static_cast<NodeCombSepColor *>(node_->storage)->mode;
NodeItem red = get_input_value("Red", NodeItem::Type::Float);
NodeItem green = get_input_value("Green", NodeItem::Type::Float);
NodeItem blue = get_input_value("Blue", NodeItem::Type::Float);
NodeItem combine = create_node("combine3", NodeItem::Type::Color3);
combine.set_input("in1", red);
combine.set_input("in2", green);
combine.set_input("in3", blue);
NodeItem res = empty();
switch (mode) {
case NODE_COMBSEP_COLOR_RGB:
res = combine;
break;
case NODE_COMBSEP_COLOR_HSV:
case NODE_COMBSEP_COLOR_HSL:
/* NOTE: HSL is unsupported color model, using HSV instead */
res = create_node("hsvtorgb", NodeItem::Type::Color3);
res.set_input("in", combine);
break;
default:
BLI_assert_unreachable();
}
return res;
}
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_combine_color_cc } // namespace blender::nodes::node_shader_combine_color_cc
void register_node_type_sh_combcolor() void register_node_type_sh_combcolor()
@ -151,6 +207,7 @@ void register_node_type_sh_combcolor()
node_type_storage( node_type_storage(
&ntype, "NodeCombSepColor", node_free_standard_storage, node_copy_standard_storage); &ntype, "NodeCombSepColor", node_free_standard_storage, node_copy_standard_storage);
ntype.gpu_fn = file_ns::gpu_shader_combcolor; ntype.gpu_fn = file_ns::gpu_shader_combcolor;
ntype.materialx_fn = file_ns::node_shader_materialx;
nodeRegisterType(&ntype); nodeRegisterType(&ntype);
} }

View File

@ -12,7 +12,7 @@
#include "NOD_multi_function.hh" #include "NOD_multi_function.hh"
namespace blender::nodes::node_shader_sepcomb_xyz_cc { namespace blender::nodes::node_shader_sepcomb_xyz_cc::sep {
static void sh_node_sepxyz_declare(NodeDeclarationBuilder &b) static void sh_node_sepxyz_declare(NodeDeclarationBuilder &b)
{ {
@ -90,11 +90,19 @@ static void sh_node_sepxyz_build_multi_function(NodeMultiFunctionBuilder &builde
builder.set_matching_fn(separate_fn); builder.set_matching_fn(separate_fn);
} }
} // namespace blender::nodes::node_shader_sepcomb_xyz_cc NODE_SHADER_MATERIALX_BEGIN
{
NodeItem vector = get_input_value("Vector", NodeItem::Type::Vector3);
int index = STREQ(socket_out_->name, "X") ? 0 : STREQ(socket_out_->name, "Y") ? 1 : 2;
return vector.extract(index);
}
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_sepcomb_xyz_cc::sep
void register_node_type_sh_sepxyz() void register_node_type_sh_sepxyz()
{ {
namespace file_ns = blender::nodes::node_shader_sepcomb_xyz_cc; namespace file_ns = blender::nodes::node_shader_sepcomb_xyz_cc::sep;
static bNodeType ntype; static bNodeType ntype;
@ -102,11 +110,12 @@ void register_node_type_sh_sepxyz()
ntype.declare = file_ns::sh_node_sepxyz_declare; ntype.declare = file_ns::sh_node_sepxyz_declare;
ntype.gpu_fn = file_ns::gpu_shader_sepxyz; ntype.gpu_fn = file_ns::gpu_shader_sepxyz;
ntype.build_multi_function = file_ns::sh_node_sepxyz_build_multi_function; ntype.build_multi_function = file_ns::sh_node_sepxyz_build_multi_function;
ntype.materialx_fn = file_ns::node_shader_materialx;
nodeRegisterType(&ntype); nodeRegisterType(&ntype);
} }
namespace blender::nodes::node_shader_sepcomb_xyz_cc { namespace blender::nodes::node_shader_sepcomb_xyz_cc::comb {
static void sh_node_combxyz_declare(NodeDeclarationBuilder &b) static void sh_node_combxyz_declare(NodeDeclarationBuilder &b)
{ {
@ -135,11 +144,25 @@ static void sh_node_combxyz_build_multi_function(NodeMultiFunctionBuilder &build
builder.set_matching_fn(fn); builder.set_matching_fn(fn);
} }
} // namespace blender::nodes::node_shader_sepcomb_xyz_cc NODE_SHADER_MATERIALX_BEGIN
{
NodeItem x = get_input_value("X", NodeItem::Type::Float);
NodeItem y = get_input_value("Y", NodeItem::Type::Float);
NodeItem z = get_input_value("Z", NodeItem::Type::Float);
NodeItem res = create_node("combine3", NodeItem::Type::Vector3);
res.set_input("in1", x);
res.set_input("in2", y);
res.set_input("in3", z);
return res;
}
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_sepcomb_xyz_cc::comb
void register_node_type_sh_combxyz() void register_node_type_sh_combxyz()
{ {
namespace file_ns = blender::nodes::node_shader_sepcomb_xyz_cc; namespace file_ns = blender::nodes::node_shader_sepcomb_xyz_cc::comb;
static bNodeType ntype; static bNodeType ntype;
@ -147,6 +170,7 @@ void register_node_type_sh_combxyz()
ntype.declare = file_ns::sh_node_combxyz_declare; ntype.declare = file_ns::sh_node_combxyz_declare;
ntype.gpu_fn = file_ns::gpu_shader_combxyz; ntype.gpu_fn = file_ns::gpu_shader_combxyz;
ntype.build_multi_function = file_ns::sh_node_combxyz_build_multi_function; ntype.build_multi_function = file_ns::sh_node_combxyz_build_multi_function;
ntype.materialx_fn = file_ns::node_shader_materialx;
nodeRegisterType(&ntype); nodeRegisterType(&ntype);
} }

View File

@ -127,6 +127,13 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat,
return true; return true;
} }
NODE_SHADER_MATERIALX_BEGIN
{
/* TODO: Implement */
return empty();
}
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_tex_environment_cc } // namespace blender::nodes::node_shader_tex_environment_cc
/* node type definition */ /* node type definition */
@ -144,6 +151,7 @@ void register_node_type_sh_tex_environment()
ntype.gpu_fn = file_ns::node_shader_gpu_tex_environment; ntype.gpu_fn = file_ns::node_shader_gpu_tex_environment;
ntype.labelfunc = node_image_label; ntype.labelfunc = node_image_label;
blender::bke::node_type_size_preset(&ntype, blender::bke::eNodeSizePreset::LARGE); blender::bke::node_type_size_preset(&ntype, blender::bke::eNodeSizePreset::LARGE);
ntype.materialx_fn = file_ns::node_shader_materialx;
nodeRegisterType(&ntype); nodeRegisterType(&ntype);
} }

View File

@ -257,6 +257,13 @@ static void sh_node_noise_build_multi_function(NodeMultiFunctionBuilder &builder
builder.construct_and_set_matching_fn<NoiseFunction>(storage.dimensions, storage.normalize); builder.construct_and_set_matching_fn<NoiseFunction>(storage.dimensions, storage.normalize);
} }
NODE_SHADER_MATERIALX_BEGIN
{
/* TODO: Implement */
return empty();
}
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_tex_noise_cc } // namespace blender::nodes::node_shader_tex_noise_cc
void register_node_type_sh_tex_noise() void register_node_type_sh_tex_noise()
@ -274,6 +281,7 @@ void register_node_type_sh_tex_noise()
ntype.gpu_fn = file_ns::node_shader_gpu_tex_noise; ntype.gpu_fn = file_ns::node_shader_gpu_tex_noise;
ntype.updatefunc = file_ns::node_shader_update_tex_noise; ntype.updatefunc = file_ns::node_shader_update_tex_noise;
ntype.build_multi_function = file_ns::sh_node_noise_build_multi_function; ntype.build_multi_function = file_ns::sh_node_noise_build_multi_function;
ntype.materialx_fn = file_ns::node_shader_materialx;
nodeRegisterType(&ntype); nodeRegisterType(&ntype);
} }

View File

@ -316,6 +316,13 @@ static void sh_node_vector_math_build_multi_function(NodeMultiFunctionBuilder &b
builder.set_matching_fn(fn); builder.set_matching_fn(fn);
} }
NODE_SHADER_MATERIALX_BEGIN
{
/* TODO: Implement */
return empty();
}
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_vector_math_cc } // namespace blender::nodes::node_shader_vector_math_cc
void register_node_type_sh_vect_math() void register_node_type_sh_vect_math()
@ -332,6 +339,7 @@ void register_node_type_sh_vect_math()
ntype.updatefunc = file_ns::node_shader_update_vector_math; ntype.updatefunc = file_ns::node_shader_update_vector_math;
ntype.build_multi_function = file_ns::sh_node_vector_math_build_multi_function; ntype.build_multi_function = file_ns::sh_node_vector_math_build_multi_function;
ntype.gather_link_search_ops = file_ns::sh_node_vector_math_gather_link_searches; ntype.gather_link_search_ops = file_ns::sh_node_vector_math_gather_link_searches;
ntype.materialx_fn = file_ns::node_shader_materialx;
nodeRegisterType(&ntype); nodeRegisterType(&ntype);
} }