diff options
author | Alexander Gavrilov <angavrilov@gmail.com> | 2016-07-31 00:30:36 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2016-07-31 03:18:23 +0300 |
commit | ea2ebf7a00f9adef9c14aaa24b79532b44043eba (patch) | |
tree | 3d683f671a4051cd8421739592e8cb70fdac88ea /intern/cycles/render | |
parent | f4bcc97729c430aac16c41f7c012a0f4c1fe6bb2 (diff) |
Cycles: constant folding for RGB/Vector Curves and Color Ramp.
These are complex nodes, and it's conceivable they may end up constant
in some circumstances within node groups, so folding support is useful.
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D2084
Diffstat (limited to 'intern/cycles/render')
-rw-r--r-- | intern/cycles/render/constant_fold.h | 1 | ||||
-rw-r--r-- | intern/cycles/render/nodes.cpp | 60 | ||||
-rw-r--r-- | intern/cycles/render/nodes.h | 12 |
3 files changed, 69 insertions, 4 deletions
diff --git a/intern/cycles/render/constant_fold.h b/intern/cycles/render/constant_fold.h index 978c8e5335a..195e5b127e8 100644 --- a/intern/cycles/render/constant_fold.h +++ b/intern/cycles/render/constant_fold.h @@ -18,6 +18,7 @@ #define __CONSTANT_FOLD_H__ #include "util_types.h" +#include "util_vector.h" CCL_NAMESPACE_BEGIN diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 3af6a713290..b3b010841e9 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -20,6 +20,7 @@ #include "scene.h" #include "svm.h" #include "svm_color_util.h" +#include "svm_ramp_util.h" #include "svm_math_util.h" #include "osl.h" #include "constant_fold.h" @@ -4855,6 +4856,30 @@ CurvesNode::CurvesNode(const NodeType *node_type) { } +void CurvesNode::constant_fold(const ConstantFolder& folder, ShaderInput *value_in) +{ + ShaderInput *fac_in = input("Fac"); + + /* remove no-op node */ + if(!fac_in->link && fac == 0.0f) { + folder.bypass(value_in->link); + } + /* evaluate fully constant node */ + else if(folder.all_inputs_constant()) { + if (curves.size() == 0) + return; + + float3 pos = (value - make_float3(min_x, min_x, min_x)) / (max_x - min_x); + float3 result; + + result[0] = rgb_ramp_lookup(curves.data(), pos[0], true, true, curves.size()).x; + result[1] = rgb_ramp_lookup(curves.data(), pos[1], true, true, curves.size()).y; + result[2] = rgb_ramp_lookup(curves.data(), pos[2], true, true, curves.size()).z; + + folder.make_constant(interp(value, result, fac)); + } +} + void CurvesNode::compile(SVMCompiler& compiler, int type, ShaderInput *value_in, ShaderOutput *value_out) { if(curves.size() == 0) @@ -4918,6 +4943,11 @@ RGBCurvesNode::RGBCurvesNode() { } +void RGBCurvesNode::constant_fold(const ConstantFolder& folder) +{ + CurvesNode::constant_fold(folder, input("Color")); +} + void RGBCurvesNode::compile(SVMCompiler& compiler) { CurvesNode::compile(compiler, NODE_RGB_CURVES, input("Color"), output("Color")); @@ -4951,6 +4981,11 @@ VectorCurvesNode::VectorCurvesNode() { } +void VectorCurvesNode::constant_fold(const ConstantFolder& folder) +{ + CurvesNode::constant_fold(folder, input("Vector")); +} + void VectorCurvesNode::compile(SVMCompiler& compiler) { CurvesNode::compile(compiler, NODE_VECTOR_CURVES, input("Vector"), output("Vector")); @@ -4984,6 +5019,31 @@ RGBRampNode::RGBRampNode() { } +void RGBRampNode::constant_fold(const ConstantFolder& folder) +{ + if(ramp.size() == 0 || ramp.size() != ramp_alpha.size()) + return; + + if(folder.all_inputs_constant()) { + float f = clamp(fac, 0.0f, 1.0f) * (ramp.size() - 1); + + /* clamp int as well in case of NaN */ + int i = clamp((int)f, 0, ramp.size()-1); + float t = f - (float)i; + + bool use_lerp = interpolate && t > 0.0f; + + if(folder.output == output("Color")) { + float3 color = rgb_ramp_lookup(ramp.data(), fac, use_lerp, false, ramp.size()); + folder.make_constant(color); + } + else if(folder.output == output("Alpha")) { + float alpha = float_ramp_lookup(ramp_alpha.data(), fac, use_lerp, false, ramp_alpha.size()); + folder.make_constant(alpha); + } + } +} + void RGBRampNode::compile(SVMCompiler& compiler) { if(ramp.size() == 0 || ramp.size() != ramp_alpha.size()) diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 28b40ba756d..b0eb2395adf 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -889,28 +889,32 @@ public: virtual int get_group() { return NODE_GROUP_LEVEL_3; } - bool has_spatial_varying() { return true; } - void compile(SVMCompiler& compiler, int type, ShaderInput *value_in, ShaderOutput *value_out); - void compile(OSLCompiler& compiler, const char *name); - array<float3> curves; float min_x, max_x, fac; float3 value; + +protected: + void constant_fold(const ConstantFolder& folder, ShaderInput *value_in); + void compile(SVMCompiler& compiler, int type, ShaderInput *value_in, ShaderOutput *value_out); + void compile(OSLCompiler& compiler, const char *name); }; class RGBCurvesNode : public CurvesNode { public: SHADER_NODE_CLASS(RGBCurvesNode) + void constant_fold(const ConstantFolder& folder); }; class VectorCurvesNode : public CurvesNode { public: SHADER_NODE_CLASS(VectorCurvesNode) + void constant_fold(const ConstantFolder& folder); }; class RGBRampNode : public ShaderNode { public: SHADER_NODE_CLASS(RGBRampNode) + void constant_fold(const ConstantFolder& folder); virtual int get_group() { return NODE_GROUP_LEVEL_1; } array<float3> ramp; |