Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
# simplexnoise
python implementation of 3d simplex noise

Python implementation of 3d simplex noise

Note: Tensorflow implementation now compatible with verseion 2.x and may not work with 1.x versions.
2 changes: 1 addition & 1 deletion numpy-simplex-naive.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def np_noise3d(v):
input_vectors = get_input_vectors(shape, phases, scaling)
raw_noise = np.empty(input_vectors.shape[0], dtype=np.float32)
start_time = time()
for i in range(0, input_vectors.shape[0]):
for i in range(input_vectors.shape[0]):
raw_noise[i] = np_noise3d(input_vectors[i])
print("The calculation took " + str(time() - start_time) + " seconds.")
image_data = sum_phases(raw_noise, phases, shape)
Expand Down
66 changes: 31 additions & 35 deletions tensor-flow-simplex-matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,22 +46,22 @@


def calculate_gradient_contribution(offsets, gis, gradient_map, length):
t = 0.5 - offsets[:, 0] ** 2 - offsets[:, 1] ** 2 - offsets[:, 2] ** 2
t = 0.5 - offsets[:, 0] ** 2. - offsets[:, 1] ** 2. - offsets[:, 2] ** 2.
mapped_gis = map_gradients(gradient_map, gis, length)
dot_products = tf.reduce_sum(mapped_gis * offsets, 1)
return tf.to_float(tf.greater_equal(t, 0)) * t ** 4 * dot_products
return tf.cast(tf.math.greater_equal(t, 0.), tf.float32) * t ** 4. * dot_products


def noise3d(input_vectors, perm, grad3, vertex_table, length):
skew_factors = (input_vectors[:, 0] + input_vectors[:, 1] + input_vectors[:, 2]) * 1.0 / 3.0
skewed_vectors = tf.floor(input_vectors + tf.expand_dims(skew_factors, 1))
unskew_factors = (skewed_vectors[:, 0] + skewed_vectors[:, 1] + skewed_vectors[:, 2]) * 1.0 / 6.0
offsets_0 = input_vectors - (skewed_vectors - tf.expand_dims(unskew_factors, 1))
simplex_vertices = get_simplex_vertices(offsets_0, vertex_table, length)
simplex_vertices = get_simplex_vertices(offsets_0, vertex_table, length) # divided it by 2, doesn't error now
offsets_1 = offsets_0 - simplex_vertices[:, 0, :] + 1.0 / 6.0
offsets_2 = offsets_0 - simplex_vertices[:, 1, :] + 1.0 / 3.0
offsets_3 = offsets_0 - 0.5
masked_skewed_vectors = tf.to_int32(skewed_vectors) % 256
masked_skewed_vectors = tf.cast(skewed_vectors, tf.int32) % 256
gi0s = tf.gather_nd(
perm,
tf.expand_dims(masked_skewed_vectors[:, 0], 1) +
Expand All @@ -75,28 +75,28 @@ def noise3d(input_vectors, perm, grad3, vertex_table, length):
gi1s = tf.gather_nd(
perm,
tf.expand_dims(masked_skewed_vectors[:, 0], 1) +
tf.expand_dims(tf.to_int32(simplex_vertices[:, 0, 0]), 1) +
tf.expand_dims(tf.cast(simplex_vertices[:, 0, 0], tf.int32), 1) +
tf.expand_dims(tf.gather_nd(
perm,
tf.expand_dims(masked_skewed_vectors[:, 1], 1) +
tf.expand_dims(tf.to_int32(simplex_vertices[:, 0, 1]), 1) +
tf.expand_dims(tf.cast(simplex_vertices[:, 0, 1], tf.int32), 1) +
tf.expand_dims(tf.gather_nd(
perm,
tf.expand_dims(masked_skewed_vectors[:, 2], 1) +
tf.expand_dims(tf.to_int32(simplex_vertices[:, 0, 2]), 1)), 1)), 1)
tf.expand_dims(tf.cast(simplex_vertices[:, 0, 2], tf.int32), 1)), 1)), 1)
) % 12
gi2s = tf.gather_nd(
perm,
tf.expand_dims(masked_skewed_vectors[:, 0], 1) +
tf.expand_dims(tf.to_int32(simplex_vertices[:, 1, 0]), 1) +
tf.expand_dims(tf.cast(simplex_vertices[:, 1, 0], tf.int32), 1) +
tf.expand_dims(tf.gather_nd(
perm,
tf.expand_dims(masked_skewed_vectors[:, 1], 1) +
tf.expand_dims(tf.to_int32(simplex_vertices[:, 1, 1]), 1) +
tf.expand_dims(tf.cast(simplex_vertices[:, 1, 1], tf.int32), 1) +
tf.expand_dims(tf.gather_nd(
perm,
tf.expand_dims(masked_skewed_vectors[:, 2], 1) +
tf.expand_dims(tf.to_int32(simplex_vertices[:, 1, 2]), 1)), 1)), 1)
tf.expand_dims(tf.cast(simplex_vertices[:, 1, 2], tf.int32), 1)), 1)), 1)
) % 12
gi3s = tf.gather_nd(
perm,
Expand All @@ -121,43 +121,39 @@ def noise3d(input_vectors, perm, grad3, vertex_table, length):

def calculate_image(noise_values, phases, shape):
val = tf.floor((tf.add_n(tf.split(
2,
phases,
tf.reshape(noise_values, [shape[0], shape[1], phases]) / tf.pow(
2.0,
tf.linspace(0.0, tf.to_float(phases - 1), phases))
)) + 1.0) * 128)
return tf.concat(2, [val, val, val])
tf.linspace(0.0, phases - 1., phases)), phases, 2)) + 1.0) * 128.)
return tf.concat([val, val, val], 2)


