forked from blender/blender
Move the MaterialX export code into the existing shader node files #18
@ -147,28 +147,9 @@ set(LIB
|
||||
if(WITH_MATERIALX)
|
||||
list(APPEND SRC
|
||||
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_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_environment.cc
|
||||
materialx/nodes/tex_noise.cc
|
||||
materialx/nodes/vector_math.cc
|
||||
materialx/nodes/wavelength.cc
|
||||
|
||||
materialx/material.h
|
||||
materialx/nodes/node_item.h
|
||||
|
@ -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
|
||||
|
@ -10,8 +10,12 @@
|
||||
#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_;
|
||||
@ -59,54 +63,6 @@ template<class T> NodeItem NodeParser::val(const T &data) const
|
||||
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 {
|
||||
MaterialX::GraphElement *graph;
|
||||
const Depsgraph *depsgraph;
|
||||
|
@ -43,6 +43,7 @@ NODE_SHADER_MATERIALX_BEGIN
|
||||
break;
|
||||
}
|
||||
case NodeItem::Type::SurfaceShader: {
|
||||
/* SurfaceShaders can't be added, returning the first one connected */
|
||||
res = get_input_shader(0, to_type_);
|
||||
if (!res) {
|
||||
res = get_input_shader(1, to_type_);
|
||||
|
@ -22,6 +22,13 @@ static int node_shader_gpu_gamma(GPUMaterial *mat,
|
||||
{
|
||||
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
|
||||
|
||||
@ -34,6 +41,7 @@ void register_node_type_sh_gamma()
|
||||
sh_node_type_base(&ntype, SH_NODE_GAMMA, "Gamma", NODE_CLASS_OP_COLOR);
|
||||
ntype.declare = file_ns::node_declare;
|
||||
ntype.gpu_fn = file_ns::node_shader_gpu_gamma;
|
||||
ntype.materialx_fn = file_ns::node_shader_materialx;
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
@ -30,6 +30,30 @@ static int gpu_shader_hue_sat(GPUMaterial *mat,
|
||||
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
|
||||
|
||||
void register_node_type_sh_hue_sat()
|
||||
@ -42,6 +66,7 @@ void register_node_type_sh_hue_sat()
|
||||
ntype.declare = file_ns::node_declare;
|
||||
blender::bke::node_type_size_preset(&ntype, blender::bke::eNodeSizePreset::MIDDLE);
|
||||
ntype.gpu_fn = file_ns::gpu_shader_hue_sat;
|
||||
ntype.materialx_fn = file_ns::node_shader_materialx;
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
@ -26,6 +26,14 @@ static int gpu_shader_invert(GPUMaterial *mat,
|
||||
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
|
||||
|
||||
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);
|
||||
ntype.declare = file_ns::node_declare;
|
||||
ntype.gpu_fn = file_ns::gpu_shader_invert;
|
||||
ntype.materialx_fn = file_ns::node_shader_materialx;
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
@ -24,6 +24,17 @@ static int node_shader_gpu_light_falloff(GPUMaterial *mat,
|
||||
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
|
||||
|
||||
/* node type definition */
|
||||
@ -37,6 +48,7 @@ void register_node_type_sh_light_falloff()
|
||||
ntype.declare = file_ns::node_declare;
|
||||
blender::bke::node_type_size_preset(&ntype, blender::bke::eNodeSizePreset::MIDDLE);
|
||||
ntype.gpu_fn = file_ns::node_shader_gpu_light_falloff;
|
||||
ntype.materialx_fn = file_ns::node_shader_materialx;
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
@ -32,6 +32,19 @@ static int node_shader_gpu_light_path(GPUMaterial *mat,
|
||||
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
|
||||
|
||||
/* 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);
|
||||
ntype.declare = file_ns::node_declare;
|
||||
ntype.gpu_fn = file_ns::node_shader_gpu_light_path;
|
||||
ntype.materialx_fn = file_ns::node_shader_materialx;
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
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.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.materialx_fn = file_ns::node_shader_materialx;
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
void register_node_type_sh_math()
|
||||
@ -192,6 +356,7 @@ void register_node_type_sh_math()
|
||||
ntype.updatefunc = node_math_update;
|
||||
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.materialx_fn = file_ns::node_shader_materialx;
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
NODE_SHADER_MATERIALX_BEGIN
|
||||
{
|
||||
/* TODO: Implement */
|
||||
return empty();
|
||||
}
|
||||
NODE_SHADER_MATERIALX_END
|
||||
|
||||
} // namespace blender::nodes::node_shader_mix_rgb_cc
|
||||
|
||||
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.gather_link_search_ops = nullptr;
|
||||
ntype.gather_add_node_search_ops = nullptr;
|
||||
ntype.materialx_fn = file_ns::node_shader_materialx;
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
@ -23,6 +23,45 @@ static int node_shader_gpu_mix_shader(GPUMaterial *mat,
|
||||
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
|
||||
|
||||
/* 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);
|
||||
ntype.declare = file_ns::node_declare;
|
||||
ntype.gpu_fn = file_ns::node_shader_gpu_mix_shader;
|
||||
ntype.materialx_fn = file_ns::node_shader_materialx;
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
@ -122,6 +122,38 @@ static int gpu_shader_normal_map(GPUMaterial *mat,
|
||||
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
|
||||
|
||||
/* node type definition */
|
||||
@ -139,6 +171,7 @@ void register_node_type_sh_normal_map()
|
||||
node_type_storage(
|
||||
&ntype, "NodeShaderNormalMap", node_free_standard_storage, node_copy_standard_storage);
|
||||
ntype.gpu_fn = file_ns::gpu_shader_normal_map;
|
||||
ntype.materialx_fn = file_ns::node_shader_materialx;
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
@ -45,26 +45,20 @@ static int node_shader_gpu_output_material(GPUMaterial *mat,
|
||||
|
||||
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();
|
||||
if (node_) {
|
||||
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", NodeItem::Type::SurfaceShader);
|
||||
if (bsdf) {
|
||||
surface.set_input("bsdf", bsdf);
|
||||
}
|
||||
if (edf) {
|
||||
surface.set_input("edf", edf);
|
||||
}
|
||||
if (bsdf || edf) {
|
||||
surface = create_node("surface", NodeItem::Type::SurfaceShader);
|
||||
if (bsdf) {
|
||||
surface.set_input("bsdf", bsdf);
|
||||
}
|
||||
else {
|
||||
surface = get_input_shader("Surface", NodeItem::Type::SurfaceShader);
|
||||
if (edf) {
|
||||
surface.set_input("edf", edf);
|
||||
}
|
||||
}
|
||||
else {
|
||||
surface = create_node("standard_surface", NodeItem::Type::SurfaceShader);
|
||||
surface.set_input("base_color", val(MaterialX::Color3(1.0f, 0.0f, 1.0f)));
|
||||
surface = get_input_shader("Surface", NodeItem::Type::SurfaceShader);
|
||||
}
|
||||
NodeItem res = create_node("surfacematerial", NodeItem::Type::Material);
|
||||
res.set_input("surfaceshader", surface);
|
||||
|
@ -27,6 +27,16 @@ static int gpu_shader_rgbtobw(GPUMaterial *mat,
|
||||
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
|
||||
|
||||
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);
|
||||
ntype.declare = file_ns::sh_node_rgbtobw_declare;
|
||||
ntype.gpu_fn = file_ns::gpu_shader_rgbtobw;
|
||||
ntype.materialx_fn = file_ns::node_shader_materialx;
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
@ -68,6 +68,31 @@ static int gpu_shader_sepcolor(GPUMaterial *mat,
|
||||
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
|
||||
|
||||
void register_node_type_sh_sepcolor()
|
||||
@ -83,6 +108,7 @@ void register_node_type_sh_sepcolor()
|
||||
node_type_storage(
|
||||
&ntype, "NodeCombSepColor", node_free_standard_storage, node_copy_standard_storage);
|
||||
ntype.gpu_fn = file_ns::gpu_shader_sepcolor;
|
||||
ntype.materialx_fn = file_ns::node_shader_materialx;
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
@ -136,6 +162,36 @@ static int gpu_shader_combcolor(GPUMaterial *mat,
|
||||
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
|
||||
|
||||
void register_node_type_sh_combcolor()
|
||||
@ -151,6 +207,7 @@ void register_node_type_sh_combcolor()
|
||||
node_type_storage(
|
||||
&ntype, "NodeCombSepColor", node_free_standard_storage, node_copy_standard_storage);
|
||||
ntype.gpu_fn = file_ns::gpu_shader_combcolor;
|
||||
ntype.materialx_fn = file_ns::node_shader_materialx;
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
#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)
|
||||
{
|
||||
@ -90,11 +90,19 @@ static void sh_node_sepxyz_build_multi_function(NodeMultiFunctionBuilder &builde
|
||||
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()
|
||||
{
|
||||
namespace file_ns = blender::nodes::node_shader_sepcomb_xyz_cc;
|
||||
namespace file_ns = blender::nodes::node_shader_sepcomb_xyz_cc::sep;
|
||||
|
||||
static bNodeType ntype;
|
||||
|
||||
@ -102,11 +110,12 @@ void register_node_type_sh_sepxyz()
|
||||
ntype.declare = file_ns::sh_node_sepxyz_declare;
|
||||
ntype.gpu_fn = file_ns::gpu_shader_sepxyz;
|
||||
ntype.build_multi_function = file_ns::sh_node_sepxyz_build_multi_function;
|
||||
ntype.materialx_fn = file_ns::node_shader_materialx;
|
||||
|
||||
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)
|
||||
{
|
||||
@ -135,11 +144,25 @@ static void sh_node_combxyz_build_multi_function(NodeMultiFunctionBuilder &build
|
||||
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()
|
||||
{
|
||||
namespace file_ns = blender::nodes::node_shader_sepcomb_xyz_cc;
|
||||
namespace file_ns = blender::nodes::node_shader_sepcomb_xyz_cc::comb;
|
||||
|
||||
static bNodeType ntype;
|
||||
|
||||
@ -147,6 +170,7 @@ void register_node_type_sh_combxyz()
|
||||
ntype.declare = file_ns::sh_node_combxyz_declare;
|
||||
ntype.gpu_fn = file_ns::gpu_shader_combxyz;
|
||||
ntype.build_multi_function = file_ns::sh_node_combxyz_build_multi_function;
|
||||
ntype.materialx_fn = file_ns::node_shader_materialx;
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
@ -127,6 +127,13 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat,
|
||||
return true;
|
||||
}
|
||||
|
||||
NODE_SHADER_MATERIALX_BEGIN
|
||||
{
|
||||
/* TODO: Implement */
|
||||
return empty();
|
||||
}
|
||||
NODE_SHADER_MATERIALX_END
|
||||
|
||||
} // namespace blender::nodes::node_shader_tex_environment_cc
|
||||
|
||||
/* 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.labelfunc = node_image_label;
|
||||
blender::bke::node_type_size_preset(&ntype, blender::bke::eNodeSizePreset::LARGE);
|
||||
ntype.materialx_fn = file_ns::node_shader_materialx;
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
NODE_SHADER_MATERIALX_BEGIN
|
||||
{
|
||||
/* TODO: Implement */
|
||||
return empty();
|
||||
}
|
||||
NODE_SHADER_MATERIALX_END
|
||||
|
||||
} // namespace blender::nodes::node_shader_tex_noise_cc
|
||||
|
||||
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.updatefunc = file_ns::node_shader_update_tex_noise;
|
||||
ntype.build_multi_function = file_ns::sh_node_noise_build_multi_function;
|
||||
ntype.materialx_fn = file_ns::node_shader_materialx;
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
@ -316,6 +316,13 @@ static void sh_node_vector_math_build_multi_function(NodeMultiFunctionBuilder &b
|
||||
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
|
||||
|
||||
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.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.materialx_fn = file_ns::node_shader_materialx;
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user