Cycles: constant folding for RGB/Vector Curves and Color Ramp.
[blender.git] / intern / cycles / kernel / svm / svm_ramp_util.h
1 /*
2  * Copyright 2011-2013 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #ifndef __SVM_RAMP_UTIL_H__
18 #define __SVM_RAMP_UTIL_H__
19
20 CCL_NAMESPACE_BEGIN
21
22 /* NOTE: svm_ramp.h, svm_ramp_util.h and node_ramp_util.h must stay consistent */
23
24 ccl_device float3 rgb_ramp_lookup(const float3 *ramp,
25                                   float f,
26                                   bool interpolate,
27                                   bool extrapolate,
28                                   int table_size)
29 {
30         if ((f < 0.0f || f > 1.0f) && extrapolate) {
31                 float3 t0, dy;
32                 if (f < 0.0f) {
33                         t0 = ramp[0];
34                         dy = t0 - ramp[1],
35                         f = -f;
36                 }
37                 else {
38                         t0 = ramp[table_size - 1];
39                         dy = t0 - ramp[table_size - 2];
40                         f = f - 1.0f;
41                 }
42                 return t0 + dy * f * (table_size - 1);
43         }
44
45         f = clamp(f, 0.0f, 1.0f) * (table_size - 1);
46
47         /* clamp int as well in case of NaN */
48         int i = clamp(float_to_int(f), 0, table_size-1);
49         float t = f - (float)i;
50
51         float3 result = ramp[i];
52
53         if (interpolate && t > 0.0f)
54                 result = (1.0f - t) * result + t * ramp[i + 1];
55
56         return result;
57 }
58
59 ccl_device float float_ramp_lookup(const float *ramp,
60                                    float f,
61                                    bool interpolate,
62                                    bool extrapolate,
63                                    int table_size)
64 {
65         if ((f < 0.0f || f > 1.0f) && extrapolate) {
66                 float t0, dy;
67                 if (f < 0.0f) {
68                         t0 = ramp[0];
69                         dy = t0 - ramp[1],
70                         f = -f;
71                 }
72                 else {
73                         t0 = ramp[table_size - 1];
74                         dy = t0 - ramp[table_size - 2];
75                         f = f - 1.0f;
76                 }
77                 return t0 + dy * f * (table_size - 1);
78         }
79
80         f = clamp(f, 0.0f, 1.0f) * (table_size - 1);
81
82         /* clamp int as well in case of NaN */
83         int i = clamp(float_to_int(f), 0, table_size-1);
84         float t = f - (float)i;
85
86         float result = ramp[i];
87
88         if (interpolate && t > 0.0f)
89                 result = (1.0f - t) * result + t * ramp[i + 1];
90
91         return result;
92 }
93
94 CCL_NAMESPACE_END
95
96 #endif /* __SVM_RAMP_UTIL_H__ */
97