if __name__ == "__main__":
shape = (512, 512)
phases = 10
scaling = 200.0
offset = (0.0, 0.0, 1.7)
v_shape = tf.Variable([512, 512], name='shape')
v_phases = tf.Variable(5, name='phases')
v_scaling = tf.Variable(200.0, name='scaling')
v_offset = tf.Variable([0.0, 0.0, 1.7], name='offset')
v_shape = tf.constant(shape, name='shape')
v_phases = tf.constant(phases, name='phases')
v_scaling = tf.constant(scaling, name='scaling')
v_offset = tf.constant(offset, name='offset')
v_input_vectors = get_input_vectors(v_shape, v_phases, v_scaling, v_offset)
perm = tf.Variable(np_perm, name='perm')
grad3 = tf.Variable(np_grad3, name='grad3')
num_steps_burn_in = 10
num_steps_benchmark = 20
vertex_table = tf.Variable(np_vertex_table, name='vertex_table')
perm = tf.constant(np_perm, name='perm')
grad3 = tf.constant(np_grad3, name='grad3')
vertex_table = tf.constant(np_vertex_table, name='vertex_table')
start_time = time()
raw_noise = noise3d(v_input_vectors, perm, grad3, vertex_table, shape[0] * shape[1] * phases)
end_time = time()
print('Time to calculate one iteration: {:.4f}'.format(end_time - start_time))
raw_image_data = calculate_image(raw_noise, phases, v_shape)
init = tf.initialize_all_variables()
input_vectors = get_input_vectors(shape, phases, scaling, offset)
noise = noise3d(input_vectors, np_perm, np_grad3, np_vertex_table, shape[0] * shape[1] * phases)
image_data = calculate_image(noise, phases, shape)
sess = tf.Session()
sess.run(init)
for i in range(num_steps_burn_in):
raw_img = sess.run(image_data)
start_time = time()
for i in range(num_steps_benchmark):
raw_img = sess.run(image_data)
print("The calculation took %.4f seconds." % ((time() - start_time) / num_steps_benchmark))
# writer = tf.train.SummaryWriter("tf-logs/", sess.graph) # write logs for TensorBoard
show(raw_img.astype(np.uint8))
show(image_data.numpy().astype(np.uint8))

# Custom vector repeating the top quarter of the image 4 times
base_values = input_vectors[0:int(input_vectors.shape[0] / 4)]
input_vectors = tf.tile(base_values, [4, 1])
noise = noise3d(input_vectors, np_perm, np_grad3, np_vertex_table, shape[0] * shape[1] * phases)
image_data = calculate_image(noise, phases, shape)

show(image_data.numpy().astype(np.uint8))
30 changes: 15 additions & 15 deletions tf_get_simplex_vertices.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,35 +14,35 @@
], dtype=np.float32)

# Dimesions are: x0 >= y0, y0 >= z0, x0 >= z0
np_vertex_table = np.array([
# np_vertex_table = np.array([
tf_vertex_table = tf.convert_to_tensor([
[[vertex_options[3], vertex_options[3]],
[vertex_options[4], vertex_options[5]]],
[[vertex_options[2], vertex_options[1]],
[vertex_options[2], vertex_options[0]]]
], dtype=np.float32)
], dtype=tf.float32)


