ClangFormat: apply to source, most of intern
[blender.git] / intern / cycles / kernel / svm / svm_musgrave.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 /* Musgrave fBm
20  *
21  * H: fractal increment parameter
22  * lacunarity: gap between successive frequencies
23  * octaves: number of frequencies in the fBm
24  *
25  * from "Texturing and Modelling: A procedural approach"
26  */
27
28 ccl_device_noinline float noise_musgrave_fBm(float3 p, float H, float lacunarity, float octaves)
29 {
30   float rmd;
31   float value = 0.0f;
32   float pwr = 1.0f;
33   float pwHL = powf(lacunarity, -H);
34   int i;
35
36   for (i = 0; i < float_to_int(octaves); i++) {
37     value += snoise(p) * pwr;
38     pwr *= pwHL;
39     p *= lacunarity;
40   }
41
42   rmd = octaves - floorf(octaves);
43   if (rmd != 0.0f)
44     value += rmd * snoise(p) * pwr;
45
46   return value;
47 }
48
49 /* Musgrave Multifractal
50  *
51  * H: highest fractal dimension
52  * lacunarity: gap between successive frequencies
53  * octaves: number of frequencies in the fBm
54  */
55
56 ccl_device_noinline float noise_musgrave_multi_fractal(float3 p,
57                                                        float H,
58                                                        float lacunarity,
59                                                        float octaves)
60 {
61   float rmd;
62   float value = 1.0f;
63   float pwr = 1.0f;
64   float pwHL = powf(lacunarity, -H);
65   int i;
66
67   for (i = 0; i < float_to_int(octaves); i++) {
68     value *= (pwr * snoise(p) + 1.0f);
69     pwr *= pwHL;
70     p *= lacunarity;
71   }
72
73   rmd = octaves - floorf(octaves);
74   if (rmd != 0.0f)
75     value *= (rmd * pwr * snoise(p) + 1.0f); /* correct? */
76
77   return value;
78 }
79
80 /* Musgrave Heterogeneous Terrain
81  *
82  * H: fractal dimension of the roughest area
83  * lacunarity: gap between successive frequencies
84  * octaves: number of frequencies in the fBm
85  * offset: raises the terrain from `sea level'
86  */
87
88 ccl_device_noinline float noise_musgrave_hetero_terrain(
89     float3 p, float H, float lacunarity, float octaves, float offset)
90 {
91   float value, increment, rmd;
92   float pwHL = powf(lacunarity, -H);
93   float pwr = pwHL;
94   int i;
95
96   /* first unscaled octave of function; later octaves are scaled */
97   value = offset + snoise(p);
98   p *= lacunarity;
99
100   for (i = 1; i < float_to_int(octaves); i++) {
101     increment = (snoise(p) + offset) * pwr * value;
102     value += increment;
103     pwr *= pwHL;
104     p *= lacunarity;
105   }
106
107   rmd = octaves - floorf(octaves);
108   if (rmd != 0.0f) {
109     increment = (snoise(p) + offset) * pwr * value;
110     value += rmd * increment;
111   }
112
113   return value;
114 }
115
116 /* Hybrid Additive/Multiplicative Multifractal Terrain
117  *
118  * H: fractal dimension of the roughest area
119  * lacunarity: gap between successive frequencies
120  * octaves: number of frequencies in the fBm
121  * offset: raises the terrain from `sea level'
122  */
123
124 ccl_device_noinline float noise_musgrave_hybrid_multi_fractal(
125     float3 p, float H, float lacunarity, float octaves, float offset, float gain)
126 {
127   float result, signal, weight, rmd;
128   float pwHL = powf(lacunarity, -H);
129   float pwr = pwHL;
130   int i;
131
132   result = snoise(p) + offset;
133   weight = gain * result;
134   p *= lacunarity;
135
136   for (i = 1; (weight > 0.001f) && (i < float_to_int(octaves)); i++) {
137     if (weight > 1.0f)
138       weight = 1.0f;
139
140     signal = (snoise(p) + offset) * pwr;
141     pwr *= pwHL;
142     result += weight * signal;
143     weight *= gain * signal;
144     p *= lacunarity;
145   }
146
147   rmd = octaves - floorf(octaves);
148   if (rmd != 0.0f)
149     result += rmd * ((snoise(p) + offset) * pwr);
150
151   return result;
152 }
153
154 /* Ridged Multifractal Terrain
155  *
156  * H: fractal dimension of the roughest area
157  * lacunarity: gap between successive frequencies
158  * octaves: number of frequencies in the fBm
159  * offset: raises the terrain from `sea level'
160  */
161
162 ccl_device_noinline float noise_musgrave_ridged_multi_fractal(
163     float3 p, float H, float lacunarity, float octaves, float offset, float gain)
164 {
165   float result, signal, weight;
166   float pwHL = powf(lacunarity, -H);
167   float pwr = pwHL;
168   int i;
169
170   signal = offset - fabsf(snoise(p));
171   signal *= signal;
172   result = signal;
173   weight = 1.0f;
174
175   for (i = 1; i < float_to_int(octaves); i++) {
176     p *= lacunarity;
177     weight = saturate(signal * gain);
178     signal = offset - fabsf(snoise(p));
179     signal *= signal;
180     signal *= weight;
181     result += signal * pwr;
182     pwr *= pwHL;
183   }
184
185   return result;
186 }
187
188 /* Shader */
189
190 ccl_device float svm_musgrave(NodeMusgraveType type,
191                               float dimension,
192                               float lacunarity,
193                               float octaves,
194                               float offset,
195                               float intensity,
196                               float gain,
197                               float3 p)
198 {
199   if (type == NODE_MUSGRAVE_MULTIFRACTAL)
200     return intensity * noise_musgrave_multi_fractal(p, dimension, lacunarity, octaves);
201   else if (type == NODE_MUSGRAVE_FBM)
202     return intensity * noise_musgrave_fBm(p, dimension, lacunarity, octaves);
203   else if (type == NODE_MUSGRAVE_HYBRID_MULTIFRACTAL)
204     return intensity *
205            noise_musgrave_hybrid_multi_fractal(p, dimension, lacunarity, octaves, offset, gain);
206   else if (type == NODE_MUSGRAVE_RIDGED_MULTIFRACTAL)
207     return intensity *
208            noise_musgrave_ridged_multi_fractal(p, dimension, lacunarity, octaves, offset, gain);
209   else if (type == NODE_MUSGRAVE_HETERO_TERRAIN)
210     return intensity * noise_musgrave_hetero_terrain(p, dimension, lacunarity, octaves, offset);
211
212   return 0.0f;
213 }
214
215 ccl_device void svm_node_tex_musgrave(
216     KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
217 {
218   uint4 node2 = read_node(kg, offset);
219   uint4 node3 = read_node(kg, offset);
220
221   uint type, co_offset, color_offset, fac_offset;
222   uint dimension_offset, lacunarity_offset, detail_offset, offset_offset;
223   uint gain_offset, scale_offset;
224
225   decode_node_uchar4(node.y, &type, &co_offset, &color_offset, &fac_offset);
226   decode_node_uchar4(
227       node.z, &dimension_offset, &lacunarity_offset, &detail_offset, &offset_offset);
228   decode_node_uchar4(node.w, &gain_offset, &scale_offset, NULL, NULL);
229
230   float3 co = stack_load_float3(stack, co_offset);
231   float dimension = stack_load_float_default(stack, dimension_offset, node2.x);
232   float lacunarity = stack_load_float_default(stack, lacunarity_offset, node2.y);
233   float detail = stack_load_float_default(stack, detail_offset, node2.z);
234   float foffset = stack_load_float_default(stack, offset_offset, node2.w);
235   float gain = stack_load_float_default(stack, gain_offset, node3.x);
236   float scale = stack_load_float_default(stack, scale_offset, node3.y);
237
238   dimension = fmaxf(dimension, 1e-5f);
239   detail = clamp(detail, 0.0f, 16.0f);
240   lacunarity = fmaxf(lacunarity, 1e-5f);
241
242   float f = svm_musgrave(
243       (NodeMusgraveType)type, dimension, lacunarity, detail, foffset, 1.0f, gain, co * scale);
244
245   if (stack_valid(fac_offset))
246     stack_store_float(stack, fac_offset, f);
247   if (stack_valid(color_offset))
248     stack_store_float3(stack, color_offset, make_float3(f, f, f));
249 }
250
251 CCL_NAMESPACE_END