Author Topic: perlin noise  (Read 478 times)

John

  • Sr. Member
  • ****
  • Posts: 362
    • View Profile
perlin noise
« on: August 25, 2016 »
going through old stuff. this code generates perlin noise, which can be used for ... things  :)  if you set the last parameter for PerlinNoise to true, the resulting noise will be seamless.

Code: [Select]
' generate 2d perlin noise.

' create noise.
noise#[][] = PerlinNoise(8, 16, 48, 24, true)

set redraw off

' display as grayscale image.
for y = 0 to sizeof(noise, 1) - 1
for x = 0 to sizeof(noise, 0) - 1
c = int(noise[x][y]*255.0)
set color c, c, c
set pixel 16 + x, 16 + y
next
next

redraw
wait keydown


' generate 2D Perlin noise as an array of float values in the range [0..1]. the
' resulting array will have the size [divX*celW][divY*celH].
function PerlinNoise#[][](divX, divY, celW, celH, tileable)
g#[divX + 1][divY + 1][2]
for y = 0 to divY
for x = 0 to divX
a# = float(rnd(360))
g[x][y][0] = cos(a)
g[x][y][1] = sin(a)
next
next
if tileable
for y = 0 to divY; g[0][y][0] = g[divX][y][0]; g[0][y][1] = g[divX][y][1]; next
for x = 0 to divX; g[x][0][0] = g[x][divY][0]; g[x][0][1] = g[x][divY][1];next
endif

w = divX*celW
h = divY*celH
res#[w][h]
for y = 0 to h - 1; for x = 0 to w - 1
res[x][y] = Perlin(g, float(x)/float(celW), float(y)/float(celH))
next; next
minVal# = res[0][0]
maxVal# = res[0][0]
for y = 0 to h - 1; for x = 0 to w - 1
minVal = min#(minVal, res[x][y])
maxVal = max#(maxVal, res[x][y])
next; next
for y = 0 to h - 1; for x = 0 to w - 1
res[x][y] = (res[x][y] - minVal)/(maxVal - minVal)
next; next
return res
endfunc

function Perlin#(&gradients#[][][], x#, y#)
x0 = int(x)
y0 = int(y)
x1 = x0 + 1
y1 = y0 + 1
sx# = x - float(x0)
sy# = y - float(y0)
n0# = DotGridGradient(gradients, x0, y0, x, y)
n1# = DotGridGradient(gradients, x1, y0, x, y)
ix0# = Interpolate(n0, n1, sx)
n0 = DotGridGradient(gradients, x0, y1, x, y)
n1 = DotGridGradient(gradients, x1, y1, x, y)
ix1# = Interpolate(n0, n1, sx)
return Interpolate(ix0, ix1, sy)
endfunc

function DotGridGradient#(&gradients#[][][], ix, iy, x#, y#)
dx# = x - float(ix)
dy# = y - float(iy)
return dx*gradients[ix][iy][0] + dy*gradients[ix][iy][1]
endfunc

function Interpolate#(a#, b#, param#)
return Linear(a, b, Polynomial(param))
endfunc

function Linear#(a#, b#, param#)
return (1.0 - param)*a + param*b
endproc

function Polynomial#(coef#)
return 3.0*coef*coef - 2.0*coef*coef*coef
endfunc
« Last Edit: August 25, 2016 by John »

John

  • Sr. Member
  • ****
  • Posts: 362
    • View Profile
Re: perlin noise
« Reply #1 on: August 25, 2016 »
if you want to save the noise data as an image just do something like this:

Code: [Select]
create image 1, sizeof(noise, 0), sizeof(noise, 1)
set image 1
for y = 0 to sizeof(noise, 1) - 1
for x = 0 to sizeof(noise, 0) - 1
c = int(noise[x][y]*255.0)
set color c, c, c
set pixel x, y
next
next
set image primary
save image 1, "my_noise.bmp"

Marcus

  • Administrator
  • Hero Member
  • *****
  • Posts: 549
    • View Profile
Re: perlin noise
« Reply #2 on: August 25, 2016 »
I actually tried building a random 2d cave generator for a platform game the other day using the cloud  generator from the examples. Perlin noise will work much better, so thanks (back to irl work, having a 15 min break)!
.\\\opz

cherbert

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: perlin noise
« Reply #3 on: August 25, 2016 »
This will be really useful. Thank you.

Marcus

  • Administrator
  • Hero Member
  • *****
  • Posts: 549
    • View Profile
Re: perlin noise
« Reply #4 on: August 25, 2016 »
Here I'm using your perlin noise functions and the tilemap library for creating a world of 1024*1024 blocks, which in this case translates to 16384x16384 pixels.  You can just scroll around with the arrow keys now, would be more fun to climb and dig with a wee sprite :) There's a mini-map showing the world with the visible area marked.

.\\\opz