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
10 changed files with 249 additions and 11 deletions
Showing only changes of commit b168808089 - Show all commits

View File

@ -24,8 +24,35 @@ static int node_shader_gpu_add_shader(GPUMaterial *mat,
NODE_SHADER_MATERIALX_BEGIN
{
/* TODO: Implement */
return empty();
NodeItem res = empty();
switch (to_type_) {
case NodeItem::Type::BSDF:
case NodeItem::Type::EDF: {
NodeItem shader1 = get_input_shader(0, to_type_);
NodeItem shader2 = get_input_shader(1, to_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, to_type_);
if (!res) {
res = get_input_shader(1, to_type_);
}
break;
}
default:
BLI_assert_unreachable();
}
return res;
}
NODE_SHADER_MATERIALX_END

View File

@ -31,6 +31,20 @@ static int node_shader_gpu_blackbody(GPUMaterial *mat,
return GPU_stack_link(mat, node, "node_blackbody", in, out, ramp_texture, GPU_constant(&layer));
}
NODE_SHADER_MATERIALX_BEGIN
{
/* TODO: 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();
}
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_blackbody_cc
/* node type definition */
@ -44,6 +58,7 @@ void register_node_type_sh_blackbody()
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_blackbody;
ntype.materialx_fn = file_ns::node_shader_materialx;
nodeRegisterType(&ntype);
}

View File

@ -23,6 +23,17 @@ static int gpu_shader_brightcontrast(GPUMaterial *mat,
return GPU_stack_link(mat, node, "brightness_contrast", in, out);
}
NODE_SHADER_MATERIALX_BEGIN
{
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));
}
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_brightness_cc
void register_node_type_sh_brightcontrast()
@ -34,6 +45,7 @@ void register_node_type_sh_brightcontrast()
sh_node_type_base(&ntype, SH_NODE_BRIGHTCONTRAST, "Brightness/Contrast", NODE_CLASS_OP_COLOR);
ntype.declare = file_ns::node_declare;
ntype.gpu_fn = file_ns::gpu_shader_brightcontrast;
ntype.materialx_fn = file_ns::node_shader_materialx;
nodeRegisterType(&ntype);
}

View File

@ -34,6 +34,26 @@ static int node_shader_gpu_bsdf_diffuse(GPUMaterial *mat,
return GPU_stack_link(mat, node, "node_bsdf_diffuse", in, out);
}
NODE_SHADER_MATERIALX_BEGIN
{
if (to_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;
}
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_bsdf_diffuse_cc
/* node type definition */
@ -48,6 +68,7 @@ void register_node_type_sh_bsdf_diffuse()
ntype.add_ui_poll = object_shader_nodes_poll;
blender::bke::node_type_size_preset(&ntype, blender::bke::eNodeSizePreset::MIDDLE);
ntype.gpu_fn = file_ns::node_shader_gpu_bsdf_diffuse;
ntype.materialx_fn = file_ns::node_shader_materialx;
nodeRegisterType(&ntype);
}

View File

@ -70,6 +70,25 @@ static void sh_node_clamp_build_multi_function(NodeMultiFunctionBuilder &builder
}
}
NODE_SHADER_MATERIALX_BEGIN
{
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;
}
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_clamp_cc
void register_node_type_sh_clamp()
@ -84,6 +103,7 @@ void register_node_type_sh_clamp()
ntype.initfunc = file_ns::node_shader_init_clamp;
ntype.gpu_fn = file_ns::gpu_shader_clamp;
ntype.build_multi_function = file_ns::sh_node_clamp_build_multi_function;
ntype.materialx_fn = file_ns::node_shader_materialx;
nodeRegisterType(&ntype);
}

View File

@ -136,6 +136,13 @@ static void sh_node_valtorgb_build_multi_function(nodes::NodeMultiFunctionBuilde
builder.construct_and_set_matching_fn<ColorBandFunction>(*color_band);
}
NODE_SHADER_MATERIALX_BEGIN
{
/* TODO: Implement */
return empty();
}
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_color_ramp_cc
void register_node_type_sh_valtorgb()
@ -151,6 +158,7 @@ void register_node_type_sh_valtorgb()
node_type_storage(&ntype, "ColorBand", node_free_standard_storage, node_copy_standard_storage);
ntype.gpu_fn = file_ns::gpu_shader_valtorgb;
ntype.build_multi_function = file_ns::sh_node_valtorgb_build_multi_function;
ntype.materialx_fn = file_ns::node_shader_materialx;
nodeRegisterType(&ntype);
}

