Skip to content

Commit d394837

Browse files
committed
refactor 3D noise
1 parent 6889d49 commit d394837

File tree

1 file changed

+97
-98
lines changed

1 file changed

+97
-98
lines changed

src/open_simplex_noise_3d.rs

Lines changed: 97 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,6 @@ impl OpenSimplexNoise3D {
9494
in_sum: f64,
9595
contribute: impl Fn(f64, f64, f64) -> f64,
9696
) -> f64 {
97-
let mut value = 0.0;
98-
9997
// Determine which two of (0, 0, 1), (0, 1, 0), (1, 0, 0) are closest.
10098
let (score, point) = OpenSimplexNoise3D::determine_closest_point(
10199
Vec2::new(ins.x, ins.y),
@@ -106,97 +104,81 @@ impl OpenSimplexNoise3D {
106104

107105
// Now we determine the two lattice points not part of the tetrahedron that may contribute.
108106
// This depends on the closest two tetrahedral vertices, including (0, 0, 0)
109-
value += OpenSimplexNoise3D::determine_lattice_points_including_0_0_0(
107+
let value = OpenSimplexNoise3D::determine_lattice_points_including_0_0_0(
110108
in_sum,
111109
score,
112110
point,
113111
|x, y, z| contribute(x, y, z),
114112
);
115113

116-
value += contribute(0.0, 0.0, 0.0)
114+
value
115+
+ contribute(0.0, 0.0, 0.0)
117116
+ contribute(1.0, 0.0, 0.0)
118117
+ contribute(0.0, 1.0, 0.0)
119-
+ contribute(0.0, 0.0, 1.0);
120-
121-
value
118+
+ contribute(0.0, 0.0, 1.0)
122119
}
123120

124-
fn determine_further_side(ins: Vec3<f64>) -> (Vec2<bool>, Vec2<i32>) {
125-
let decide_between_points = |p: f64, point_val: (i32, i32)| {
126-
if p > 1.0 {
127-
return (p - 1.0, point_val.0, true)
128-
}
129-
(1.0 - p, point_val.1, false)
130-
};
131-
132-
// Decide between point (0, 0, 1) and (1, 1, 0) as closest
133-
let (score_x, mut point_x, mut is_further_side_x) = decide_between_points(ins.x + ins.y, (3, 4));
134-
135-
// Decide between point (0, 1, 0) and (1, 0, 1) as closest
136-
let (score_y, mut point_y, mut is_further_side_y) = decide_between_points(ins.x + ins.z, (5, 2));
121+
fn inside_tetrahedron_at_1_1_1(
122+
ins: Vec3<f64>,
123+
in_sum: f64,
124+
contribute: impl Fn(f64, f64, f64) -> f64,
125+
) -> f64 {
126+
// Determine which two tetrahedral vertices are the closest, out of (1, 1, 0), (1, 0, 1), (0, 1, 1) but not (1, 1, 1).
127+
let (score, point) = OpenSimplexNoise3D::determine_closest_point(
128+
Vec2::new(ins.x, ins.y),
129+
Vec2::new(6, 5),
130+
Vec2::new(3, 3),
131+
ins,
132+
);
137133

138-
// The closest out of the two (1, 0, 0) and (0, 1, 1) will replace
139-
// the furthest out of the two decided above, if closer.
140-
let p = ins.y + ins.z;
141-
if p > 1.0 {
142-
let score_value = p - 1.0;
143-
if score_x <= score_y && score_x < score_value {
144-
point_x = 6;
145-
is_further_side_x = true;
146-
} else if score_x > score_y && score_y < score_value {
147-
point_y = 6;
148-
is_further_side_y = true;
149-
}
150-
} else {
151-
let score_value = 1.0 - p;
152-
if score_x <= score_y && score_x < score_value {
153-
point_x = 1;
154-
is_further_side_x = false;
155-
} else if score_x > score_y && score_y < score_value {
156-
point_y = 1;
157-
is_further_side_y = false;
158-
}
159-
}
134+
// Now we determine the two lattice points not part of the tetrahedron that may contribute.
135+
// This depends on the closest two tetrahedral vertices, including (1, 1, 1)
136+
let value = OpenSimplexNoise3D::determine_lattice_points_including_1_1_1(
137+
in_sum,
138+
score,
139+
point,
140+
|x, y, z| contribute(x, y, z),
141+
);
160142

161-
(Vec2::new(is_further_side_x, is_further_side_y), Vec2::new(point_x, point_y))
143+
value
144+
+ contribute(1.0, 1.0, 0.0)
145+
+ contribute(1.0, 0.0, 1.0)
146+
+ contribute(0.0, 1.0, 1.0)
147+
+ contribute(1.0, 1.0, 1.0)
162148
}
163149

164150
fn inside_octahedron_in_between(
165151
ins: Vec3<f64>,
166152
contribute: impl Fn(f64, f64, f64) -> f64,
167153
) -> f64 {
168-
let mut value = 0.0;
169-
170154
let (is_further_side, point) = OpenSimplexNoise3D::determine_further_side(ins);
171155

172156
// Where each of the two closest points are determines how the extra two vertices are calculated.
173-
if is_further_side.x == is_further_side.y {
157+
let value = if is_further_side.x == is_further_side.y {
174158
if is_further_side.x {
175159
// Both closest points on (1, 1, 1) side
176-
177160
// One of the two extra points is (1, 1, 1)
178-
value += contribute(1.0, 1.0, 1.0);
179-
180161
// Other extra point is based on the shared axis.
181162
let closest = point.x & point.y;
182-
value += match closest {
183-
1 => contribute(2.0, 0.0, 0.0),
184-
2 => contribute(0.0, 2.0, 0.0),
185-
_ => contribute(0.0, 0.0, 2.0), // closest == 4
186-
}
163+
164+
contribute(1.0, 1.0, 1.0)
165+
+ match closest {
166+
1 => contribute(2.0, 0.0, 0.0),
167+
2 => contribute(0.0, 2.0, 0.0),
168+
_ => contribute(0.0, 0.0, 2.0), // closest == 4
169+
}
187170
} else {
188171
// Both closest points on (0, 0, 0) side
189-
190172
// One of the two extra points is (0, 0, 0)
191-
value += contribute(0.0, 0.0, 0.0);
192-
193173
// Other extra point is based on the omitted axis.
194174
let closest = point.x | point.y;
195-
value += match closest {
196-
3 => contribute(1.0, 1.0, -1.0),
197-
4 => contribute(1.0, -1.0, 1.0),
198-
_ => contribute(-1.0, 1.0, 1.0), // closest == 6
199-
}
175+
176+
contribute(0.0, 0.0, 0.0)
177+
+ match closest {
178+
3 => contribute(1.0, 1.0, -1.0),
179+
4 => contribute(1.0, -1.0, 1.0),
180+
_ => contribute(-1.0, 1.0, 1.0), // closest == 6
181+
}
200182
}
201183
} else {
202184
// One point on (0, 0, 0) side, one point on (1, 1, 1) side
@@ -207,58 +189,75 @@ impl OpenSimplexNoise3D {
207189
};
208190

209191
// One contribution is a permutation of (1, 1, -1)
210-
value += match c1 {
192+
// One contribution is a permutation of (0, 0, 2)
193+
(match c1 {
211194
3 => contribute(1.0, 1.0, -1.0),
212195
5 => contribute(1.0, -1.0, 1.0),
213196
_ => contribute(-1.0, 1.0, 1.0), // c1 == 6
214-
};
215-
// One contribution is a permutation of (0, 0, 2)
216-
value += match c2 {
197+
}) + match c2 {
217198
1 => contribute(2.0, 0.0, 0.0),
218199
2 => contribute(0.0, 2.0, 0.0),
219200
_ => contribute(0.0, 0.0, 2.0), // c1 == 4
220-
};
221-
}
201+
}
202+
};
222203

223-
value += contribute(1.0, 0.0, 0.0)
204+
value
205+
+ contribute(1.0, 0.0, 0.0)
224206
+ contribute(0.0, 1.0, 0.0)
225207
+ contribute(0.0, 0.0, 1.0)
226208
+ contribute(1.0, 1.0, 0.0)
227209
+ contribute(1.0, 0.0, 1.0)
228-
+ contribute(0.0, 1.0, 1.0);
229-
230-
value
210+
+ contribute(0.0, 1.0, 1.0)
231211
}
232212

233-
fn inside_tetrahedron_at_1_1_1(
234-
ins: Vec3<f64>,
235-
in_sum: f64,
236-
contribute: impl Fn(f64, f64, f64) -> f64,
237-
) -> f64 {
238-
let mut value = 0.0;
239-
// Determine which two tetrahedral vertices are the closest, out of (1, 1, 0), (1, 0, 1), (0, 1, 1) but not (1, 1, 1).
240-
let (score, point) = OpenSimplexNoise3D::determine_closest_point(
241-
Vec2::new(ins.x, ins.y),
242-
Vec2::new(6, 5),
243-
Vec2::new(3, 3),
244-
ins,
245-
);
213+
fn decide_between_points(ins: Vec3<f64>) -> (Vec2<f64>, Vec2<i32>, Vec2<bool>) {
214+
let decide_between_points = |p: f64, point_val: (i32, i32)| {
215+
if p > 1.0 {
216+
return (p - 1.0, point_val.0, true);
217+
}
218+
(1.0 - p, point_val.1, false)
219+
};
246220

247-
// Now we determine the two lattice points not part of the tetrahedron that may contribute.
248-
// This depends on the closest two tetrahedral vertices, including (1, 1, 1)
249-
value += OpenSimplexNoise3D::determine_lattice_points_including_1_1_1(
250-
in_sum,
251-
score,
252-
point,
253-
|x, y, z| contribute(x, y, z),
254-
);
221+
// Decide between point (0, 0, 1) and (1, 1, 0) as closest
222+
let (score_x, point_x, is_further_side_x) = decide_between_points(ins.x + ins.y, (3, 4));
223+
// Decide between point (0, 1, 0) and (1, 0, 1) as closest
224+
let (score_y, point_y, is_further_side_y) = decide_between_points(ins.x + ins.z, (5, 2));
255225

256-
value += contribute(1.0, 1.0, 0.0)
257-
+ contribute(1.0, 0.0, 1.0)
258-
+ contribute(0.0, 1.0, 1.0)
259-
+ contribute(1.0, 1.0, 1.0);
226+
(
227+
Vec2::new(score_x, score_y),
228+
Vec2::new(point_x, point_y),
229+
Vec2::new(is_further_side_x, is_further_side_y),
230+
)
231+
}
260232

261-
value
233+
fn determine_further_side(ins: Vec3<f64>) -> (Vec2<bool>, Vec2<i32>) {
234+
let (score, mut point, mut is_further_side) =
235+
OpenSimplexNoise3D::decide_between_points(ins);
236+
237+
// The closest out of the two (1, 0, 0) and (0, 1, 1) will replace
238+
// the furthest out of the two decided above, if closer.
239+
let p = ins.y + ins.z;
240+
if p > 1.0 {
241+
let score_value = p - 1.0;
242+
if score.x <= score.y && score.x < score_value {
243+
point.x = 6;
244+
is_further_side.x = true;
245+
} else if score.x > score.y && score.y < score_value {
246+
point.y = 6;
247+
is_further_side.y = true;
248+
}
249+
} else {
250+
let score_value = 1.0 - p;
251+
if score.x <= score.y && score.x < score_value {
252+
point.x = 1;
253+
is_further_side.x = false;
254+
} else if score.x > score.y && score.y < score_value {
255+
point.y = 1;
256+
is_further_side.y = false;
257+
}
258+
}
259+
260+
(is_further_side, point)
262261
}
263262

264263
fn determine_closest_point(

0 commit comments

Comments
 (0)