Cycles: constant folding for RGB/Vector Curves and Color Ramp.
[blender.git] / intern / cycles / kernel / shaders / node_texture.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 /* Voronoi / Worley like */
18
19 color cellnoise_color(point p)
20 {
21         float r = cellnoise(p);
22         float g = cellnoise(point(p[1], p[0], p[2]));
23         float b = cellnoise(point(p[1], p[2], p[0]));
24
25         return color(r, g, b);
26 }
27
28 void voronoi(point p, float e, float da[4], point pa[4])
29 {
30         /* returns distances in da and point coords in pa */
31         int xx, yy, zz, xi, yi, zi;
32
33         xi = (int)floor(p[0]);
34         yi = (int)floor(p[1]);
35         zi = (int)floor(p[2]);
36
37         da[0] = 1e10;
38         da[1] = 1e10;
39         da[2] = 1e10;
40         da[3] = 1e10;
41
42         for (xx = xi - 1; xx <= xi + 1; xx++) {
43                 for (yy = yi - 1; yy <= yi + 1; yy++) {
44                         for (zz = zi - 1; zz <= zi + 1; zz++) {
45                                 point ip = point(xx, yy, zz);
46                                 point vp = (point)cellnoise_color(ip);
47                                 point pd = p - (vp + ip);
48                                 float d = dot(pd, pd);
49
50                                 vp += point(xx, yy, zz);
51
52                                 if (d < da[0]) {
53                                         da[3] = da[2];
54                                         da[2] = da[1];
55                                         da[1] = da[0];
56                                         da[0] = d;
57
58                                         pa[3] = pa[2];
59                                         pa[2] = pa[1];
60                                         pa[1] = pa[0];
61                                         pa[0] = vp;
62                                 }
63                                 else if (d < da[1]) {
64                                         da[3] = da[2];
65                                         da[2] = da[1];
66                                         da[1] = d;
67
68                                         pa[3] = pa[2];
69                                         pa[2] = pa[1];
70                                         pa[1] = vp;
71                                 }
72                                 else if (d < da[2]) {
73                                         da[3] = da[2];
74                                         da[2] = d;
75
76                                         pa[3] = pa[2];
77                                         pa[2] = vp;
78                                 }
79                                 else if (d < da[3]) {
80                                         da[3] = d;
81                                         pa[3] = vp;
82                                 }
83                         }
84                 }
85         }
86 }
87
88 /* Noise Bases */
89
90 float safe_noise(point p, string type)
91 {
92         float f = 0.0;
93         
94         /* Perlin noise in range -1..1 */
95         if (type == "signed")
96                 f = noise("perlin", p);
97         
98         /* Perlin noise in range 0..1 */
99         else
100                 f = noise(p);
101
102         /* can happen for big coordinates, things even out to 0.5 then anyway */
103         if (!isfinite(f))
104                 return 0.5;
105         
106         return f;
107 }
108
109 /* Turbulence */
110
111 float noise_turbulence(point p, float details, int hard)
112 {
113         float fscale = 1.0;
114         float amp = 1.0;
115         float sum = 0.0;
116         int i, n;
117         
118         float octaves = clamp(details, 0.0, 16.0);
119         n = (int)octaves;
120
121         for (i = 0; i <= n; i++) {
122                 float t = safe_noise(fscale * p, "unsigned");
123
124                 if (hard)
125                         t = fabs(2.0 * t - 1.0);
126
127                 sum += t * amp;
128                 amp *= 0.5;
129                 fscale *= 2.0;
130         }
131         
132         float rmd = octaves - floor(octaves);
133
134         if (rmd != 0.0) {
135                 float t = safe_noise(fscale * p, "unsigned");
136
137                 if (hard)
138                         t = fabs(2.0 * t - 1.0);
139
140                 float sum2 = sum + t * amp;
141
142                 sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1));
143                 sum2 *= ((float)(1 << (n + 1)) / (float)((1 << (n + 2)) - 1));
144
145                 return (1.0 - rmd) * sum + rmd * sum2;
146         }
147         else {
148                 sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1));
149                 return sum;
150         }
151 }
152
153 /* Utility */
154
155 float nonzero(float f, float eps)
156 {
157         float r;
158
159         if (abs(f) < eps)
160                 r = sign(f) * eps;
161         else
162                 r = f;
163         
164         return r;
165 }
166