View File

@ -16,7 +16,7 @@
#include "node_util.hh"
namespace blender::nodes::node_shader_curves_cc {
namespace blender::nodes::node_shader_curves_cc::vec {
static void sh_node_curve_vec_declare(NodeDeclarationBuilder &b)
{
@ -109,11 +109,18 @@ static void sh_node_curve_vec_build_multi_function(NodeMultiFunctionBuilder &bui
builder.construct_and_set_matching_fn<CurveVecFunction>(*cumap);
}
} // namespace blender::nodes::node_shader_curves_cc
NODE_SHADER_MATERIALX_BEGIN
{
/* TODO: Implement */
return empty();
}
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_curves_cc::vec
void register_node_type_sh_curve_vec()
{
namespace file_ns = blender::nodes::node_shader_curves_cc;
namespace file_ns = blender::nodes::node_shader_curves_cc::vec;
static bNodeType ntype;
@ -124,13 +131,14 @@ void register_node_type_sh_curve_vec()
node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves);
ntype.gpu_fn = file_ns::gpu_shader_curve_vec;
ntype.build_multi_function = file_ns::sh_node_curve_vec_build_multi_function;
ntype.materialx_fn = file_ns::node_shader_materialx;
nodeRegisterType(&ntype);
}
/* **************** CURVE RGB ******************** */
namespace blender::nodes::node_shader_curves_cc {
namespace blender::nodes::node_shader_curves_cc::rgb {
static void sh_node_curve_rgb_declare(NodeDeclarationBuilder &b)
{
@ -251,11 +259,18 @@ static void sh_node_curve_rgb_build_multi_function(NodeMultiFunctionBuilder &bui
builder.construct_and_set_matching_fn<CurveRGBFunction>(*cumap);
}
} // namespace blender::nodes::node_shader_curves_cc
NODE_SHADER_MATERIALX_BEGIN
{
/* TODO: Implement */
return empty();
}
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_curves_cc::rgb
void register_node_type_sh_curve_rgb()
{
namespace file_ns = blender::nodes::node_shader_curves_cc;
namespace file_ns = blender::nodes::node_shader_curves_cc::rgb;
static bNodeType ntype;
@ -266,13 +281,14 @@ void register_node_type_sh_curve_rgb()
node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves);
ntype.gpu_fn = file_ns::gpu_shader_curve_rgb;
ntype.build_multi_function = file_ns::sh_node_curve_rgb_build_multi_function;
ntype.materialx_fn = file_ns::node_shader_materialx;
nodeRegisterType(&ntype);
}
/* **************** CURVE FLOAT ******************** */
namespace blender::nodes::node_shader_curves_cc {
namespace blender::nodes::node_shader_curves_cc::flt {
static void sh_node_curve_float_declare(NodeDeclarationBuilder &b)
{
@ -369,11 +385,18 @@ static void sh_node_curve_float_build_multi_function(NodeMultiFunctionBuilder &b
builder.construct_and_set_matching_fn<CurveFloatFunction>(*cumap);
}
} // namespace blender::nodes::node_shader_curves_cc
NODE_SHADER_MATERIALX_BEGIN
{
/* TODO: Implement */
return empty();
}
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_curves_cc::flt
void register_node_type_sh_curve_float()
{
namespace file_ns = blender::nodes::node_shader_curves_cc;
namespace file_ns = blender::nodes::node_shader_curves_cc::flt;
static bNodeType ntype;
@ -384,6 +407,7 @@ void register_node_type_sh_curve_float()
node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves);
ntype.gpu_fn = file_ns::gpu_shader_curve_float;
ntype.build_multi_function = file_ns::sh_node_curve_float_build_multi_function;
ntype.materialx_fn = file_ns::node_shader_materialx;
nodeRegisterType(&ntype);
}

View File

@ -24,6 +24,21 @@ static int node_shader_gpu_emission(GPUMaterial *mat,
return GPU_stack_link(mat, node, "node_emission", in, out);
}
NODE_SHADER_MATERIALX_BEGIN
{
if (to_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;
}
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_emission_cc
/* node type definition */
@ -36,6 +51,7 @@ void register_node_type_sh_emission()
sh_node_type_base(&ntype, SH_NODE_EMISSION, "Emission", NODE_CLASS_SHADER);
ntype.declare = file_ns::node_declare;
ntype.gpu_fn = file_ns::node_shader_gpu_emission;
ntype.materialx_fn = file_ns::node_shader_materialx;
nodeRegisterType(&ntype);
}

View File

@ -102,6 +102,26 @@ static void sh_node_tex_checker_build_multi_function(NodeMultiFunctionBuilder &b
builder.set_matching_fn(fn);
}
NODE_SHADER_MATERIALX_BEGIN
{
NodeItem vector = get_input_link("Vector", NodeItem::Type::Vector2);
if (!vector) {
vector = texcoord_node();
}
NodeItem value1 = val(1.0f);
NodeItem value2 = val(0.0f);
if (STREQ(socket_out_->name, "Color")) {
value1 = get_input_value("Color1", NodeItem::Type::Color4);
value2 = get_input_value("Color2", NodeItem::Type::Color4);
}
NodeItem scale = get_input_value("Scale", NodeItem::Type::Float);
vector = (vector * scale) % val(2.0f);
return (vector.extract(0).floor() + vector.extract(1).floor())
.if_else(NodeItem::CompareOp::Eq, val(1.0f), value1, value2);
}
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_tex_checker_cc
void register_node_type_sh_tex_checker()
@ -117,6 +137,7 @@ void register_node_type_sh_tex_checker()
&ntype, "NodeTexChecker", node_free_standard_storage, node_copy_standard_storage);
ntype.gpu_fn = file_ns::node_shader_gpu_tex_checker;
ntype.build_multi_function = file_ns::sh_node_tex_checker_build_multi_function;
ntype.materialx_fn = file_ns::node_shader_materialx;
nodeRegisterType(&ntype);
}

View File

@ -11,6 +11,10 @@
#include "IMB_colormanagement.h"
#include "hydra/image.h"
#include "DEG_depsgraph_query.h"
namespace blender::nodes::node_shader_tex_image_cc {
static void sh_node_tex_image_declare(NodeDeclarationBuilder &b)
@ -172,6 +176,75 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
return true;
}
NODE_SHADER_MATERIALX_BEGIN
{
NodeItem res = val(MaterialX::Color4(1.0f, 0.0f, 1.0f, 1.0f));
Image *image = (Image *)node_->id;
if (image) {
NodeTexImage *tex_image = static_cast<NodeTexImage *>(node_->storage);
Scene *scene = DEG_get_input_scene(depsgraph_);
Main *bmain = DEG_get_bmain(depsgraph_);
/* TODO: What if Blender built without Hydra? Also io::hydra::cache_or_get_image_file contains
* pretty general code, so could be moved from bf_usd project. */
std::string image_path = io::hydra::cache_or_get_image_file(
bmain, scene, image, &tex_image->iuser);
NodeItem vector = get_input_link("Vector", NodeItem::Type::Vector2);
if (!vector) {
vector = texcoord_node();
}
/* TODO: add math to vector depending of tex_image->projection */
std::string filtertype;
switch (tex_image->interpolation) {
case SHD_INTERP_LINEAR:
filtertype = "linear";
break;
case SHD_INTERP_CLOSEST:
filtertype = "closest";
break;
case SHD_INTERP_CUBIC:
case SHD_INTERP_SMART:
filtertype = "cubic";
break;
default:
BLI_assert_unreachable();
}
std::string addressmode;
switch (tex_image->extension) {
case SHD_IMAGE_EXTENSION_REPEAT:
addressmode = "periodic";
break;
case SHD_IMAGE_EXTENSION_EXTEND:
addressmode = "clamp";
break;
case SHD_IMAGE_EXTENSION_CLIP:
addressmode = "constant";
break;
case SHD_IMAGE_EXTENSION_MIRROR:
addressmode = "mirror";
break;
default:
BLI_assert_unreachable();
}
res = create_node("image", NodeItem::Type::Color4);
res.set_input("file", image_path, NodeItem::Type::Filename);
res.set_input("texcoord", vector);
res.set_input("filtertype", val(filtertype));
res.set_input("uaddressmode", val(addressmode));
res.set_input("vaddressmode", val(addressmode));
}
if (STREQ(socket_out_->name, "Alpha")) {
res = res.extract(3);
}
return res;
}
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_tex_image_cc
void register_node_type_sh_tex_image()
@ -188,6 +261,7 @@ void register_node_type_sh_tex_image()
ntype.gpu_fn = file_ns::node_shader_gpu_tex_image;
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);
}