Cycles: change __device and similar qualifiers to ccl_device in kernel code.
[blender.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 ccl_device float voronoi_distance(NodeDistanceMetric distance_metric, float3 d, float e)
22 {
23 #if 0
24         if(distance_metric == NODE_VORONOI_DISTANCE_SQUARED)
25 #endif
26                 return dot(d, d);
27 #if 0
28         if(distance_metric == NODE_VORONOI_ACTUAL_DISTANCE)
29                 return len(d);
30         if(distance_metric == NODE_VORONOI_MANHATTAN)
31                 return fabsf(d.x) + fabsf(d.y) + fabsf(d.z);
32         if(distance_metric == NODE_VORONOI_CHEBYCHEV)
33                 return fmaxf(fabsf(d.x), fmaxf(fabsf(d.y), fabsf(d.z)));
34         if(distance_metric == NODE_VORONOI_MINKOVSKY_H)
35                 return sqrtf(fabsf(d.x)) + sqrtf(fabsf(d.y)) + sqrtf(fabsf(d.y));
36         if(distance_metric == NODE_VORONOI_MINKOVSKY_4)
37                 return sqrtf(sqrtf(dot(d*d, d*d)));
38         if(distance_metric == NODE_VORONOI_MINKOVSKY)
39                 return powf(powf(fabsf(d.x), e) + powf(fabsf(d.y), e) + powf(fabsf(d.z), e), 1.0f/e);
40         
41         return 0.0f;
42 #endif
43 }
44
45 /* Voronoi / Worley like */
46
47 ccl_device_noinline 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
123 ccl_device float voronoi_F1(float3 p) { return voronoi_Fn(p, 0.0f, 0, -1).w; }
124 ccl_device float voronoi_F2(float3 p) { return voronoi_Fn(p, 0.0f, 1, -1).w; }
125 ccl_device float voronoi_F3(float3 p) { return voronoi_Fn(p, 0.0f, 2, -1).w; }
126 ccl_device float voronoi_F4(float3 p) { return voronoi_Fn(p, 0.0f, 3, -1).w; }
127 ccl_device float voronoi_F1F2(float3 p) { return voronoi_Fn(p, 0.0f, 0, 1).w; }
128
129 ccl_device float voronoi_Cr(float3 p)
130 {
131         /* crackle type pattern, just a scale/clamp of F2-F1 */
132         float t = 10.0f*voronoi_F1F2(p);
133         return (t > 1.0f)? 1.0f: t;
134 }
135
136 ccl_device float voronoi_F1S(float3 p) { return 2.0f*voronoi_F1(p) - 1.0f; }
137 ccl_device float voronoi_F2S(float3 p) { return 2.0f*voronoi_F2(p) - 1.0f; }
138 ccl_device float voronoi_F3S(float3 p) { return 2.0f*voronoi_F3(p) - 1.0f; }
139 ccl_device float voronoi_F4S(float3 p) { return 2.0f*voronoi_F4(p) - 1.0f; }
140 ccl_device float voronoi_F1F2S(float3 p) { return 2.0f*voronoi_F1F2(p) - 1.0f; }
141 ccl_device float voronoi_CrS(float3 p) { return 2.0f*voronoi_Cr(p) - 1.0f; }
142
143 /* Noise Bases */
144
145 ccl_device float noise_basis(float3 p, NodeNoiseBasis basis)
146 {
147         /* Only Perlin enabled for now, others break CUDA compile by making kernel
148          * too big, with compile using > 4GB, due to everything being inlined. */
149
150 #if 0
151         if(basis == NODE_NOISE_PERLIN)
152 #endif
153                 return noise(p);
154 #if 0
155         if(basis == NODE_NOISE_VORONOI_F1)
156                 return voronoi_F1S(p);
157         if(basis == NODE_NOISE_VORONOI_F2)
158                 return voronoi_F2S(p);
159         if(basis == NODE_NOISE_VORONOI_F3)
160                 return voronoi_F3S(p);
161         if(basis == NODE_NOISE_VORONOI_F4)
162                 return voronoi_F4S(p);
163         if(basis == NODE_NOISE_VORONOI_F2_F1)
164                 return voronoi_F1F2S(p);
165         if(basis == NODE_NOISE_VORONOI_CRACKLE)
166                 return voronoi_CrS(p);
167         if(basis == NODE_NOISE_CELL_NOISE)
168                 return cellnoise(p);
169         
170         return 0.0f;
171 #endif
172 }
173
174 /* Soft/Hard Noise */
175
176 ccl_device float noise_basis_hard(float3 p, NodeNoiseBasis basis, int hard)
177 {
178         float t = noise_basis(p, basis);
179         return (hard)? fabsf(2.0f*t - 1.0f): t;
180 }
181
182 /* Turbulence */
183
184 ccl_device_noinline float noise_turbulence(float3 p, NodeNoiseBasis basis, float octaves, int hard)
185 {
186         float fscale = 1.0f;
187         float amp = 1.0f;
188         float sum = 0.0f;
189         int i, n;
190
191         octaves = clamp(octaves, 0.0f, 16.0f);
192         n = float_to_int(octaves);
193
194         for(i = 0; i <= n; i++) {
195                 float t = noise_basis(fscale*p, basis);
196
197                 if(hard)
198                         t = fabsf(2.0f*t - 1.0f);
199
200                 sum += t*amp;
201                 amp *= 0.5f;
202                 fscale *= 2.0f;
203         }
204
205         float rmd = octaves - floorf(octaves);
206
207         if(rmd != 0.0f) {
208                 float t = noise_basis(fscale*p, basis);
209
210                 if(hard)
211                         t = fabsf(2.0f*t - 1.0f);
212
213                 float sum2 = sum + t*amp;
214
215                 sum *= ((float)(1 << n)/(float)((1 << (n+1)) - 1));
216                 sum2 *= ((float)(1 << (n+1))/(float)((1 << (n+2)) - 1));
217
218                 return (1.0f - rmd)*sum + rmd*sum2;
219         }
220         else {
221                 sum *= ((float)(1 << n)/(float)((1 << (n+1)) - 1));
222                 return sum;
223         }
224 }
225
226 CCL_NAMESPACE_END
227