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/kernel | |
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/kernel')
-rw-r--r-- | intern/cycles/kernel/CMakeLists.txt | 1 | ||||
-rw-r--r-- | intern/cycles/kernel/shaders/node_ramp_util.h | 89 | ||||
-rw-r--r-- | intern/cycles/kernel/shaders/node_rgb_curves.osl | 48 | ||||
-rw-r--r-- | intern/cycles/kernel/shaders/node_rgb_ramp.osl | 21 | ||||
-rw-r--r-- | intern/cycles/kernel/shaders/node_vector_curves.osl | 48 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm.h | 4 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_ramp.h | 33 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_ramp_util.h | 97 |
8 files changed, 210 insertions, 131 deletions
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index 685574eb394..0d663bb474f 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -140,6 +140,7 @@ set(SRC_SVM_HEADERS svm/svm_noisetex.h svm/svm_normal.h svm/svm_ramp.h + svm/svm_ramp_util.h svm/svm_sepcomb_hsv.h svm/svm_sepcomb_vector.h svm/svm_sky.h diff --git a/intern/cycles/kernel/shaders/node_ramp_util.h b/intern/cycles/kernel/shaders/node_ramp_util.h new file mode 100644 index 00000000000..917fb65c6df --- /dev/null +++ b/intern/cycles/kernel/shaders/node_ramp_util.h @@ -0,0 +1,89 @@ +/* + * Copyright 2011-2013 Blender Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* NOTE: svm_ramp.h, svm_ramp_util.h and node_ramp_util.h must stay consistent */ + +color rgb_ramp_lookup(color ramp[], float at, int interpolate, int extrapolate) +{ + float f = at; + int table_size = arraylength(ramp); + + if ((f < 0.0 || f > 1.0) && extrapolate) { + color t0, dy; + if (f < 0.0) { + t0 = ramp[0]; + dy = t0 - ramp[1]; + f = -f; + } + else { + t0 = ramp[table_size - 1]; + dy = t0 - ramp[table_size - 2]; + f = f - 1.0; + } + return t0 + dy * f * (table_size - 1); + } + + f = clamp(at, 0.0, 1.0) * (table_size - 1); + + /* clamp int as well in case of NaN */ + int i = (int)f; + if (i < 0) i = 0; + if (i >= table_size) i = table_size - 1; + float t = f - (float)i; + + color result = ramp[i]; + + if (interpolate && t > 0.0) + result = (1.0 - t) * result + t * ramp[i + 1]; + + return result; +} + +float rgb_ramp_lookup(float ramp[], float at, int interpolate, int extrapolate) +{ + float f = at; + int table_size = arraylength(ramp); + + if ((f < 0.0 || f > 1.0) && extrapolate) { + float t0, dy; + if (f < 0.0) { + t0 = ramp[0]; + dy = t0 - ramp[1]; + f = -f; + } + else { + t0 = ramp[table_size - 1]; + dy = t0 - ramp[table_size - 2]; + f = f - 1.0; + } + return t0 + dy * f * (table_size - 1); + } + + f = clamp(at, 0.0, 1.0) * (table_size - 1); + + /* clamp int as well in case of NaN */ + int i = (int)f; + if (i < 0) i = 0; + if (i >= table_size) i = table_size - 1; + float t = f - (float)i; + + float result = ramp[i]; + + if (interpolate && t > 0.0) + result = (1.0 - t) * result + t * ramp[i + 1]; + + return result; +} diff --git a/intern/cycles/kernel/shaders/node_rgb_curves.osl b/intern/cycles/kernel/shaders/node_rgb_curves.osl index 8e208e8a8f7..c8e7e4f175b 100644 --- a/intern/cycles/kernel/shaders/node_rgb_curves.osl +++ b/intern/cycles/kernel/shaders/node_rgb_curves.osl @@ -14,43 +14,7 @@ * limitations under the License. */ -#include "stdosl.h" -#include "oslutil.h" - -float ramp_lookup(color ramp[], float at, int component) -{ - int table_size = arraylength(ramp); - - if (at < 0.0 || at > 1.0) { - float t0, dy; - if (at < 0.0) { - t0 = ramp[0][component]; - dy = t0 - ramp[1][component]; - at = -at; - } - else { - t0 = ramp[table_size - 1][component]; - dy = t0 - ramp[table_size - 2][component]; - at = at - 1.0; - } - return t0 + dy * at * (table_size - 1); - } - - float f = clamp(at, 0.0, 1.0) * (table_size - 1); - - /* clamp int as well in case of NaN */ - int i = (int)f; - if (i < 0) i = 0; - if (i >= table_size) i = table_size - 1; - float t = f - (float)i; - - float result = ramp[i][component]; - - if (t > 0.0) - result = (1.0 - t) * result + t * ramp[i + 1][component]; - - return result; -} +#include "node_ramp_util.h" shader node_rgb_curves( color ramp[] = {0.0}, @@ -63,9 +27,13 @@ shader node_rgb_curves( { color c = (ColorIn - color(min_x, min_x, min_x)) / (max_x - min_x); - ColorOut[0] = ramp_lookup(ramp, c[0], 0); - ColorOut[1] = ramp_lookup(ramp, c[1], 1); - ColorOut[2] = ramp_lookup(ramp, c[2], 2); + color r = rgb_ramp_lookup(ramp, c[0], 1, 1); + color g = rgb_ramp_lookup(ramp, c[0], 1, 1); + color b = rgb_ramp_lookup(ramp, c[0], 1, 1); + + ColorOut[0] = r[0]; + ColorOut[1] = g[1]; + ColorOut[2] = b[2]; ColorOut = mix(ColorIn, ColorOut, Fac); } diff --git a/intern/cycles/kernel/shaders/node_rgb_ramp.osl b/intern/cycles/kernel/shaders/node_rgb_ramp.osl index c0ae74d6b33..24b8728b999 100644 --- a/intern/cycles/kernel/shaders/node_rgb_ramp.osl +++ b/intern/cycles/kernel/shaders/node_rgb_ramp.osl @@ -14,8 +14,7 @@ * limitations under the License. */ -#include "stdosl.h" -#include "oslutil.h" +#include "node_ramp_util.h" shader node_rgb_ramp( color ramp_color[] = {0.0}, @@ -26,21 +25,7 @@ shader node_rgb_ramp( output color Color = 0.0, output float Alpha = 1.0) { - int table_size = arraylength(ramp_color); - float f = clamp(Fac, 0.0, 1.0) * (table_size - 1); - - /* clamp int as well in case of NaN */ - int i = (int)f; - if (i < 0) i = 0; - if (i >= table_size) i = table_size - 1; - float t = f - (float)i; - - Color = ramp_color[i]; - Alpha = ramp_alpha[i]; - - if (interpolate && t > 0.0) { - Color = (1.0 - t) * Color + t * ramp_color[i + 1]; - Alpha = (1.0 - t) * Alpha + t * ramp_alpha[i + 1]; - } + Color = rgb_ramp_lookup(ramp_color, Fac, interpolate, 0); + Alpha = rgb_ramp_lookup(ramp_alpha, Fac, interpolate, 0); } diff --git a/intern/cycles/kernel/shaders/node_vector_curves.osl b/intern/cycles/kernel/shaders/node_vector_curves.osl index cff4efe1d98..d92fa11d439 100644 --- a/intern/cycles/kernel/shaders/node_vector_curves.osl +++ b/intern/cycles/kernel/shaders/node_vector_curves.osl @@ -14,43 +14,7 @@ * limitations under the License. */ -#include "stdosl.h" -#include "oslutil.h" - -float ramp_lookup(color ramp[], float at, int component) -{ - int table_size = arraylength(ramp); - - if (at < 0.0 || at > 1.0) { - float t0, dy; - if (at < 0.0) { - t0 = ramp[0][component]; - dy = t0 - ramp[1][component]; - at = -at; - } - else { - t0 = ramp[table_size - 1][component]; - dy = t0 - ramp[table_size - 2][component]; - at = at - 1.0; - } - return t0 + dy * at * (table_size - 1); - } - - float f = clamp(at, 0.0, 1.0) * (table_size - 1); - - /* clamp int as well in case of NaN */ - int i = (int)f; - if (i < 0) i = 0; - if (i >= table_size) i = table_size - 1; - float t = f - (float)i; - - float result = ramp[i][component]; - - if (t > 0.0) - result = (1.0 - t) * result + t * ramp[i + 1][component]; - - return result; -} +#include "node_ramp_util.h" shader node_vector_curves( color ramp[] = {0.0}, @@ -63,9 +27,13 @@ shader node_vector_curves( { vector c = (VectorIn - vector(min_x, min_x, min_x)) / (max_x - min_x); - VectorOut[0] = ramp_lookup(ramp, c[0], 0); - VectorOut[1] = ramp_lookup(ramp, c[1], 1); - VectorOut[2] = ramp_lookup(ramp, c[2], 2); + color r = rgb_ramp_lookup(ramp, c[0], 1, 1); + color g = rgb_ramp_lookup(ramp, c[0], 1, 1); + color b = rgb_ramp_lookup(ramp, c[0], 1, 1); + + VectorOut[0] = r[0]; + VectorOut[1] = g[1]; + VectorOut[2] = b[2]; VectorOut = mix(VectorIn, VectorOut, Fac); } diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h index de7e03e5a19..502994e71f1 100644 --- a/intern/cycles/kernel/svm/svm.h +++ b/intern/cycles/kernel/svm/svm.h @@ -405,10 +405,8 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ccl_a #if NODES_GROUP(NODE_GROUP_LEVEL_3) case NODE_RGB_CURVES: - svm_node_rgb_curves(kg, sd, stack, node, &offset); - break; case NODE_VECTOR_CURVES: - svm_node_vector_curves(kg, sd, stack, node, &offset); + svm_node_curves(kg, sd, stack, node, &offset); break; case NODE_TANGENT: svm_node_tangent(kg, sd, stack, node); diff --git a/intern/cycles/kernel/svm/svm_ramp.h b/intern/cycles/kernel/svm/svm_ramp.h index 24275d05c4a..f959d90f309 100644 --- a/intern/cycles/kernel/svm/svm_ramp.h +++ b/intern/cycles/kernel/svm/svm_ramp.h @@ -19,6 +19,8 @@ CCL_NAMESPACE_BEGIN +/* NOTE: svm_ramp.h, svm_ramp_util.h and node_ramp_util.h must stay consistent */ + ccl_device float4 rgb_ramp_lookup(KernelGlobals *kg, int offset, float f, @@ -75,36 +77,7 @@ ccl_device void svm_node_rgb_ramp(KernelGlobals *kg, ShaderData *sd, float *stac *offset += table_size; } -ccl_device void svm_node_rgb_curves(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) -{ - uint fac_offset, color_offset, out_offset; - decode_node_uchar4(node.y, - &fac_offset, - &color_offset, - &out_offset, - NULL); - - uint table_size = read_node(kg, offset).x; - - float fac = stack_load_float(stack, fac_offset); - float3 color = stack_load_float3(stack, color_offset); - - const float min_x = __int_as_float(node.z), - max_x = __int_as_float(node.w); - const float range_x = max_x - min_x; - const float3 relpos = (color - make_float3(min_x, min_x, min_x)) / range_x; - - float r = rgb_ramp_lookup(kg, *offset, relpos.x, true, true, table_size).x; - float g = rgb_ramp_lookup(kg, *offset, relpos.y, true, true, table_size).y; - float b = rgb_ramp_lookup(kg, *offset, relpos.z, true, true, table_size).z; - - color = (1.0f - fac)*color + fac*make_float3(r, g, b); - stack_store_float3(stack, out_offset, color); - - *offset += table_size; -} - -ccl_device void svm_node_vector_curves(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) +ccl_device void svm_node_curves(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) { uint fac_offset, color_offset, out_offset; decode_node_uchar4(node.y, diff --git a/intern/cycles/kernel/svm/svm_ramp_util.h b/intern/cycles/kernel/svm/svm_ramp_util.h new file mode 100644 index 00000000000..495d98cf250 --- /dev/null +++ b/intern/cycles/kernel/svm/svm_ramp_util.h @@ -0,0 +1,97 @@ +/* + * Copyright 2011-2013 Blender Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __SVM_RAMP_UTIL_H__ +#define __SVM_RAMP_UTIL_H__ + +CCL_NAMESPACE_BEGIN + +/* NOTE: svm_ramp.h, svm_ramp_util.h and node_ramp_util.h must stay consistent */ + +ccl_device float3 rgb_ramp_lookup(const float3 *ramp, + float f, + bool interpolate, + bool extrapolate, + int table_size) +{ + if ((f < 0.0f || f > 1.0f) && extrapolate) { + float3 t0, dy; + if (f < 0.0f) { + t0 = ramp[0]; + dy = t0 - ramp[1], + f = -f; + } + else { + t0 = ramp[table_size - 1]; + dy = t0 - ramp[table_size - 2]; + f = f - 1.0f; + } + return t0 + dy * f * (table_size - 1); + } + + f = clamp(f, 0.0f, 1.0f) * (table_size - 1); + + /* clamp int as well in case of NaN */ + int i = clamp(float_to_int(f), 0, table_size-1); + float t = f - (float)i; + + float3 result = ramp[i]; + + if (interpolate && t > 0.0f) + result = (1.0f - t) * result + t * ramp[i + 1]; + + return result; +} + +ccl_device float float_ramp_lookup(const float *ramp, + float f, + bool interpolate, + bool extrapolate, + int table_size) +{ + if ((f < 0.0f || f > 1.0f) && extrapolate) { + float t0, dy; + if (f < 0.0f) { + t0 = ramp[0]; + dy = t0 - ramp[1], + f = -f; + } + else { + t0 = ramp[table_size - 1]; + dy = t0 - ramp[table_size - 2]; + f = f - 1.0f; + } + return t0 + dy * f * (table_size - 1); + } + + f = clamp(f, 0.0f, 1.0f) * (table_size - 1); + + /* clamp int as well in case of NaN */ + int i = clamp(float_to_int(f), 0, table_size-1); + float t = f - (float)i; + + float result = ramp[i]; + + if (interpolate && t > 0.0f) + result = (1.0f - t) * result + t * ramp[i + 1]; + + return result; +} + +CCL_NAMESPACE_END + +#endif /* __SVM_RAMP_UTIL_H__ */ + |