December 04, 2020, 11:47:29 AM

Author Topic: [bb] Perlin noise by Flanker [ 1+ years ago ]  (Read 662 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
[bb] Perlin noise by Flanker [ 1+ years ago ]
« on: June 29, 2017, 12:28:43 AM »
Title : Perlin noise
Author : Flanker
Posted : 1+ years ago

Description : One of the first thing I did in Blitz3D, based on an article from Ken Perlin. It's quite old and it's probably not optimize or correct and it's badly commented but it works quite well. It generates perlin noise in an array with values beetween 0 and 255.

Function parameters to play with (all are optionnal):
- size : size of the "texture", must be power of 8 (64,128,256...)
(note that it will actually generate a "texture" of size+1)
- octaves : number of layers to merge, increasing octaves gives more details but is slower to generate.
- frequency : frequency of "big" details like craters or hills.
- persistence : persistence is like smooth or accentuate the result.
- loop : makes the "texture" seamless
- seed : you can provide a random seed to generate the exact same noise.

Octaves and frequency values can cause strange results if not chosen correctly. Just test yourself.


Code :
Code: BlitzBasic
  1. Dim octave(x,y,octaves)
  2. Dim perlin#(x,y)
  3.  
  4. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  5. ; example ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  6. Graphics 800,600,32,2
  7. SetBuffer BackBuffer()
  8.  
  9. SeedRnd MilliSecs()
  10.  
  11. perlin_size = 256
  12.  
  13. While Not KeyHit(1)
  14.  
  15.         Cls
  16.  
  17.         time = Perlin_Generate(perlin_size,8,4,0.5,False,0)
  18.        
  19.         LockBuffer()
  20.        
  21.         For x = 0 To perlin_size-1
  22.                 For y = 0 To perlin_size-1
  23.                
  24.                         rgb = perlin(x,y) Or (perlin(x,y) Shl 8) Or (perlin(x,y) Shl 16)
  25.                
  26.                         WritePixelFast x,y,rgb
  27.                
  28.                 Next
  29.         Next
  30.        
  31.         UnlockBuffer()
  32.        
  33.         Text 650,50,time + "ms"
  34.        
  35.         Flip
  36.        
  37.         WaitKey()
  38.        
  39. Wend
  40.  
  41. End
  42. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  43. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  44.  
  45. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  46. Function Perlin_Generate(size#=128,octaves#=8,frequency#=8,persistence#=0.5,loop=False,seed=0)
  47.  
  48.         ; time measure
  49.         time = MilliSecs()
  50.  
  51.         ; used to store maximum value
  52.         maximum# = 0
  53.         minimum# = 2147483647
  54.  
  55.  
  56.         ; resize arrays
  57.         Dim octave(size+1,size+1,octaves)
  58.         Dim perlin(size+1,size+1)
  59.  
  60.         ; calculate the size of initial cells
  61.         inc# = size / frequency
  62.        
  63.         ; fill randomly octave 0
  64.         If seed <> 0 Then SeedRnd seed
  65.         For x = 0 To size
  66.                 For y = 0 To size
  67.                
  68.                         octave(x,y,0) = Rand(255)
  69.                        
  70.                         ; to loop the noise : fill cells from a side with value from opposite side
  71.                         If loop = True
  72.                                 If x = size Then octave(x,y,0) = octave(0,y,0)
  73.                                 If y = size Then octave(x,y,0) = octave(x,0,0)
  74.                         EndIf
  75.                        
  76.                 Next
  77.         Next
  78.        
  79.         ; interpolate points from octaves, based on first octave
  80.         For layer = 1 To octaves
  81.                
  82.                 ; initialize new x for each layer
  83.                 x1# = 0
  84.                 x2# = inc
  85.                
  86.                 For x = 0 To size
  87.                
  88.                         ; advance in x if necessary
  89.                         If x = x2
  90.                                 x1 = x2
  91.                                 x2 = x2+inc
  92.                                 If x2 > size+1 Then x2 = size+1
  93.                         EndIf
  94.                
  95.                         ; initialize new x for each layer
  96.                         y1# = 0
  97.                         y2# = inc
  98.                
  99.                         For y = 0 To size
  100.                        
  101.                                 ; advance in x if necessary
  102.                                 If y = y2
  103.                                         y1 = y2
  104.                                         y2 = y2+inc
  105.                                         If y2 > size+1 Then y2 = size+1
  106.                                 EndIf                  
  107.  
  108.                                 ; special function from Ken Perlin, similar to a sinusoid but faster than Sin/Cos
  109.                                 position# = (y-y1) / (y2-y1)
  110.                                 position = position * position * position * (position * (position * 6 - 15) + 10)
  111.                                
  112.                                 v1# = octave(x1,y1,0) + position * (octave(x1,y2,0) - octave(x1,y1,0))
  113.                                 v2# = octave(x2,y1,0) + position * (octave(x2,y2,0) - octave(x2,y1,0))
  114.                                
  115.                                 position = (x-x1) / (x2-x1)
  116.                                 position = position * position * position * (position * (position * 6 - 15) + 10)
  117.                                
  118.                                 octave(x,y,layer) = v1 + position * (v2 - v1)
  119.                                                                
  120.                                 ; add the new point to perlin array (sum)
  121.                                 perlin(x,y) = perlin(x,y) + octave(x,y,layer) * persistence^layer
  122.                                
  123.                                 ; update minimum and maximum values
  124.                                 If perlin(x,y) > maximum Then maximum = perlin(x,y)
  125.                                 If perlin(x,y) < minimum Then minimum = perlin(x,y)
  126.  
  127.                                
  128.                         Next
  129.                 Next
  130.                
  131.                 frequency = frequency * 2 ; from each octave to the next, multiply the frequency by 2
  132.                 inc = size / frequency ; update the cells size (or step)
  133.  
  134.         Next
  135.        
  136.         ; interpolate noise from 0 to 255
  137.         For x = 0 To size
  138.                 For y = 0 To size
  139.                
  140.                         perlin(x,y) = (perlin(x,y)-minimum) / (maximum-minimum) * 255
  141.                
  142.                 Next
  143.         Next
  144.        
  145.         ; return the time taken to proceed
  146.         Return MilliSecs()-time
  147.        
  148. End Function


Comments : none...

 

SimplePortal 2.3.6 © 2008-2014, SimplePortal