diff options
Diffstat (limited to 'intern/cycles/render')
-rw-r--r-- | intern/cycles/render/nodes.cpp | 79 | ||||
-rw-r--r-- | intern/cycles/render/nodes.h | 12 |
2 files changed, 90 insertions, 1 deletions
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 90f70cf19ec..1629895ff6e 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -6382,7 +6382,7 @@ void BumpNode::constant_fold(const ConstantFolder &folder) /* TODO(sergey): Ignore bump with zero strength. */ } -/* Curve node */ +/* Curves node */ CurvesNode::CurvesNode(const NodeType *node_type) : ShaderNode(node_type) { @@ -6531,6 +6531,83 @@ void VectorCurvesNode::compile(OSLCompiler &compiler) CurvesNode::compile(compiler, "node_vector_curves"); } +/* FloatCurveNode */ + +NODE_DEFINE(FloatCurveNode) +{ + NodeType *type = NodeType::add("float_curve", create, NodeType::SHADER); + + SOCKET_FLOAT_ARRAY(curve, "Curve", array<float>()); + SOCKET_FLOAT(min_x, "Min X", 0.0f); + SOCKET_FLOAT(max_x, "Max X", 1.0f); + + SOCKET_IN_FLOAT(fac, "Factor", 0.0f); + SOCKET_IN_FLOAT(value, "Value", 0.0f); + + SOCKET_OUT_FLOAT(value, "Value"); + + return type; +} + +FloatCurveNode::FloatCurveNode() : ShaderNode(get_node_type()) +{ +} + +void FloatCurveNode::constant_fold(const ConstantFolder &folder) +{ + ShaderInput *value_in = input("Value"); + ShaderInput *fac_in = input("Factor"); + + /* evaluate fully constant node */ + if (folder.all_inputs_constant()) { + if (curve.size() == 0) { + return; + } + + float pos = (value - min_x) / (max_x - min_x); + float result = float_ramp_lookup(curve.data(), pos, true, true, curve.size()); + + folder.make_constant(value + fac * (result - value)); + } + /* remove no-op node */ + else if (!fac_in->link && fac == 0.0f) { + /* link is not null because otherwise all inputs are constant */ + folder.bypass(value_in->link); + } +} + +void FloatCurveNode::compile(SVMCompiler &compiler) +{ + if (curve.size() == 0) + return; + + ShaderInput *value_in = input("Value"); + ShaderInput *fac_in = input("Factor"); + ShaderOutput *value_out = output("Value"); + + compiler.add_node(NODE_FLOAT_CURVE, + compiler.encode_uchar4(compiler.stack_assign(fac_in), + compiler.stack_assign(value_in), + compiler.stack_assign(value_out)), + __float_as_int(min_x), + __float_as_int(max_x)); + + compiler.add_node(curve.size()); + for (int i = 0; i < curve.size(); i++) + compiler.add_node(make_float4(curve[i])); +} + +void FloatCurveNode::compile(OSLCompiler &compiler) +{ + if (curve.size() == 0) + return; + + compiler.parameter_array("ramp", curve.data(), curve.size()); + compiler.parameter(this, "min_x"); + compiler.parameter(this, "max_x"); + compiler.add(this, "node_float_curve"); +} + /* RGBRampNode */ NODE_DEFINE(RGBRampNode) diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 22bdb06b059..5ac72835ac5 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -1398,6 +1398,18 @@ class VectorCurvesNode : public CurvesNode { void constant_fold(const ConstantFolder &folder); }; +class FloatCurveNode : public ShaderNode { + public: + SHADER_NODE_CLASS(FloatCurveNode) + void constant_fold(const ConstantFolder &folder); + + NODE_SOCKET_API_ARRAY(array<float>, curve) + NODE_SOCKET_API(float, min_x) + NODE_SOCKET_API(float, max_x) + NODE_SOCKET_API(float, fac) + NODE_SOCKET_API(float, value) +}; + class RGBRampNode : public ShaderNode { public: SHADER_NODE_CLASS(RGBRampNode) |