This is a simplified version of the OpenSimplex noise (and all its versions).
seed = 0x120367e73b381c44
#Modified version of random number generator by Bernard Widynski. https://arxiv.org/abs/2004.06278
get_random_number(pos,seed) = get_random_number(convert(UInt64,pos),convert(UInt64,seed))
get_random_noise(pos,seed) = get_random_noise(convert(UInt64,pos),convert(UInt64,seed))
function get_random_number(pos::UInt64,seed::UInt64)
y = x = pos*seed; z = y+seed
x = x*x+y; x = (x>>32)|(x<<32)
x = x*x+z; x = (x>>32)|(x<<32)
x = x*x+y; x = (x>>32)|(x<<32)
return ((x*x+z)>>32)%UInt32
end
function get_random_noise(pos::UInt64,seed::UInt64)
y = x = pos*seed; z = y+seed
x = x*x+y; x = (x>>32)|(x<<32)
x = x*x+z; x = (x>>32)|(x<<32)
x = x*x+y; x = (x>>32)|(x<<32)
return reinterpret(Float32,(((x*x+z)>>41)%UInt32)|reinterpret(UInt32,Float32(1.0)))-Float32(1.0)
end
function smooth_transition(x)
x = x*(1-x)
x2 = x*x
return 16*x2
end
function smoother_step_7_th_order(x)
x_sq = x*x
return x_sq*x_sq*(((-20*x+70)*x-84)*x+35)
end
using Plots
using Random
using LoopVectorization
x = range(0, 1, length=100)
y = smoother_step_7_th_order.(x)
plot(x,y)
const main_seed::UInt64 = 0xb6e06d07c7dd3a5f
#seeder = Xoshiro(main_seed)
@inline function noise2d(x_in,y_in,xx_seed,xy_seed,xz_seed,yx_seed,yy_seed,yz_seed,zx_seed,zy_seed,zz_seed)
#x = 0.66666667*y_in
eps = 1e-6
unit = one(UInt64)
y = 0.57735027*x_in -0.33333333*y_in
z = -0.57735027*x_in -0.33333333*y_in
x = -y-z
#(X,x) = (reinterpret(UInt64,floor(Int64,x)),x%1)
X = reinterpret(UInt64,floor(Int64,x))
x = x-floor(x)
Y = reinterpret(UInt64,floor(Int64,y))
y = y-floor(y)
Z = reinterpret(UInt64,floor(Int64,z))
z = z-floor(z)
#(Y,y) = (reinterpret(UInt64,floor(Int64,y)),y%1)
#(Z,z) = (reinterpret(UInt64,floor(Int64,z)),z%1)
next_X = X+unit
next_Y = Y+unit
next_Z = Z+unit
x_seed = xx_seed⊻get_random_number(Y,xy_seed)⊻get_random_number(Z,xz_seed)
#println(xx_seed)
current_x_value = get_random_noise(X,x_seed)
next_x_value = get_random_noise(next_X,x_seed)
true_x_value = (smoother_step_7_th_order(x)*(next_x_value-current_x_value) + current_x_value-0.5)*2
#println("Debug")
#println(current_x_value)
#println(next_x_value)
true_x_value *= smooth_transition(y)*smooth_transition(z)
#println(true_x_value)
y_seed = yy_seed⊻get_random_number(X,yx_seed)⊻get_random_number(Z,yz_seed)
current_y_value = get_random_noise(Y,y_seed)
next_y_value = get_random_noise(next_Y,y_seed)
true_y_value = (smoother_step_7_th_order(y)*(next_y_value-current_y_value) + current_y_value-0.5)*2
true_y_value *= smooth_transition(x)*smooth_transition(z)
z_seed = zz_seed⊻get_random_number(X,zx_seed)⊻get_random_number(Y,zy_seed)
current_z_value = get_random_noise(Z,z_seed)
next_z_value = get_random_noise(next_Z,z_seed)
true_z_value = (smoother_step_7_th_order(z)*(next_z_value-current_z_value) + current_z_value-0.5)*2
true_z_value *= smooth_transition(x)*smooth_transition(y)
return (true_x_value+true_y_value+true_z_value)/3
end
function main(seed)
seeder = Xoshiro(seed)
#Seed can be generated in any random way.
xx_seed = rand(seeder,UInt64)
xy_seed = rand(seeder,UInt64)
xz_seed = rand(seeder,UInt64)
yx_seed = rand(seeder,UInt64)
yy_seed = rand(seeder,UInt64)
yz_seed = rand(seeder,UInt64)
zx_seed = rand(seeder,UInt64)
zy_seed = rand(seeder,UInt64)
zz_seed = rand(seeder,UInt64)
A = Array{Float64,2}(undef,(1024,1024))
for y in 1:1024, x in 1:1024
@inbounds @fastmath A[x,y] = noise2d(x/64,y/64,xx_seed,xy_seed,xz_seed,yx_seed,yy_seed,yz_seed,zx_seed,zy_seed,zz_seed)
end
return A
end
Xoshiro(main_seed)
heatmap(main(main_seed))
@Siddharth_Bhatia, @Kyjor
@cormullion you might be interested.