У меня возникли проблемы с реализацией алгоритма перлин-шума, подробно описанного ниже. Алгоритм производит вывод, который явно неверен, демонстрируя мозаику вдоль линий сетки и градиентов, которые на самом деле не выглядят случайными вообще.
Perlin()
for(var/x = origin_x, x < limit_x, x++)
for(var/y = origin_y, y < limit_y, y++)
OctavePerlin(x/scale, y/scale, 1, octaves, virility)
/proc/OctavePerlin(var/x, var/y, var/z, var/octaves, var/persistence)
var/total = 0
var/frequency = 1
var/amplitude = 1
var/maxValue = 0 // Used for normalizing result to 0.0 - 1.0
for(var/i = 0; i < octaves; i++)
total += perlin(x * frequency, y * frequency, z * frequency) * amplitude
maxValue += amplitude
amplitude *= persistence
frequency *= 2
return total/maxValue
var/list/perlin_permutation = list(151,160,137,91,90,15,
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180 )
var/perlin_p[512]
/proc/Perlin()
for(var/x = 1; x <= 512; x++)
perlin_p[x] = perlin_permutation[x % 256]
/proc/perlin(var/x, var/y, var/z)
var/xi = x & 255
var/yi = y & 255
var/zi = z & 255
var/xf = x - round(x)
var/yf = y - round(y)
var/zf = z - round(z)
var/u = fade(xf)
var/v = fade(yf)
var/w = fade(zf)
var/aaa = perlin_p[perlin_p[perlin_p[ xi ]+ yi ]+ zi ]
var/aba = perlin_p[perlin_p[perlin_p[ xi ]+(yi++)]+ zi ]
var/aab = perlin_p[perlin_p[perlin_p[ xi ]+ yi ]+(zi++)]
var/abb = perlin_p[perlin_p[perlin_p[ xi ]+(yi++)]+(zi++)]
var/baa = perlin_p[perlin_p[perlin_p[(xi++)]+ yi ]+ zi ]
var/bba = perlin_p[perlin_p[perlin_p[(xi++)]+(yi++)]+ zi ]
var/bab = perlin_p[perlin_p[perlin_p[(xi++)]+ yi ]+(zi++)]
var/bbb = perlin_p[perlin_p[perlin_p[(xi++)]+(yi++)]+(zi++)]
var/x1 = lerp(grad (aaa, xf , yf , zf),
grad (baa, xf-1, yf , zf),
u)
var/x2 = lerp(grad (aba, xf , yf-1, zf),
grad (bba, xf-1, yf-1, zf),
u)
var/y1 = lerp(x1, x2, v)
x1 = lerp(grad (aab, xf , yf , zf-1),
grad (bab, xf-1, yf , zf-1),
u)
x2 = lerp(grad (abb, xf , yf-1, zf-1),
grad (bbb, xf-1, yf-1, zf-1),
u)
var/y2 = lerp (x1, x2, v)
return (lerp (y1, y2, w)+1)/2
/proc/grad(var/hash, var/x, var/y, var/z)
switch(hash & 0xF)
if (0x0)
return x + y
if (0x1)
return -x + y
if (0x2)
return x - y
if (0x3)
return -x - y
if (0x4)
return x + z
if (0x5)
return -x + z
if (0x6)
return x - z
if (0x7)
return -x - z
if (0x8)
return y + z
if (0x9)
return -y + z
if (0xA)
return y - z
if (0xB)
return -y - z
if (0xC)
return y + x
if (0xD)
return -y + z
if (0xE)
return y - x
if (0xF)
return -y - z
else
return 0 // never happens
/proc/fade(var/t)
return t * t * t * (t * (t * 6 - 15) + 10)
/proc/lerp(var/a, var/b, var/x)
return a + x * (b - a)
Вывод этого вывода вместо карты шума перлина: Неправильный вывод, показывающий мозаику вдоль линий сетки
Этот код выше получен из модели, установленной этим кодом ниже; https://gist.github.com/Flafla2/f0260a861be0ebdeef76