[Bf-blender-cvs] [40eedd5] master: Cycles: implement partial constant folding for exponentiation.
Alexander Gavrilov
noreply at git.blender.org
Sat Oct 1 13:47:32 CEST 2016
Commit: 40eedd5df9083ce54c38c6307946488a1fa8aae0
Author: Alexander Gavrilov
Date: Thu Sep 29 00:35:53 2016 +0300
Branches: master
https://developer.blender.org/rB40eedd5df9083ce54c38c6307946488a1fa8aae0
Cycles: implement partial constant folding for exponentiation.
This is also an important mathematical operation that can be folded
if it is known that one argument is a certain constant. For colors
the operation is provided as a Gamma node.
The SVM Gamma node needs a small fix to make it follow the 0 ^ 0 == 1
rule, same as the Power node, or the Gamma node itself in OSL mode.
Reviewers: #cycles
Differential Revision: https://developer.blender.org/D2263
===================================================================
M intern/cycles/kernel/svm/svm_math_util.h
M intern/cycles/render/constant_fold.cpp
M intern/cycles/render/constant_fold.h
M intern/cycles/render/nodes.cpp
M intern/cycles/test/render_graph_finalize_test.cpp
===================================================================
diff --git a/intern/cycles/kernel/svm/svm_math_util.h b/intern/cycles/kernel/svm/svm_math_util.h
index 6d13a0d..01547b6 100644
--- a/intern/cycles/kernel/svm/svm_math_util.h
+++ b/intern/cycles/kernel/svm/svm_math_util.h
@@ -164,6 +164,9 @@ ccl_device float3 svm_math_blackbody_color(float t) {
ccl_device_inline float3 svm_math_gamma_color(float3 color, float gamma)
{
+ if(gamma == 0.0f)
+ return make_float3(1.0f, 1.0f, 1.0f);
+
if(color.x > 0.0f)
color.x = powf(color.x, gamma);
if(color.y > 0.0f)
diff --git a/intern/cycles/render/constant_fold.cpp b/intern/cycles/render/constant_fold.cpp
index 200a4c4..b7f2566 100644
--- a/intern/cycles/render/constant_fold.cpp
+++ b/intern/cycles/render/constant_fold.cpp
@@ -89,6 +89,19 @@ void ConstantFolder::make_zero() const
}
}
+void ConstantFolder::make_one() const
+{
+ if(output->type() == SocketType::FLOAT) {
+ make_constant(1.0f);
+ }
+ else if(SocketType::is_float3(output->type())) {
+ make_constant(make_float3(1.0f, 1.0f, 1.0f));
+ }
+ else {
+ assert(0);
+ }
+}
+
void ConstantFolder::bypass(ShaderOutput *new_output) const
{
assert(new_output);
@@ -321,6 +334,15 @@ void ConstantFolder::fold_math(NodeMath type, bool clamp) const
make_zero();
}
break;
+ case NODE_MATH_POWER:
+ /* 1 ^ X == X ^ 0 == 1 */
+ if(is_one(value1_in) || is_zero(value2_in)) {
+ make_one();
+ }
+ /* X ^ 1 == X */
+ else if(is_one(value2_in)) {
+ try_bypass_or_make_constant(value1_in, clamp);
+ }
default:
break;
}
diff --git a/intern/cycles/render/constant_fold.h b/intern/cycles/render/constant_fold.h
index 2b31c2a..7962698 100644
--- a/intern/cycles/render/constant_fold.h
+++ b/intern/cycles/render/constant_fold.h
@@ -43,6 +43,7 @@ public:
void make_constant_clamp(float value, bool clamp) const;
void make_constant_clamp(float3 value, bool clamp) const;
void make_zero() const;
+ void make_one() const;
/* Bypass node, relinking to another output socket. */
void bypass(ShaderOutput *output) const;
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index df43863..7ea52b2 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -3896,6 +3896,19 @@ void GammaNode::constant_fold(const ConstantFolder& folder)
if(folder.all_inputs_constant()) {
folder.make_constant(svm_math_gamma_color(color, gamma));
}
+ else {
+ ShaderInput *color_in = input("Color");
+ ShaderInput *gamma_in = input("Gamma");
+
+ /* 1 ^ X == X ^ 0 == 1 */
+ if(folder.is_one(color_in) || folder.is_zero(gamma_in)) {
+ folder.make_one();
+ }
+ /* X ^ 1 == X */
+ else if(folder.is_one(gamma_in)) {
+ folder.try_bypass_or_make_constant(color_in, false);
+ }
+ }
}
void GammaNode::compile(SVMCompiler& compiler)
diff --git a/intern/cycles/test/render_graph_finalize_test.cpp b/intern/cycles/test/render_graph_finalize_test.cpp
index 60e41be..6f1c0b8 100644
--- a/intern/cycles/test/render_graph_finalize_test.cpp
+++ b/intern/cycles/test/render_graph_finalize_test.cpp
@@ -931,6 +931,72 @@ TEST(render_graph, constant_fold_gamma)
}
/*
+ * Tests: Gamma with one constant 0 input.
+ */
+TEST(render_graph, constant_fold_gamma_part_0)
+{
+ DEFINE_COMMON_VARIABLES(builder, log);
+
+ EXPECT_ANY_MESSAGE(log);
+ INVALID_INFO_MESSAGE(log, "Folding Gamma_Cx::");
+ CORRECT_INFO_MESSAGE(log, "Folding Gamma_xC::Color to constant (1, 1, 1).");
+
+ builder
+ .add_attribute("Attribute")
+ /* constant on the left */
+ .add_node(ShaderNodeBuilder<GammaNode>("Gamma_Cx")
+ .set("Color", make_float3(0.0f, 0.0f, 0.0f)))
+ .add_connection("Attribute::Fac", "Gamma_Cx::Gamma")
+ /* constant on the right */
+ .add_node(ShaderNodeBuilder<GammaNode>("Gamma_xC")
+ .set("Gamma", 0.0f))
+ .add_connection("Attribute::Color", "Gamma_xC::Color")
+ /* output sum */
+ .add_node(ShaderNodeBuilder<MixNode>("Out")
+ .set(&MixNode::type, NODE_MIX_ADD)
+ .set(&MixNode::use_clamp, true)
+ .set("Fac", 1.0f))
+ .add_connection("Gamma_Cx::Color", "Out::Color1")
+ .add_connection("Gamma_xC::Color", "Out::Color2")
+ .output_color("Out::Color");
+
+ graph.finalize(&scene);
+}
+
+/*
+ * Tests: Gamma with one constant 1 input.
+ */
+TEST(render_graph, constant_fold_gamma_part_1)
+{
+ DEFINE_COMMON_VARIABLES(builder, log);
+
+ EXPECT_ANY_MESSAGE(log);
+ CORRECT_INFO_MESSAGE(log, "Folding Gamma_Cx::Color to constant (1, 1, 1).");
+ CORRECT_INFO_MESSAGE(log, "Folding Gamma_xC::Color to socket Attribute::Color.");
+
+ builder
+ .add_attribute("Attribute")
+ /* constant on the left */
+ .add_node(ShaderNodeBuilder<GammaNode>("Gamma_Cx")
+ .set("Color", make_float3(1.0f, 1.0f, 1.0f)))
+ .add_connection("Attribute::Fac", "Gamma_Cx::Gamma")
+ /* constant on the right */
+ .add_node(ShaderNodeBuilder<GammaNode>("Gamma_xC")
+ .set("Gamma", 1.0f))
+ .add_connection("Attribute::Color", "Gamma_xC::Color")
+ /* output sum */
+ .add_node(ShaderNodeBuilder<MixNode>("Out")
+ .set(&MixNode::type, NODE_MIX_ADD)
+ .set(&MixNode::use_clamp, true)
+ .set("Fac", 1.0f))
+ .add_connection("Gamma_Cx::Color", "Out::Color1")
+ .add_connection("Gamma_xC::Color", "Out::Color2")
+ .output_color("Out::Color");
+
+ graph.finalize(&scene);
+}
+
+/*
* Tests: BrightnessContrast with all constant inputs.
*/
TEST(render_graph, constant_fold_bright_contrast)
@@ -1143,6 +1209,40 @@ TEST(render_graph, constant_fold_part_math_div_0)
}
/*
+ * Tests: partial folding for Math Power with known 0.
+ */
+TEST(render_graph, constant_fold_part_math_pow_0)
+{
+ DEFINE_COMMON_VARIABLES(builder, log);
+
+ EXPECT_ANY_MESSAGE(log);
+ /* X ^ 0 == 1 */
+ INVALID_INFO_MESSAGE(log, "Folding Math_Cx::");
+ CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Value to constant (1).");
+ INVALID_INFO_MESSAGE(log, "Folding Out::");
+
+ build_math_partial_test_graph(builder, NODE_MATH_POWER, 0.0f);
+ graph.finalize(&scene);
+}
+
+/*
+ * Tests: partial folding for Math Power with known 1.
+ */
+TEST(render_graph, constant_fold_part_math_pow_1)
+{
+ DEFINE_COMMON_VARIABLES(builder, log);
+
+ EXPECT_ANY_MESSAGE(log);
+ /* 1 ^ X == 1; X ^ 1 == X */
+ CORRECT_INFO_MESSAGE(log, "Folding Math_Cx::Value to constant (1)");
+ CORRECT_INFO_MESSAGE(log, "Folding Math_xC::Value to socket Attribute::Fac.");
+ INVALID_INFO_MESSAGE(log, "Folding Out::");
+
+ build_math_partial_test_graph(builder, NODE_MATH_POWER, 1.0f);
+ graph.finalize(&scene);
+}
+
+/*
* Tests: Vector Math with all constant inputs.
*/
TEST(render_graph, constant_fold_vector_math)
More information about the Bf-blender-cvs
mailing list