2
* This program is free software; you can redistribute it and/or
3
* modify it under the terms of the GNU General Public License
4
* as published by the Free Software Foundation; either version 2
5
* of the License, or (at your option) any later version.
7
* This program is distributed in the hope that it will be useful,
8
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
* GNU General Public License for more details.
12
* You should have received a copy of the GNU General Public License
13
* along with this program; if not, write to the Free Software Foundation,
14
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
/* Voronoi Distances */
19
float voronoi_distance(string distance_metric, vector d, float e)
23
if (distance_metric == "Distance Squared")
25
if (distance_metric == "Actual Distance")
27
if (distance_metric == "Manhattan")
28
result = fabs(d[0]) + fabs(d[1]) + fabs(d[2]);
29
if (distance_metric == "Chebychev")
30
result = max(fabs(d[0]), max(fabs(d[1]), fabs(d[2])));
31
if (distance_metric == "Minkovsky 1/2")
32
result = sqrt(fabs(d[0])) + sqrt(fabs(d[1])) + sqrt(fabs(d[1]));
33
if (distance_metric == "Minkovsky 4")
34
result = sqrt(sqrt(dot(d * d, d * d)));
35
if (distance_metric == "Minkovsky")
36
result = pow(pow(fabs(d[0]), e) + pow(fabs(d[1]), e) + pow(fabs(d[2]), e), 1.0 / e);
41
/* Voronoi / Worley like */
43
color cellnoise_color(point p)
45
float r = cellnoise(p);
46
float g = cellnoise(point(p[1], p[0], p[2]));
47
float b = cellnoise(point(p[1], p[2], p[0]));
49
return color(r, g, b);
52
void voronoi(point p, string distance_metric, float e, float da[4], point pa[4])
54
/* returns distances in da and point coords in pa */
55
int xx, yy, zz, xi, yi, zi;
57
xi = (int)floor(p[0]);
58
yi = (int)floor(p[1]);
59
zi = (int)floor(p[2]);
66
for (xx = xi - 1; xx <= xi + 1; xx++) {
67
for (yy = yi - 1; yy <= yi + 1; yy++) {
68
for (zz = zi - 1; zz <= zi + 1; zz++) {
69
point ip = point(xx, yy, zz);
70
point vp = (point)cellnoise_color(ip);
71
point pd = p - (vp + ip);
72
float d = voronoi_distance(distance_metric, pd, e);
74
vp += point(xx, yy, zz);
103
else if (d < da[3]) {
112
float voronoi_Fn(point p, int n)
117
voronoi(p, "Distance Squared", 0, da, pa);
122
float voronoi_FnFn(point p, int n1, int n2)
127
voronoi(p, "Distance Squared", 0, da, pa);
129
return da[n2] - da[n1];
132
float voronoi_F1(point p) { return voronoi_Fn(p, 0); }
133
float voronoi_F2(point p) { return voronoi_Fn(p, 1); }
134
float voronoi_F3(point p) { return voronoi_Fn(p, 2); }
135
float voronoi_F4(point p) { return voronoi_Fn(p, 3); }
136
float voronoi_F1F2(point p) { return voronoi_FnFn(p, 0, 1); }
138
float voronoi_Cr(point p)
140
/* crackle type pattern, just a scale/clamp of F2-F1 */
141
float t = 10.0 * voronoi_F1F2(p);
142
return (t > 1.0) ? 1.0 : t;
145
float voronoi_F1S(point p) { return 2.0 * voronoi_F1(p) - 1.0; }
146
float voronoi_F2S(point p) { return 2.0 * voronoi_F2(p) - 1.0; }
147
float voronoi_F3S(point p) { return 2.0 * voronoi_F3(p) - 1.0; }
148
float voronoi_F4S(point p) { return 2.0 * voronoi_F4(p) - 1.0; }
149
float voronoi_F1F2S(point p) { return 2.0 * voronoi_F1F2(p) - 1.0; }
150
float voronoi_CrS(point p) { return 2.0 * voronoi_Cr(p) - 1.0; }
154
float safe_noise(point p, int type)
158
/* Perlin noise in range -1..1 */
160
f = noise("perlin", p);
162
/* Perlin noise in range 0..1 */
166
/* can happen for big coordinates, things even out to 0.5 then anyway */
173
float noise_basis(point p, string basis)
177
if (basis == "Perlin")
178
result = safe_noise(p, 1);
179
if (basis == "Voronoi F1")
180
result = voronoi_F1S(p);
181
if (basis == "Voronoi F2")
182
result = voronoi_F2S(p);
183
if (basis == "Voronoi F3")
184
result = voronoi_F3S(p);
185
if (basis == "Voronoi F4")
186
result = voronoi_F4S(p);
187
if (basis == "Voronoi F2-F1")
188
result = voronoi_F1F2S(p);
189
if (basis == "Voronoi Crackle")
190
result = voronoi_CrS(p);
191
if (basis == "Cell Noise")
192
result = cellnoise(p);
197
/* Soft/Hard Noise */
199
float noise_basis_hard(point p, string basis, int hard)
201
float t = noise_basis(p, basis);
202
return (hard) ? fabs(2.0 * t - 1.0) : t;
207
float noise_wave(string wave, float a)
211
if (wave == "Sine") {
212
result = 0.5 + 0.5 * sin(a);
214
else if (wave == "Saw") {
216
int n = (int)(a / b);
222
else if (wave == "Tri") {
226
result = rmax - 2.0 * fabs(floor((a * (1.0 / b)) + 0.5) - (a * (1.0 / b)));
234
float noise_turbulence(point p, string basis, float details, int hard)
241
float octaves = clamp(details, 0.0, 16.0);
244
for (i = 0; i <= n; i++) {
245
float t = noise_basis(fscale * p, basis);
248
t = fabs(2.0 * t - 1.0);
255
float rmd = octaves - floor(octaves);
258
float t = noise_basis(fscale * p, basis);
261
t = fabs(2.0 * t - 1.0);
263
float sum2 = sum + t*amp;
265
sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1));
266
sum2 *= ((float)(1 << (n + 1)) / (float)((1 << (n + 2)) - 1));
268
return (1.0 - rmd)*sum + rmd*sum2;
271
sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1));
278
float nonzero(float f, float eps)