1 #ifndef PerlinNoise_HXX
2 #define PerlinNoise_HXX
3
4 /**
5 * As the PerlinNoise written in the exercises
6 * but from 2D to 3D
7 */
8 class PerlinNoise
9 {
10 private:
11 /**
12 * 'random' generator
13 */
14 float Noise3D (int x, int y, int z)
15 {
16 int n = x + y * 57 + z * 3366;
17 n = (n << 13) ^ n;
18 float r = ( 1.0 - ( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);
19 return r;
20 }
21
22 /**
23 * get interpolated noise around the given pixel in all three dimensions
24 * therefore: average the noise of all neighbour pixels
25 */
26 float SmoothNoise3D (int x, int y, int z)
27 {
28 float result = 0.0;
29
30 for (int i = -1; i <= 1; i++)
31 for (int j = -1; j <= 1; j++)
32 for (int k = -1; k <= 1; k++)
33 result += Noise3D(x-i,y-j,z-k);
34
35 float average = result / ( powf(3.0,3.0) );
36
37 return average;
38 }
39
40 /**
41 * cosine interpolation
42 */
43 float cosrp(float a, float b, float x)
44 {
45 float f = x * (float) M_PI;
46 f = (1 - cosf(f)) * .5f;
47 return lerp(a,b,f);
48 }
49
50 public:
51 PerlinNoise()
52 {};
53
54 ~PerlinNoise()
55 {};
56
57 /**
58 * interpolation around a given point 'a'
59 * nearly the same as for one of the exercise sheet, just one dimension added
60 */
61 float Interpolation( Vec3f a )
62 {
63 int int_x = (int) floorf(a.x());
64 int int_y = (int) floorf(a.y());
65 int int_z = (int) floorf(a.z());
66
67 float frac_x = a.x() - int_x;
68 float frac_y = a.y() - int_y;
69 float frac_z = a.z() - int_z;
70
71 float value[2];
72 for (int i = 0; i <= 1; i++)
73 {
74 float v1 = SmoothNoise3D(int_x + 0, int_y + 0, int_z + i);
75 float v2 = SmoothNoise3D(int_x + 1, int_y + 0, int_z + i);
76 float v3 = SmoothNoise3D(int_x + 0, int_y + 1, int_z + i);
77 float v4 = SmoothNoise3D(int_x + 1, int_y + 1, int_z + i);
78
79 float i1 = cosrp(v1, v2, frac_x);
80 float i2 = cosrp(v3, v4, frac_x);
81
82 value[i] = cosrp(i1, i2, frac_y);
83 }
84
85 return cosrp(value[0] , value[1] , frac_z);
86 }
87
88 /**
89 * main function
90 */
91 float PerlinNoise3D(Vec3f point, float persistence, float octaves)
92 {
93 float result = 0.0;
94 float amplitude = 1.0;
95 float frequency = 1.0;
96
97 for (int i = 0; i < octaves; i++)
98 {
99 result += Interpolation( frequency * point ) * amplitude;
100
101 frequency *= 2.0;
102 amplitude *= persistence;
103 }
104
105 return result;
106 }
107 };
108
109 #endif
syntax highlighted by Code2HTML, v. 0.9.1