Line data Source code
1 : // Utility function used in both noises as an ease curve
2 : function easeCurve(t)
3 : {
4 0 : return t*t*t*(t*(t*6-15)+10);
5 : }
6 :
7 : // Find mod of number but only positive values
8 : function modPos(num, m)
9 : {
10 0 : var p = num % m;
11 0 : if (p < 0)
12 0 : p += m;
13 :
14 0 : return p;
15 : }
16 :
17 : /////////////////////////////////////////////////////////////////////
18 : // Noise2D
19 : //
20 : // Class representing 2D noise with a given base frequency
21 : //
22 : /////////////////////////////////////////////////////////////////////
23 :
24 : function Noise2D(freq)
25 : {
26 0 : freq = Math.floor(freq);
27 0 : this.freq = freq;
28 0 : this.grads = [];
29 :
30 0 : for (var i=0; i < freq; ++i)
31 : {
32 0 : this.grads[i] = [];
33 0 : for (var j=0; j < freq; ++j)
34 : {
35 0 : var a = randomAngle();
36 0 : this.grads[i][j] = new Vector2D(Math.cos(a), Math.sin(a));
37 : }
38 : }
39 : }
40 :
41 6 : Noise2D.prototype.get = function(x, y)
42 : {
43 0 : x *= this.freq;
44 0 : y *= this.freq;
45 :
46 0 : var ix = modPos(Math.floor(x), this.freq);
47 0 : var iy = modPos(Math.floor(y), this.freq);
48 :
49 0 : var fx = x - ix;
50 0 : var fy = y - iy;
51 :
52 0 : var ix1 = (ix+1) % this.freq;
53 0 : var iy1 = (iy+1) % this.freq;
54 :
55 0 : var s = this.grads[ix][iy].dot(new Vector2D(fx, fy));
56 0 : var t = this.grads[ix1][iy].dot(new Vector2D(fx-1, fy));
57 0 : var u = this.grads[ix][iy1].dot(new Vector2D(fx, fy-1));
58 0 : var v = this.grads[ix1][iy1].dot(new Vector2D(fx-1, fy-1));
59 :
60 0 : var ex = easeCurve(fx);
61 0 : var ey = easeCurve(fy);
62 0 : var a = s + ex*(t-s);
63 0 : var b = u + ex*(v-u);
64 0 : return (a + ey*(b-a)) * 0.5 + 0.5;
65 : };
66 :
67 : /////////////////////////////////////////////////////////////////////
68 : // Noise3D
69 : //
70 : // Class representing 3D noise with given base frequencies
71 : //
72 : /////////////////////////////////////////////////////////////////////
73 :
74 : function Noise3D(freq, vfreq)
75 : {
76 0 : freq = Math.floor(freq);
77 0 : vfreq = Math.floor(vfreq);
78 0 : this.freq = freq;
79 0 : this.vfreq = vfreq;
80 0 : this.grads = [];
81 :
82 0 : for (var i=0; i < freq; ++i)
83 : {
84 0 : this.grads[i] = [];
85 0 : for (var j=0; j < freq; ++j)
86 : {
87 0 : this.grads[i][j] = [];
88 0 : for(var k=0; k < vfreq; ++k)
89 : {
90 0 : var v = new Vector3D();
91 0 : do
92 : {
93 0 : v.set(randFloat(-1, 1), randFloat(-1, 1), randFloat(-1, 1));
94 : }
95 : while(v.lengthSquared() > 1 || v.lengthSquared() < 0.1);
96 :
97 0 : v.normalize();
98 :
99 0 : this.grads[i][j][k] = v;
100 : }
101 : }
102 : }
103 : }
104 :
105 6 : Noise3D.prototype.get = function(x, y, z)
106 : {
107 0 : x *= this.freq;
108 0 : y *= this.freq;
109 0 : z *= this.vfreq;
110 :
111 0 : var ix =modPos(Math.floor(x), this.freq);
112 0 : var iy = modPos(Math.floor(y), this.freq);
113 0 : var iz = modPos(Math.floor(z), this.vfreq);
114 :
115 0 : var fx = x - ix;
116 0 : var fy = y - iy;
117 0 : var fz = z - iz;
118 :
119 0 : var ix1 = (ix+1) % this.freq;
120 0 : var iy1 = (iy+1) % this.freq;
121 0 : var iz1 = (iz+1) % this.vfreq;
122 :
123 0 : var s0 = this.grads[ix][iy][iz].dot(new Vector3D(fx, fy, fz));
124 0 : var t0 = this.grads[ix1][iy][iz].dot(new Vector3D(fx-1, fy, fz));
125 0 : var u0 = this.grads[ix][iy1][iz].dot(new Vector3D(fx, fy-1, fz));
126 0 : var v0 = this.grads[ix1][iy1][iz].dot(new Vector3D(fx-1, fy-1, fz));
127 :
128 0 : var s1 = this.grads[ix][iy][iz1].dot(new Vector3D(fx, fy, fz-1));
129 0 : var t1 = this.grads[ix1][iy][iz1].dot(new Vector3D(fx-1, fy, fz-1));
130 0 : var u1 = this.grads[ix][iy1][iz1].dot(new Vector3D(fx, fy-1, fz-1));
131 0 : var v1 = this.grads[ix1][iy1][iz1].dot(new Vector3D(fx-1, fy-1, fz-1));
132 :
133 0 : var ex = easeCurve(fx);
134 0 : var ey = easeCurve(fy);
135 0 : var ez = easeCurve(fz);
136 :
137 0 : var a0 = s0 + ex*(t0-s0);
138 0 : var b0 = u0 + ex*(v0-u0);
139 0 : var c0 = a0 + ey*(b0-a0);
140 :
141 0 : var a1 = s1 + ex*(t1-s1);
142 0 : var b1 = u1 + ex*(v1-u1);
143 0 : var c1 = a1 + ey*(b1-a1);
144 :
145 0 : return (c0 + ez*(c1-c0)) * 0.5 + 0.5;
146 : };
|