Attempt to port eevee perlin noise implementation to wren. didn't really got the same result https://gist.github.com/eevee/26f547457522755cb1fb8739d0ea89a1#file-perlin-py-L71
seems like it's something related to the random.gauss function
Attempt to port eevee perlin noise implementation to wren. didn't really got the same result https://gist.github.com/eevee/26f547457522755cb1fb8739d0ea89a1#file-perlin-py-L71
seems like it's something related to the random.gauss function
| import "random" for Random | |
| class Perlin{ | |
| construct new(seed, dimension, octaves, tile, unbias){ | |
| _random = Random.new(seed) | |
| _dimension = dimension | |
| _octaves = octaves | |
| _tile = tile | |
| _unbias = unbias | |
| _scale_factor = 2 * _dimension.pow(-0.5) | |
| _gradient = {} | |
| } | |
| smoothstep(t){ | |
| return t * t * (3.0 - 2.0 * t) | |
| } | |
| lerp(t, a, b){ | |
| return a + t * (b - a) | |
| } | |
| generate_gradient(){ | |
| if(_dimension == 1){ | |
| return [_random.float(-1, 1), 0] | |
| } | |
| var random_point = [] | |
| for(d in 0..._dimension){ | |
| random_point.add(randn_bm(0, 1, 1)) | |
| } | |
| var scale = 0 | |
| for(p in random_point){ | |
| scale = scale + (p * p) | |
| } | |
| scale.pow(-0.5) | |
| System.print(random_point) | |
| for(i in 0...random_point.count){ | |
| random_point[i] = random_point[i] * scale | |
| } | |
| return random_point | |
| } | |
| //https://stackoverflow.com/questions/25582882/javascript-math-random-normal-distribution-gaussian-bell-curve/39187274#39187274 | |
| randn_bm(min, max, skew){ | |
| var u = 0 | |
| var v = 0 | |
| while(u == 0) u = _random.float() //Converting [0,1) to (0,1) | |
| while(v == 0) v = _random.float() | |
| var num = ( -2.0 * u.log ).sqrt * ( 2.0 * Num.pi * v ).cos | |
| num = num / 10.0 + 0.5 // Translate to 0 -> 1 | |
| if (num > 1 || num < 0) num = randn_bm(min, max, skew) // resample between 0 and 1 if out of range | |
| num = num.pow(skew) // Skew | |
| num = num * (max - min) // Stretch to fill range | |
| num = num + min // offset to min | |
| return num | |
| } | |
| get_plain_noise(point){ | |
| if(point.count != _dimension){ | |
| System.print("expected %(_dimension) values, got %(point.count)") | |
| } | |
| var grid_coords = [] | |
| for (coord in point){ | |
| var min_coord = coord.floor | |
| var max_coord = min_coord + 1 | |
| grid_coords.add([min_coord, max_coord]) | |
| } | |
| var dots = [] | |
| for(grid_point in cartesian_product(grid_coords)){ | |
| var grid_point_hash = get_grid_point_hash(grid_point) | |
| if(!_gradient[grid_point_hash]){ | |
| _gradient[grid_point_hash] = generate_gradient() | |
| } | |
| var gradient = _gradient[grid_point_hash] | |
| var dot = 0 | |
| for(i in 0..._dimension){ | |
| dot = dot + gradient[i] * (point[i] - grid_point[i]) | |
| } | |
| dots.add(dot) | |
| } | |
| var dim = _dimension | |
| while(dots.count > 1){ | |
| dim = dim - 1 | |
| var s = smoothstep(point[dim] - grid_coords[dim][0]) | |
| var next_dots = [] | |
| while(dots.count > 0){ | |
| next_dots.add(lerp(s, dots.removeAt(0), dots.removeAt(0))) | |
| } | |
| dots = next_dots | |
| } | |
| return dots[0] * _scale_factor | |
| } | |
| get_grid_point_hash(grid_point){ | |
| var hash = "" | |
| grid_point.each {|n| | |
| hash = hash + "%(n)" | |
| } | |
| return hash | |
| } | |
| cartesian_product(list){ | |
| var results = [[]] | |
| for (i in 0...list.count) { | |
| var currentSubArray = list[i] | |
| var temp = [] | |
| for ( j in 0...results.count) { | |
| for (k in 0...currentSubArray.count) { | |
| temp.add(results[j] + [currentSubArray[k]]) | |
| } | |
| } | |
| results = temp | |
| } | |
| return results | |
| } | |
| noise(point){ | |
| //return | |
| var ret = 0 | |
| for(oct in 0..._octaves){ | |
| var oct_2 = 1 << oct | |
| var new_point = [] | |
| for(i in 0...point.count){ | |
| var coord = point[i] | |
| coord = coord * oct_2 | |
| if(_tile[i]){ | |
| coord = coord % _tile[i] * oct_2 | |
| } | |
| new_point.add(coord) | |
| } | |
| ret = ret + get_plain_noise(new_point) / oct_2 | |
| } | |
| ret = ret / (2 - 2.pow(1 - _octaves)) | |
| if(_unbias){ | |
| var r = (ret + 1) / 2 | |
| for(i in 0...(_octaves / 2 + 0.5).floor){ | |
| r = smoothstep(r) | |
| } | |
| ret = r * 2 - 1 | |
| } | |
| return ret | |
| } | |
| } |