forked from blender/blender
Code improvements + Mix node #30
@ -82,7 +82,7 @@ void MaterialData::init()
|
|||||||
scene_delegate_->depsgraph, (Material *)id);
|
scene_delegate_->depsgraph, (Material *)id);
|
||||||
pxr::UsdMtlxRead(doc, stage);
|
pxr::UsdMtlxRead(doc, stage);
|
||||||
|
|
||||||
/* Logging stage: creating lambda stage_str() for not to call stage->ExportToString()
|
/* Logging stage: creating lambda stage_str() to not call stage->ExportToString()
|
||||||
* if log won't be printed. */
|
* if log won't be printed. */
|
||||||
auto stage_str = [&stage]() {
|
auto stage_str = [&stage]() {
|
||||||
std::string str;
|
std::string str;
|
||||||
|
@ -184,6 +184,8 @@ NodeItem NodeItem::operator^(const NodeItem &other) const
|
|||||||
|
|
||||||
NodeItem NodeItem::operator[](int index) const
|
NodeItem NodeItem::operator[](int index) const
|
||||||
{
|
{
|
||||||
|
BLI_assert(is_arithmetic(type()));
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
float v = 0.0f;
|
float v = 0.0f;
|
||||||
switch (type()) {
|
switch (type()) {
|
||||||
@ -264,6 +266,14 @@ NodeItem NodeItem::length() const
|
|||||||
return create_node("magnitude", Type::Float, {{"in", to_vector()}});
|
return create_node("magnitude", Type::Float, {{"in", to_vector()}});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NodeItem NodeItem::normalize() const
|
||||||
|
{
|
||||||
|
if (value) {
|
||||||
|
return *this / length();
|
||||||
|
}
|
||||||
|
return create_node("normalize", Type::Vector3, {{"in", to_vector()}});
|
||||||
|
}
|
||||||
|
|
||||||
NodeItem NodeItem::min(const NodeItem &other) const
|
NodeItem NodeItem::min(const NodeItem &other) const
|
||||||
{
|
{
|
||||||
return arithmetic(other, "min", [](float a, float b) { return std::min(a, b); });
|
return arithmetic(other, "min", [](float a, float b) { return std::min(a, b); });
|
||||||
@ -363,6 +373,34 @@ NodeItem NodeItem::clamp(float min_val, float max_val) const
|
|||||||
return clamp(val(min_val), val(max_val));
|
return clamp(val(min_val), val(max_val));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NodeItem NodeItem::rotate(const NodeItem &angle, const NodeItem &axis)
|
||||||
|
{
|
||||||
|
BLI_assert(type() == Type::Vector3);
|
||||||
|
BLI_assert(angle.type() == Type::Float);
|
||||||
|
BLI_assert(axis.type() == Type::Vector3);
|
||||||
|
|
||||||
|
return create_node(
|
||||||
|
"rotate3d",
|
||||||
|
NodeItem::Type::Vector3,
|
||||||
|
{{"in", *this}, {"amount", angle * val(float(180.0f / M_PI))}, {"axis", axis}});
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeItem NodeItem::rotate(const NodeItem &angle_xyz, bool invert)
|
||||||
|
{
|
||||||
|
NodeItem angle = angle_xyz * val(float(180.0f / M_PI));
|
||||||
|
NodeItem x = angle[0];
|
||||||
|
NodeItem y = angle[1];
|
||||||
|
NodeItem z = angle[2];
|
||||||
|
if (invert) {
|
||||||
|
return rotate(z, val(MaterialX::Vector3(0.0f, 0.0f, 1.0f)))
|
||||||
|
.rotate(y, val(MaterialX::Vector3(0.0f, 1.0f, 0.0f)))
|
||||||
|
.rotate(x, val(MaterialX::Vector3(1.0f, 0.0f, 0.0f)));
|
||||||
|
}
|
||||||
|
return rotate(x, val(MaterialX::Vector3(1.0f, 0.0f, 0.0f)))
|
||||||
|
.rotate(y, val(MaterialX::Vector3(0.0f, 1.0f, 0.0f)))
|
||||||
|
.rotate(z, val(MaterialX::Vector3(0.0f, 0.0f, 1.0f)));
|
||||||
|
}
|
||||||
|
|
||||||
NodeItem NodeItem::sin() const
|
NodeItem NodeItem::sin() const
|
||||||
{
|
{
|
||||||
return to_vector().arithmetic("sin", [](float a) { return std::sinf(a); });
|
return to_vector().arithmetic("sin", [](float a) { return std::sinf(a); });
|
||||||
@ -706,23 +744,6 @@ NodeItem NodeItem::empty() const
|
|||||||
return NodeItem(graph_);
|
return NodeItem(graph_);
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeItem NodeItem::rotate3d(NodeItem rotation, bool invert)
|
|
||||||
{
|
|
||||||
NodeItem res = *this;
|
|
||||||
if (res.type() == Type::Vector3 && rotation.type() == Type::Vector3) {
|
|
||||||
for (int i = 0; i <= 2; i++) {
|
|
||||||
int j = invert ? 2 - i : i;
|
|
||||||
MaterialX::Vector3 axis_vector = MaterialX::Vector3();
|
|
||||||
axis_vector[j] = 1.0f;
|
|
||||||
res = create_node(
|
|
||||||
"rotate3d",
|
|
||||||
NodeItem::Type::Vector3,
|
|
||||||
{{"in", res}, {"amount", rotation.extract(j)}, {"axis", val(axis_vector)}});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
NodeItem::Type NodeItem::type() const
|
NodeItem::Type NodeItem::type() const
|
||||||
{
|
{
|
||||||
if (value) {
|
if (value) {
|
||||||
@ -882,9 +903,7 @@ NodeItem NodeItem::arithmetic(const std::string &category, std::function<float(f
|
|||||||
{
|
{
|
||||||
NodeItem res = empty();
|
NodeItem res = empty();
|
||||||
Type type = this->type();
|
Type type = this->type();
|
||||||
if (!is_arithmetic(type)) {
|
BLI_assert(is_arithmetic(type));
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
@ -10,9 +10,11 @@
|
|||||||
|
|
||||||
namespace blender::nodes::materialx {
|
namespace blender::nodes::materialx {
|
||||||
|
|
||||||
/* This class serves as abstraction from MateralX API. It implements arithmetic operations,
|
/**
|
||||||
|
* This class serves as abstraction from MateralX API. It implements arithmetic operations,
|
||||||
* convertions between different types, adding new nodes, setting inputs, etc.
|
* convertions between different types, adding new nodes, setting inputs, etc.
|
||||||
* All work should be done via this class instead of using MaterialX API directly. */
|
* All work should be done via this class instead of using MaterialX API directly.
|
||||||
|
*/
|
||||||
class NodeItem {
|
class NodeItem {
|
||||||
public:
|
public:
|
||||||
using Inputs = std::vector<std::pair<std::string, NodeItem>>;
|
using Inputs = std::vector<std::pair<std::string, NodeItem>>;
|
||||||
@ -21,22 +23,22 @@ class NodeItem {
|
|||||||
Any = 0,
|
Any = 0,
|
||||||
Empty,
|
Empty,
|
||||||
Multioutput,
|
Multioutput,
|
||||||
|
|
||||||
/* Value types */
|
/* Value types */
|
||||||
String,
|
String,
|
||||||
Filename,
|
Filename,
|
||||||
Boolean,
|
Boolean,
|
||||||
Integer,
|
Integer,
|
||||||
/* Block of arithmetic types. Ordered by type cast */
|
|
||||||
|
/* Arithmetic types. NOTE: Ordered by type cast */
|
||||||
Float,
|
Float,
|
||||||
Vector2,
|
Vector2,
|
||||||
Vector3,
|
Vector3,
|
||||||
Color3,
|
Color3,
|
||||||
Vector4,
|
Vector4,
|
||||||
Color4,
|
Color4,
|
||||||
/* End of arithmetic types */
|
|
||||||
|
|
||||||
/* Shader types
|
/* Shader types. NOTE: There are only supported types */
|
||||||
* NOTE: There are only supported types */
|
|
||||||
BSDF,
|
BSDF,
|
||||||
EDF,
|
EDF,
|
||||||
Displacementshader,
|
Displacementshader,
|
||||||
@ -83,12 +85,15 @@ class NodeItem {
|
|||||||
NodeItem floor() const;
|
NodeItem floor() const;
|
||||||
NodeItem ceil() const;
|
NodeItem ceil() const;
|
||||||
NodeItem length() const;
|
NodeItem length() const;
|
||||||
|
NodeItem normalize() const;
|
||||||
NodeItem min(const NodeItem &other) const;
|
NodeItem min(const NodeItem &other) const;
|
||||||
NodeItem max(const NodeItem &other) const;
|
NodeItem max(const NodeItem &other) const;
|
||||||
NodeItem dotproduct(const NodeItem &other) const;
|
NodeItem dotproduct(const NodeItem &other) const;
|
||||||
NodeItem mix(const NodeItem &val1, const NodeItem &val2) const;
|
NodeItem mix(const NodeItem &val1, const NodeItem &val2) const;
|
||||||
NodeItem clamp(const NodeItem &min_val, const NodeItem &max_val) const;
|
NodeItem clamp(const NodeItem &min_val, const NodeItem &max_val) const;
|
||||||
NodeItem clamp(float min_val = 0.0f, float max_val = 1.0f) const;
|
NodeItem clamp(float min_val = 0.0f, float max_val = 1.0f) const;
|
||||||
|
NodeItem rotate(const NodeItem &angle, const NodeItem &axis);
|
||||||
|
NodeItem rotate(const NodeItem &angle_xyz, bool invert = false);
|
||||||
NodeItem sin() const;
|
NodeItem sin() const;
|
||||||
NodeItem cos() const;
|
NodeItem cos() const;
|
||||||
NodeItem tan() const;
|
NodeItem tan() const;
|
||||||
@ -112,7 +117,6 @@ class NodeItem {
|
|||||||
|
|
||||||
/* Useful functions */
|
/* Useful functions */
|
||||||
NodeItem empty() const;
|
NodeItem empty() const;
|
||||||
NodeItem rotate3d(NodeItem rotation, bool invert = false);
|
|
||||||
template<class T> NodeItem val(const T &data) const;
|
template<class T> NodeItem val(const T &data) const;
|
||||||
Type type() const;
|
Type type() const;
|
||||||
|
|
||||||
|
@ -18,6 +18,10 @@ extern struct CLG_LogRef *LOG_MATERIALX_SHADER;
|
|||||||
|
|
||||||
class GroupNodeParser;
|
class GroupNodeParser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is base abstraction class for parsing Blender nodes into MaterialX nodes.
|
||||||
|
* NodeParser::compute() should be overrides in child classes.
|
||||||
|
*/
|
||||||
class NodeParser {
|
class NodeParser {
|
||||||
protected:
|
protected:
|
||||||
MaterialX::GraphElement *graph_;
|
MaterialX::GraphElement *graph_;
|
||||||
@ -72,8 +76,21 @@ template<class T> NodeItem NodeParser::val(const T &data) const
|
|||||||
return empty().val(data);
|
return empty().val(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Defines for including MaterialX node parsing code into node_shader_<name>.cc
|
* Defines for including MaterialX node parsing code into node_shader_<name>.cc
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* \code{.c}
|
||||||
|
* NODE_SHADER_MATERIALX_BEGIN
|
||||||
|
* #ifdef WITH_MATERIALX
|
||||||
|
* {
|
||||||
|
* NodeItem color = get_input_value("Color", NodeItem::Type::Color4);
|
||||||
|
* NodeItem gamma = get_input_value("Gamma", NodeItem::Type::Float);
|
||||||
|
* return color ^ gamma;
|
||||||
|
* }
|
||||||
|
* #endif
|
||||||
|
* NODE_SHADER_MATERIALX_END
|
||||||
|
* \endcode
|
||||||
*/
|
*/
|
||||||
struct NodeParserData {
|
struct NodeParserData {
|
||||||
MaterialX::GraphElement *graph;
|
MaterialX::GraphElement *graph;
|
||||||
|
@ -348,14 +348,7 @@ NODE_SHADER_MATERIALX_BEGIN
|
|||||||
|
|
||||||
NodeItem n_main_tangent = empty();
|
NodeItem n_main_tangent = empty();
|
||||||
if (tangent && normal) {
|
if (tangent && normal) {
|
||||||
NodeItem n_tangent_rotate = create_node(
|
NodeItem n_tangent_rotate_normalize = tangent.rotate(rotation, normal).normalize();
|
||||||
"rotate3d",
|
|
||||||
NodeItem::Type::Vector3,
|
|
||||||
{{"in", tangent}, {"amount", rotation * val(360.0f)}, {"axis", normal}});
|
|
||||||
|
|
||||||
NodeItem n_tangent_rotate_normalize = create_node(
|
|
||||||
"normalize", NodeItem::Type::Vector3, {{"in", n_tangent_rotate}});
|
|
||||||
|
|
||||||
n_main_tangent = anisotropy.if_else(
|
n_main_tangent = anisotropy.if_else(
|
||||||
NodeItem::CompareOp::Greater, val(0.0f), n_tangent_rotate_normalize, tangent);
|
NodeItem::CompareOp::Greater, val(0.0f), n_tangent_rotate_normalize, tangent);
|
||||||
}
|
}
|
||||||
@ -375,14 +368,8 @@ NODE_SHADER_MATERIALX_BEGIN
|
|||||||
{"normal", coat_normal}});
|
{"normal", coat_normal}});
|
||||||
|
|
||||||
if (tangent && coat_normal) {
|
if (tangent && coat_normal) {
|
||||||
NodeItem n_coat_tangent_rotate = create_node(
|
NodeItem n_coat_tangent_rotate_normalize =
|
||||||
"rotate3d",
|
tangent.rotate(rotation, coat_normal).normalize();
|
||||||
NodeItem::Type::Vector3,
|
|
||||||
{{"in", tangent}, {"amount", rotation * val(360.0f)}, {"axis", coat_normal}});
|
|
||||||
|
|
||||||
NodeItem n_coat_tangent_rotate_normalize = create_node(
|
|
||||||
"normalize", NodeItem::Type::Vector3, {{"in", n_coat_tangent_rotate}});
|
|
||||||
|
|
||||||
NodeItem n_coat_tangent = anisotropy.if_else(
|
NodeItem n_coat_tangent = anisotropy.if_else(
|
||||||
NodeItem::CompareOp::Greater, val(0.0f), n_coat_tangent_rotate_normalize, tangent);
|
NodeItem::CompareOp::Greater, val(0.0f), n_coat_tangent_rotate_normalize, tangent);
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ 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
|
NODE_SHADER_MATERIALX_BEGIN
|
||||||
#ifdef WITH_MATERIALX
|
#ifdef WITH_MATERIALX
|
||||||
{
|
{
|
||||||
|
@ -79,34 +79,30 @@ NODE_SHADER_MATERIALX_BEGIN
|
|||||||
{
|
{
|
||||||
NodeItem res = empty();
|
NodeItem res = empty();
|
||||||
NodeItem vector = get_input_link("Vector", NodeItem::Type::Vector3);
|
NodeItem vector = get_input_link("Vector", NodeItem::Type::Vector3);
|
||||||
|
|
||||||
if (!vector) {
|
if (!vector) {
|
||||||
return res;
|
return empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeItem scale = get_input_value("Scale", NodeItem::Type::Vector3);
|
NodeItem scale = get_input_value("Scale", NodeItem::Type::Vector3);
|
||||||
NodeItem location = get_input_value("Location", NodeItem::Type::Vector3);
|
NodeItem location = get_input_value("Location", NodeItem::Type::Vector3);
|
||||||
NodeItem rotation = (get_input_value("Rotation", NodeItem::Type::Vector3) *
|
NodeItem rotation = get_input_value("Rotation", NodeItem::Type::Vector3);
|
||||||
val(float(180.0f / M_PI)));
|
|
||||||
|
|
||||||
switch (node_->custom1) {
|
switch (node_->custom1) {
|
||||||
case NODE_MAPPING_TYPE_POINT:
|
case NODE_MAPPING_TYPE_POINT:
|
||||||
res = (vector * scale).rotate3d(rotation) + location;
|
return (vector * scale).rotate(rotation) + location;
|
||||||
break;
|
break;
|
||||||
case NODE_MAPPING_TYPE_TEXTURE:
|
case NODE_MAPPING_TYPE_TEXTURE:
|
||||||
res = (vector - location).rotate3d(rotation, true) / scale;
|
res = (vector - location).rotate(rotation, true) / scale;
|
||||||
break;
|
break;
|
||||||
case NODE_MAPPING_TYPE_VECTOR:
|
case NODE_MAPPING_TYPE_VECTOR:
|
||||||
res = (vector * scale).rotate3d(rotation * val(MaterialX::Vector3(1.0f, 1.0f, -1.0f)));
|
res = (vector * scale).rotate(rotation * val(MaterialX::Vector3(1.0f, 1.0f, -1.0f)));
|
||||||
break;
|
break;
|
||||||
case NODE_MAPPING_TYPE_NORMAL:
|
case NODE_MAPPING_TYPE_NORMAL:
|
||||||
res = create_node(
|
res = (vector / scale).rotate(rotation).normalize();
|
||||||
"normalize", NodeItem::Type::Vector3, {{"in", (vector / scale).rotate3d(rotation)}});
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
BLI_assert_unreachable();
|
BLI_assert_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -237,12 +237,11 @@ NODE_SHADER_MATERIALX_BEGIN
|
|||||||
angle = get_input_value("Angle", NodeItem::Type::Float);
|
angle = get_input_value("Angle", NodeItem::Type::Float);
|
||||||
}
|
}
|
||||||
|
|
||||||
angle = angle * val(float(180.0f / M_PI));
|
|
||||||
angle = invert ? angle * val(-1.0f) : angle;
|
angle = invert ? angle * val(-1.0f) : angle;
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case NODE_VECTOR_ROTATE_TYPE_EULER_XYZ: {
|
case NODE_VECTOR_ROTATE_TYPE_EULER_XYZ: {
|
||||||
return res.rotate3d(angle, invert) + center;
|
return res.rotate(angle, invert) + center;
|
||||||
}
|
}
|
||||||
case NODE_VECTOR_ROTATE_TYPE_AXIS: {
|
case NODE_VECTOR_ROTATE_TYPE_AXIS: {
|
||||||
axis = get_input_value("Axis", NodeItem::Type::Vector3) *
|
axis = get_input_value("Axis", NodeItem::Type::Vector3) *
|
||||||
|
Loading…
Reference in New Issue
Block a user