October 17, 2021, 10:23:14

Author Topic: [bmx] Perlin Noise Type by Bladum [ 1+ years ago ]  (Read 535 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
[bmx] Perlin Noise Type by Bladum [ 1+ years ago ]
« on: June 29, 2017, 00:28:41 »
Title : Perlin Noise Type
Author : Bladum
Posted : 1+ years ago

Description : This is a Perlin Noise implementation for 2D maps with linear interpolation and usage of 3 layers = altitude, temperature and humidity.

- different outputs available (as a separate layers or a whole world map)
- one function setup with easy to change parameters


Code :
Code: BlitzMax
  1. '==========================================
  2. '           CLASS                          
  3. '   main perlin noise class              
  4. '==========================================
  5. Type CPerlinNoise
  6.  
  7.         Field sizeX = 640
  8.         Field sizeY = 480
  9.  
  10.         'first random noise table      
  11.         Field noiseArr:Float[,] = New Float[sizeX, sizeY]
  12.         'output table
  13.         Field terrainArr:Float[,] = New Float[sizeX, sizeY]
  14.         'output bitmap
  15.         Field bitmapOut:TPixmap = TPixmap.Create(sizeX, sizeY, PF_RGBA8888)
  16.  
  17.         'frequency, the lower the larger terrains of same level
  18.         Field frequency:Float = 1.0
  19.         'starting amplitude
  20.         Field amplitude:Float = 1.0
  21.         'change of amplitude of next octave
  22.         Field persistance:Float = 0.6
  23.         'number of octaves
  24.         Field octaves = 8
  25.  
  26.         'min and max colors
  27.         Field colMin:CColor = CColor.Create(0, 0, 0)
  28.         Field colMax:CColor = CColor.Create(0, 0, 0)
  29.        
  30.         '==========================================
  31.         '    to init perlin noise values
  32.         '==========================================
  33.         Method ChangeParams(fre:Float, amp:Float, pers:Float, oct)
  34.                
  35.                 frequency = fre
  36.                 amplitude = amp
  37.                 persistance = pers
  38.                 octaves = oct
  39.        
  40.         End Method
  41.        
  42.         '==========================================
  43.         '       single field noise generation
  44.         '=========================================
  45.         Method GetRandomNoise:Float(x:Float, y:Float)
  46.                
  47.                 Local fre:Float = frequency
  48.                 Local amp:Float = amplitude
  49.                 Local finalValue:Float = 0.0
  50.                
  51.                 For Local i = 0 To octaves
  52.                         finalValue = finalValue + LinearFIlterNoise(x * fre, y * fre) * amp
  53.                         fre = fre * 2.0
  54.                         amp = amp * persistance
  55.                 Next
  56.                
  57.                 If(finalValue < - 1.0) finalValue = -1.0
  58.                 If(finalValue > 1.0) finalValue = 1.0
  59.                
  60.                 finalValue = finalValue * 0.5 + 0.5
  61.                
  62.                 Return finalValue
  63.        
  64.         End Method
  65.        
  66.         '==========================================
  67.         '      create output terrain array
  68.         '==========================================
  69.         Method MakeTerrainMap()
  70.                
  71.                 For Local x = 0 To sizeX - 1
  72.                         For Local y = 0 To sizeY - 1
  73.                                 terrainArr[x, y] = GetRandomNoise(x, y)
  74.                         Next
  75.                 Next
  76.        
  77.         End Method
  78.        
  79.         '==========================================
  80.         '   process bitmap to file
  81.         '==========================================
  82.         Method MakeBitmap()
  83.                
  84.                 bitmapOut.ClearPixels($FFFFFFFF)
  85.                        
  86.                 For Local x = 0 To sizeX - 1
  87.                         For Local y = 0 To sizeY - 1
  88.                        
  89.                                 Local val:Float = terrainArr[x, y]
  90.                                 Local R = colMax.R * val + colMin.R * (1 - val)
  91.                                 Local G = colMax.G * val + colMin.G * (1 - val)
  92.                                 Local B = colMax.B * val + colMin.B * (1 - val)
  93.                                                                
  94.                                 SetColor(R, G, B)
  95.                                 bitmapOut.WritePixel(x, y, $FF000000 + (R * $10000 + G * $100 + B))
  96.                                
  97.                         Next
  98.                 Next
  99.        
  100.         End Method
  101.        
  102.         '============================================
  103.         '    perlin noise with linear interpolation
  104.         '===========================================
  105.         Method LinearFilterNoise:Float(x:Float, y:Float)
  106.                
  107.                 Local fractionX:Float = X - Int(X)
  108.                 Local fractionY:Float = Y - Int(Y)
  109.                
  110.                 Local x1 = (Int(x) + sizeX) Mod sizeX
  111.                 Local y1 = (Int(y) + sizeY) Mod sizeY
  112.                 Local x2 = (Int(x) + sizeX - 1) Mod sizeX
  113.                 Local y2 = (Int(y) + sizeY - 1) Mod sizeY
  114.                
  115.                 If(x1 < 0) x1 = x1 + sizeX
  116.                 If(x2 < 0) x2 = x2 + sizeX
  117.                 If(y1 < 0) y1 = y1 + sizeY
  118.                 If(y2 < 0) y2 = y2 + sizeY
  119.                
  120.                 Local finVal:Float = 0
  121.                
  122.                 finVal = finVal + fractionX * fractionY * noiseArr[x1, y1]
  123.                 finVal = finVal + fractionX * (1 - fractionY) * noiseArr[x1, y2]
  124.                 finVal = finVal + (1 - fractionX) * fractionY * noiseArr[x2, y1]
  125.                 finVal = finVal + (1 - fractionX) * (1 - fractionY) * noiseArr[x2, y2]
  126.                
  127.                 Return finVal
  128.        
  129.         End Method
  130.        
  131.         '===========================================
  132.         '     to fill noise array with white noise
  133.         '===========================================
  134.         Method InitNoise()
  135.                
  136.                 noiseArr = New Float[sizeX, sizeY]
  137.                 For Local x = 0 To sizeX - 1
  138.                         For Local y = 0 To sizeY - 1
  139.                                 noiseArr[x, y] = (RndFloat() - 0.5) * 2.0
  140.                         Next
  141.                 Next
  142.                        
  143.         End Method
  144.        
  145.         '===========================================
  146.         Method terrainSinus(p:Float)
  147.                
  148.                 For Local x = 0 To sizeX - 1
  149.                         For Local y = 0 To sizeY - 1
  150.                
  151.                                 Local md:Float = Sin(y * 180 / sizeY) * 2 - 1
  152.                                 terrainArr[x, y] = md * p + terrainArr[x, y] * (1.0 - p)
  153.                                
  154.                         Next
  155.                 Next
  156.        
  157.         End Method
  158.        
  159.         '============================================
  160.         '      start process
  161.         '===========================================
  162.         Function Calculate()
  163.                
  164.                 'create altitude map
  165.                 Local highMap:CPerlinNoise = New CPerlinNoise
  166.                 highMap.ChangeParams(0.02, 0.95, 0.6, 6)
  167.                 highMap.colMin = CColor.Create(0, 120, 0)
  168.                 highMap.colMax = CColor.Create(100, 220, 100)
  169.                 highMap.InitNoise()
  170.                 highMap.MakeTerrainMap()
  171.                 highMap.MakeBitmap()
  172.                 SavePixmapPNG(highMap.bitmapOut, "high1.png")
  173.                
  174.                 'creat humitidy map
  175.                 Local humMap:CPerlinNoise = New CPerlinNoise
  176.                 humMap.ChangeParams(0.04, 0.99, 0.6, 6)
  177.                 humMap.colMin = CColor.Create(0, 0, 20)
  178.                 humMap.colMax = CColor.Create(0, 50, 120)
  179.                 humMap.InitNoise()
  180.                 humMap.MakeTerrainMap()
  181.                 humMap.MakeBitmap()
  182.                 SavePixmapPNG(humMap.bitmapOut, "high2.png")
  183.                
  184.                 'create temperature map
  185.                 Local tempMap:CPerlinNoise = New CPerlinNoise
  186.                 tempMap.ChangeParams(0.04, 0.99, 0.6, 6)
  187.                 tempMap.colMin = CColor.Create(60, 0, 0)
  188.                 tempMap.colMax = CColor.Create(240, 0, 0)
  189.                 tempMap.InitNoise()
  190.                 tempMap.MakeTerrainMap()
  191.                 tempMap.terrainSinus(0.6)
  192.                 tempMap.MakeBitmap()
  193.                 SavePixmapPNG(tempMap.bitmapOut, "high3.png")
  194.                
  195.                 'generate additional world map
  196.                 GenerateWorldMap(highMap, humMap, tempMap)
  197.  
  198.         End Function
  199.        
  200.         '=============================================
  201.         '      generate simple world map
  202.         '=============================================
  203.         Function GenerateWorldMap(highMap:CPerlinNoise,humMap:CPerlinNoise,tempMap:CPerlinNoise)
  204.        
  205.                 Local pixies:TPixmap = TPixmap.Create(tempMap.sizeX, tempMap.sizeY, PF_RGBA8888)
  206.                
  207.                 For Local x = 0 To tempMap.sizeX - 1
  208.                         For Local y = 0 To tempMap.sizeY - 1
  209.                
  210.                                 Local T:Float = tempMap.terrainArr[x, y] * 2 - 1.0
  211.                                 Local H:Float = humMap.terrainArr[x, y] * 2 - 1.0
  212.                                 Local A:Float = highMap.terrainArr[x, y] * 2 - 1.0
  213.                        
  214.                                 Local R, G, B
  215.                                
  216.                                 'water
  217.                                 If(A < 0)
  218.                                         R = 0
  219.                                         G = 60 + A * 60
  220.                                         B = 120 + A * 100
  221.                                 'land
  222.                                 Else
  223.                                
  224.                                         'altitude
  225.                                         R = 60 + A * 180
  226.                                         G = 60 + A * 180
  227.                                         B = 60 + A * 180
  228.                                        
  229.                                         'temperature
  230.                                         If(T >= 0)
  231.                                                 G = G * (1.0 - T * 0.3)
  232.                                                 B = B * (1.0 - T * 0.3)
  233.                                         Else
  234.                                                 R = R * (1.0 + T * 0.3)
  235.                                         End If
  236.                                        
  237.                                         'high humidity
  238.                                         If(H >= 0)
  239.                                                 R = R * (1.0 - H * 0.3)
  240.                                                 B = B * (1.0 - H * 0.3)
  241.                                         Else
  242.                                                 G = G * (1.0 + H * 0.3)
  243.                                         End If
  244.                                
  245.                                 End If
  246.  
  247.                                 'some final quantizations
  248.                                                                
  249.                                 R = (R / 15) * 15
  250.                                 G = (G / 15) * 15
  251.                                 B = (B / 15) * 15
  252.                                
  253.                                
  254.                                 pixies.WritePixel(x, y, $FF000000 + (R * $10000 + G * $100 + B))
  255.                        
  256.                         Next
  257.                 Next
  258.                 SavePixmapPNG(pixies, "worldMap.png")
  259.                
  260.         End Function
  261.        
  262. End Type
  263.  
  264.  
  265.  
  266. '==================================
  267. '                       CLASS                  
  268. 'just simple class to help colors
  269. '==================================
  270. Type CColor
  271.  
  272.         Field R = 0
  273.         Field G = 0
  274.         Field B = 0
  275.        
  276.         '==================================
  277.         Function Create:CColor(r, g, b)
  278.                 Local aa:CColor = New CColor
  279.                
  280.                 aa.R = r
  281.                 aa.g = g
  282.                 aa.b = b
  283.                
  284.                 Return aa
  285.         End Function
  286.        
  287.         '==================================
  288.         Function Process:CColor(f:Long)
  289.                 Local aa:CColor = New CColor
  290.                
  291.                 aa.R = f & $00FF0000
  292.                 aa.R = aa.R / $10000
  293.                 aa.G = f & $0000FF00
  294.                 aa.G = aa.G / $100
  295.                 aa.B = f & $000000FF           
  296.                
  297.                 Return aa
  298.         End Function
  299.        
  300. End Type
  301.  
  302.  
  303. '===========================================================
  304. '===========================================================
  305. '===========================================================
  306. '===========================================================
  307. '===========================================================
  308. '===========================================================
  309.  
  310. 'some simple setup
  311. SetGraphicsDriver(GLMax2DDriver ())
  312. Graphics(640, 480, 0, 60)
  313.        
  314. 'run perlin noise
  315. CPerlinNoise.Calculate()
  316.  
  317. Global img:TImage = LoadImage("worldMap.png")
  318.        
  319. While Not KeyHit(KEY_ESCAPE) And Not AppTerminate()
  320.         Cls()
  321.        
  322.         DrawImage(img,0,0)
  323.  
  324.         Flip(1)
  325. Wend


Comments : none...

 

SimplePortal 2.3.6 © 2008-2014, SimplePortal