Cycles: Code cleanup, spaces around keywords
[blender-staging.git] / intern / cycles / kernel / svm / svm_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 CCL_NAMESPACE_BEGIN
18
19 /* Voronoi Distances */
20
21 #if 0
22 ccl_device float voronoi_distance(NodeDistanceMetric distance_metric, float3 d, float e)
23 {
24 #if 0
25         if(distance_metric == NODE_VORONOI_DISTANCE_SQUARED)
26 #endif
27                 return dot(d, d);
28 #if 0
29         if(distance_metric == NODE_VORONOI_ACTUAL_DISTANCE)
30                 return len(d);
31         if(distance_metric == NODE_VORONOI_MANHATTAN)
32                 return fabsf(d.x) + fabsf(d.y) + fabsf(d.z);
33         if(distance_metric == NODE_VORONOI_CHEBYCHEV)
34                 return fmaxf(fabsf(d.x), fmaxf(fabsf(d.y), fabsf(d.z)));
35         if(distance_metric == NODE_VORONOI_MINKOVSKY_H)
36                 return sqrtf(fabsf(d.x)) + sqrtf(fabsf(d.y)) + sqrtf(fabsf(d.y));
37         if(distance_metric == NODE_VORONOI_MINKOVSKY_4)
38                 return sqrtf(sqrtf(dot(d*d, d*d)));
39         if(distance_metric == NODE_VORONOI_MINKOVSKY)
40                 return powf(powf(fabsf(d.x), e) + powf(fabsf(d.y), e) + powf(fabsf(d.z), e), 1.0f/e);
41         
42         return 0.0f;
43 #endif
44 }
45
46 /* Voronoi / Worley like */
47 ccl_device_inline float4 voronoi_Fn(float3 p, float e, int n1, int n2)
48 {
49         float da[4];
50         float3 pa[4];
51         NodeDistanceMetric distance_metric = NODE_VORONOI_DISTANCE_SQUARED;
52
53         /* returns distances in da and point coords in pa */
54         int xx, yy, zz, xi, yi, zi;
55
56         xi = floor_to_int(p.x);
57         yi = floor_to_int(p.y);
58         zi = floor_to_int(p.z);
59
60         da[0] = 1e10f;
61         da[1] = 1e10f;
62         da[2] = 1e10f;
63         da[3] = 1e10f;
64
65         pa[0] = make_float3(0.0f, 0.0f, 0.0f);
66         pa[1] = make_float3(0.0f, 0.0f, 0.0f);
67         pa[2] = make_float3(0.0f, 0.0f, 0.0f);
68         pa[3] = make_float3(0.0f, 0.0f, 0.0f);
69
70         for(xx = xi-1; xx <= xi+1; xx++) {
71                 for(yy = yi-1; yy <= yi+1; yy++) {
72                         for(zz = zi-1; zz <= zi+1; zz++) {
73                                 float3 ip = make_float3((float)xx, (float)yy, (float)zz);
74                                 float3 vp = cellnoise_color(ip);
75                                 float3 pd = p - (vp + ip);
76                                 float d = voronoi_distance(distance_metric, pd, e);
77
78                                 vp += ip;
79
80                                 if(d < da[0]) {
81                                         da[3] = da[2];
82                                         da[2] = da[1];
83                                         da[1] = da[0];
84                                         da[0] = d;
85
86                                         pa[3] = pa[2];
87                                         pa[2] = pa[1];
88                                         pa[1] = pa[0];
89                                         pa[0] = vp;
90                                 }
91                                 else if(d < da[1]) {
92                                         da[3] = da[2];
93                                         da[2] = da[1];
94                                         da[1] = d;
95
96                                         pa[3] = pa[2];
97                                         pa[2] = pa[1];
98                                         pa[1] = vp;
99                                 }
100                                 else if(d < da[2]) {
101                                         da[3] = da[2];
102                                         da[2] = d;
103
104                                         pa[3] = pa[2];
105                                         pa[2] = vp;
106                                 }
107                                 else if(d < da[3]) {
108                                         da[3] = d;
109                                         pa[3] = vp;
110                                 }
111                         }
112                 }
113         }
114
115         float4 result = make_float4(pa[n1].x, pa[n1].y, pa[n1].z, da[n1]);
116
117         if(n2 != -1)
118                 result = make_float4(pa[n2].x, pa[n2].y, pa[n2].z, da[n2]) - result;
119
120         return result;
121 }
122 #endif
123
124 ccl_device float voronoi_F1_distance(float3 p)
125 {
126         /* returns squared distance in da */
127         float da = 1e10f;
128
129 #ifndef __KERNEL_SSE2__
130         int ix = floor_to_int(p.x), iy = floor_to_int(p.y), iz = floor_to_int(p.z);
131
132         for(int xx = -1; xx <= 1; xx++) {
133                 for(int yy = -1; yy <= 1; yy++) {
134                         for(int zz = -1; zz <= 1; zz++) {
135                                 float3 ip = make_float3(ix + xx, iy + yy, iz + zz);
136                                 float3 vp = ip + cellnoise_color(ip);
137                                 float d = len_squared(p - vp);
138                                 da = min(d, da);
139                         }
140                 }
141         }
142 #else
143         ssef vec_p = load4f(p);
144         ssei xyzi = quick_floor_sse(vec_p);
145
146         for(int xx = -1; xx <= 1; xx++) {
147                 for(int yy = -1; yy <= 1; yy++) {
148                         for(int zz = -1; zz <= 1; zz++) {
149                                 ssef ip = ssef(xyzi + ssei(xx, yy, zz, 0));
150                                 ssef vp = ip + cellnoise_color(ip);
151                                 float d = len_squared<1, 1, 1, 0>(vec_p - vp);
152                                 da = min(d, da);
153                         }
154                 }
155         }
156 #endif
157
158         return da;
159 }
160
161 ccl_device float3 voronoi_F1_color(float3 p)
162 {
163         /* returns color of the nearest point */
164         float da = 1e10f;
165
166 #ifndef __KERNEL_SSE2__
167         float3 pa;
168         int ix = floor_to_int(p.x), iy = floor_to_int(p.y), iz = floor_to_int(p.z);
169
170         for(int xx = -1; xx <= 1; xx++) {
171                 for(int yy = -1; yy <= 1; yy++) {
172                         for(int zz = -1; zz <= 1; zz++) {
173                                 float3 ip = make_float3(ix + xx, iy + yy, iz + zz);
174                                 float3 vp = ip + cellnoise_color(ip);
175                                 float d = len_squared(p - vp);
176
177                                 if(d < da) {
178                                         da = d;
179                                         pa = vp;
180                                 }
181                         }
182                 }
183         }
184
185         return cellnoise_color(pa);
186 #else
187         ssef pa, vec_p = load4f(p);
188         ssei xyzi = quick_floor_sse(vec_p);
189
190         for(int xx = -1; xx <= 1; xx++) {
191                 for(int yy = -1; yy <= 1; yy++) {
192                         for(int zz = -1; zz <= 1; zz++) {
193                                 ssef ip = ssef(xyzi + ssei(xx, yy, zz, 0));
194                                 ssef vp = ip + cellnoise_color(ip);
195                                 float d = len_squared<1, 1, 1, 0>(vec_p - vp);
196
197                                 if(d < da) {
198                                         da = d;
199                                         pa = vp;
200                                 }
201                         }
202                 }
203         }
204
205         ssef color = cellnoise_color(pa);
206         return (float3 &)color;
207 #endif
208 }
209
210 #if 0
211 ccl_device float voronoi_F1(float3 p) { return voronoi_Fn(p, 0.0f, 0, -1).w; }
212 ccl_device float voronoi_F2(float3 p) { return voronoi_Fn(p, 0.0f, 1, -1).w; }
213 ccl_device float voronoi_F3(float3 p) { return voronoi_Fn(p, 0.0f, 2, -1).w; }
214 ccl_device float voronoi_F4(float3 p) { return voronoi_Fn(p, 0.0f, 3, -1).w; }
215 ccl_device float voronoi_F1F2(float3 p) { return voronoi_Fn(p, 0.0f, 0, 1).w; }
216
217 ccl_device float voronoi_Cr(float3 p)
218 {
219         /* crackle type pattern, just a scale/clamp of F2-F1 */
220         float t = 10.0f*voronoi_F1F2(p);
221         return (t > 1.0f)? 1.0f: t;
222 }
223
224 ccl_device float voronoi_F1S(float3 p) { return 2.0f*voronoi_F1(p) - 1.0f; }
225 ccl_device float voronoi_F2S(float3 p) { return 2.0f*voronoi_F2(p) - 1.0f; }
226 ccl_device float voronoi_F3S(float3 p) { return 2.0f*voronoi_F3(p) - 1.0f; }
227 ccl_device float voronoi_F4S(float3 p) { return 2.0f*voronoi_F4(p) - 1.0f; }
228 ccl_device float voronoi_F1F2S(float3 p) { return 2.0f*voronoi_F1F2(p) - 1.0f; }
229 ccl_device float voronoi_CrS(float3 p) { return 2.0f*voronoi_Cr(p) - 1.0f; }
230 #endif
231
232 /* Noise Bases */
233
234 ccl_device float noise_basis(float3 p, NodeNoiseBasis basis)
235 {
236         /* Only Perlin enabled for now, others break CUDA compile by making kernel
237          * too big, with compile using > 4GB, due to everything being inlined. */
238
239 #if 0
240         if(basis == NODE_NOISE_PERLIN)
241 #endif
242                 return noise(p);
243 #if 0
244         if(basis == NODE_NOISE_VORONOI_F1)
245                 return voronoi_F1S(p);
246         if(basis == NODE_NOISE_VORONOI_F2)
247                 return voronoi_F2S(p);
248         if(basis == NODE_NOISE_VORONOI_F3)
249                 return voronoi_F3S(p);
250         if(basis == NODE_NOISE_VORONOI_F4)
251                 return voronoi_F4S(p);
252         if(basis == NODE_NOISE_VORONOI_F2_F1)
253                 return voronoi_F1F2S(p);
254         if(basis == NODE_NOISE_VORONOI_CRACKLE)
255                 return voronoi_CrS(p);
256         if(basis == NODE_NOISE_CELL_NOISE)
257                 return cellnoise(p);
258         
259         return 0.0f;
260 #endif
261 }
262
263 /* Soft/Hard Noise */
264
265 ccl_device float noise_basis_hard(float3 p, NodeNoiseBasis basis, int hard)
266 {
267         float t = noise_basis(p, basis);
268         return (hard)? fabsf(2.0f*t - 1.0f): t;
269 }
270
271 /* Turbulence */
272
273 ccl_device_noinline float noise_turbulence(float3 p, NodeNoiseBasis basis, float octaves, int hard)
274 {
275         float fscale = 1.0f;
276         float amp = 1.0f;
277         float sum = 0.0f;
278         int i, n;
279
280         octaves = clamp(octaves, 0.0f, 16.0f);
281         n = float_to_int(octaves);
282
283         for(i = 0; i <= n; i++) {
284                 float t = noise_basis(fscale*p, basis);
285
286                 if(hard)
287                         t = fabsf(2.0f*t - 1.0f);
288
289                 sum += t*amp;
290                 amp *= 0.5f;
291                 fscale *= 2.0f;
292         }
293
294         float rmd = octaves - floorf(octaves);
295
296         if(rmd != 0.0f) {
297                 float t = noise_basis(fscale*p, basis);
298
299                 if(hard)
300                         t = fabsf(2.0f*t - 1.0f);
301
302                 float sum2 = sum + t*amp;
303
304                 sum *= ((float)(1 << n)/(float)((1 << (n+1)) - 1));
305                 sum2 *= ((float)(1 << (n+1))/(float)((1 << (n+2)) - 1));
306
307                 return (1.0f - rmd)*sum + rmd*sum2;
308         }
309         else {
310                 sum *= ((float)(1 << n)/(float)((1 << (n+1)) - 1));
311                 return sum;
312         }
313 }
314
315 CCL_NAMESPACE_END
316