def get_simplex_vertices(offsets, vertex_table, length):
vertex_table_x_index = tf.to_int32(offsets[:, 0] >= offsets[:, 1])
vertex_table_y_index = tf.to_int32(offsets[:, 1] >= offsets[:, 2])
vertex_table_z_index = tf.to_int32(offsets[:, 0] >= offsets[:, 2])
index_list = tf.concat(1, [
tf.reshape(tf.tile(tf.concat(1, [
vertex_table_x_index = tf.cast((offsets[:, 0] >= offsets[:, 1]), tf.int32)
vertex_table_y_index = tf.cast((offsets[:, 1] >= offsets[:, 2]), tf.int32)
vertex_table_z_index = tf.cast((offsets[:, 0] >= offsets[:, 2]), tf.int32)

index_list = tf.concat([
tf.reshape(tf.tile(tf.concat([
tf.expand_dims(vertex_table_x_index, 1),
tf.expand_dims(vertex_table_y_index, 1),
tf.expand_dims(vertex_table_z_index, 1),
]), [1, 6]), [6 * length, 3]),
tf.expand_dims(tf.tile(tf.range(0, limit=6), [length]), 1)])
], 1), [1, 6]), [6 * length, 3]),
tf.expand_dims(tf.tile(tf.range(0, limit=6), [length]), 1)], 1)
vertices = tf.reshape(tf.gather_nd(vertex_table, index_list), [-1, 2, 3])
return vertices


if __name__ == "__main__":
vertex_table = tf.Variable(np_vertex_table, name='vertex_table')
test_offsets = tf.Variable([[0.2, 0.1, 0.3], [0.03, 0.15, 0.12],

vertex_table = tf.constant(tf_vertex_table, name='vertex_table')
test_offsets = tf.constant([[0.2, 0.1, 0.3], [0.03, 0.15, 0.12],
[0.34, 0.21, 0.31], [0.49, 0.0012, 0.237]], name="offsets")
verts = get_simplex_vertices(test_offsets, vertex_table, 4)
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
print(sess.run(tf.to_int32(verts[:, 0, 1])))
print(verts)
13 changes: 7 additions & 6 deletions tf_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,17 @@ def tf_repeat(x, num_repeats):


def get_input_vectors(shape, phases, scaling, offset):
x = tf.reshape(tf_repeat(offset[0] + tf.linspace(0.0, tf.to_float(shape[0] - 1), shape[0]) / scaling,
x = tf.reshape(tf_repeat(offset[0] + tf.linspace(0.0, float(shape[0]) - 1., shape[0]) / float(scaling),
shape[1] * phases),
[shape[0], shape[1], phases]) * tf.pow(2.0, tf.linspace(0.0, tf.to_float(phases - 1), phases))
[shape[0], shape[1], phases]) * tf.pow(2.0, tf.linspace(0.0, float(phases) - 1., phases))
y = tf.reshape(tf_repeat(tf.tile(
offset[1] + tf.linspace(0.0, tf.to_float(shape[1] - 1), shape[1]) / scaling,
offset[1] + tf.linspace(0.0, float(shape[1]) - 1., shape[1]) / scaling,
[shape[0]]
), phases), [shape[0], shape[1], phases]) * tf.pow(2.0, tf.linspace(0.0, tf.to_float(phases - 1), phases))
), phases), [shape[0], shape[1], phases]) * tf.pow(2.0, tf.linspace(0.0, float(phases) - 1., phases))
z = tf.reshape(
tf.tile(offset[2] + 10 * tf.linspace(0.0, tf.to_float(phases - 1), phases), [shape[0] * shape[1]]),
tf.tile(offset[2] + 10. * tf.linspace(0.0, float(phases) - 1., phases), [shape[0] * shape[1]]),
[shape[0], shape[1], phases, 1])
x = tf.reshape(x, [shape[0], shape[1], phases, 1])
y = tf.reshape(y, [shape[0], shape[1], phases, 1])
return tf.reshape(tf.concat(3, [x, y, z]), [shape[0] * shape[1] * phases, 3])

return tf.reshape(tf.concat([x, y, z], 3), [shape[0] * shape[1] * phases, 3])
11 changes: 4 additions & 7 deletions tf_map_gradient.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,15 @@


def map_gradients(gradient_map, gis, length):
index_tensor = tf.reshape(tf.concat(1, [
index_tensor = tf.reshape(tf.concat([
tf.reshape(tf.tile(tf.expand_dims(gis, 1), [1, 3]), [length * 3, 1]),
tf.expand_dims(tf.tile(tf.range(0, limit=3), [length]), 1)
]), [length, 3, 2])
], 1), [length, 3, 2])
return tf.gather_nd(gradient_map, index_tensor)


if __name__ == "__main__":
gradient_map = tf.Variable(np_grad3, name='vertex_table')
gradient_map = tf.constant(np_grad3, name='vertex_table')
gis = tf.Variable([0, 3, 7, 2, 9, 11, 7, 4], name="gis")
gradients = map_gradients(gradient_map, gis, 8)
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
print(sess.run(gradients))
print(gradients)