Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Help with understanding perlin noise and implementing modifiers

Discussion in 'Scripting' started by AlucardJay, Apr 5, 2013.

  1. AlucardJay

    AlucardJay

    Joined:
    May 28, 2012
    Posts:
    328
    I am looking for help in understanding how to generate perlin noise based on several different parameters.
    I have successfully generated terrain previously by gathering two perlin points (low octave sample and high octave sample) and combining them. Now I wish to do this type of thing :

    $fullnoisediagram.png

    that is : creating different 'modules' with varying outputs of perlin, and then somehow blending them together.

    I have been reading (among many other pages) :

    * http://libnoise.sourceforge.net/tutorials/tutorial5.html
    * http://stackoverflow.com/questions/4753055/perlin-noise-generation-for-terrain

    ... and my head hurts. I cannot see how to factor in these variables :

    Code (csharp):
    1. var persistence : float = 1.0;
    2. var frequency : float = 1.0;
    3. var amplitude : float = 1.0;
    4. var octaves : int = 1;
    5. var randomSeed : int = 1;
    From the libnoise tutorial :

    * http://libnoise.sourceforge.net/glossary/index.html#frequency
    * http://libnoise.sourceforge.net/glossary/index.html#octave

    I really cannot see the difference between octave and frequency, nor how to implement these two factors.

    Amplitude I have concluded is just a percentage of the returned perlin value.

    And with Persistence, well I just do not understand where to implement that at all.

    So I tried some experimentation :

    Code (csharp):
    1. #pragma strict
    2.  
    3. public var terrain : Terrain;
    4. var terrainData : TerrainData;
    5.  
    6. var heightmapWidth : int;
    7. var heightmapHeight : int;
    8.  
    9. var persistence : float = 1.0;
    10. var frequency : float = 1.0;
    11. var amplitude : float = 1.0;
    12. var octaves : int = 1;
    13. var randomSeed : int = 1;
    14.  
    15. function Start()
    16. {
    17.     GetTerrainData();
    18. }
    19.  
    20. function Update()
    21. {
    22.     if ( Input.GetMouseButtonDown(0) )
    23.     {
    24.         GeneratePerlinTerrain();
    25.     }
    26. }
    27.  
    28. function GeneratePerlinTerrain()
    29. {
    30.     var heightmapData : float[,] = terrainData.GetHeights( 0, 0, heightmapWidth, heightmapHeight );
    31.    
    32.     for ( var y : int = 0; y < heightmapHeight; y ++ )
    33.     {
    34.         for ( var x : int = 0; x < heightmapWidth; x ++ )
    35.         {
    36.             // calculate percentage of octave
    37.             var pOctave : Vector2 = new Vector2( (parseFloat( octaves ) / heightmapWidth) * x, (parseFloat( octaves ) / heightmapHeight) * y );
    38.            
    39.             // modify with frequency
    40.             pOctave *= frequency;
    41.            
    42.             // read perlin
    43.             var newHeight : float = Mathf.PerlinNoise( pOctave.x, pOctave.y );
    44.            
    45.             // restrict by amplitude
    46.             newHeight *= amplitude;
    47.            
    48.             // apply to height at position x,y
    49.             heightmapData[y,x] = newHeight;
    50.         }
    51.     }
    52.    
    53.     terrainData.SetHeights( 0, 0, heightmapData );
    54. }
    55.  
    56. function GetTerrainData()
    57. {
    58.     if ( !terrain )
    59.     {
    60.         terrain = Terrain.activeTerrain;
    61.     }
    62.    
    63.     terrainData = terrain.terrainData;
    64.    
    65.     heightmapWidth = terrain.terrainData.heightmapWidth;
    66.     heightmapHeight = terrain.terrainData.heightmapHeight;
    67. }
    But all this is doing is creating a basic perlin output. Is there anyone here who would like to explain and help me understand how I can use all these modifiers before or after reading a perlin noise sample?

    You have my thanks just for reading this =]
     
  2. aubergine

    aubergine

    Joined:
    Sep 12, 2009
    Posts:
    2,862
    Mathf perlinnoise and libnoise are completely different stuff.
    Try my Libnoise port with visual frontend for textures, terrain and normal maps with artificial lights and tutorials, its on a 50% discount now.
     
  3. scrawk

    scrawk

    Joined:
    Nov 22, 2012
    Posts:
    804
    Hi. Your really not using the perlin noise as it intended to be used.

    This is how I normally create fractal noise. Dont worry about persistance for the time being. Its just the rate at which the amp changes. This is quite a simple version but is easy to follow. The noise value will be in the range of 0 to 1 so you may need to scale it up to what height you want

    I also have a perlin noise plug-in found here

    Code (csharp):
    1. var octaves : int = 8;
    2. var frq : float = 100.0;
    3. var amp : float 1.0;
    4.  
    5. for ( var y : int = 0; y < heightmapHeight; y ++ )
    6. {
    7.  
    8.  for ( var x : int = 0; x < heightmapWidth; x ++ )
    9.  {
    10.  
    11. var noise : float = 0.0;
    12. var gain : float = 1.0;
    13.  for(var i : int = 0; i < octaves; i++)
    14. {
    15.  
    16. noise +=  Mathf.PerlinNoise(x*gain/frq, y*gain/frq) * amp/gain;
    17. gain *= 2.0;
    18.  
    19. }
    20.  
    21. heightmapData[y,x] = noise;
    22.  
    23. }
    24. }
     
    Last edited: Apr 6, 2013
  4. AlucardJay

    AlucardJay

    Joined:
    May 28, 2012
    Posts:
    328
    aubergine : Thanks, but I'm not really interested in a product. For me its about understanding the principles and applying them for myself. I appreciate your response, and I understand there is a clear difference between LibNoise and PerlinNoise. My main interest in LibNoise was how they combined the data sets, but I'm now working on my own code that will blend between data sets.

    scrawk : wow, you have a most excellent blog there. I shall indeed take my time and work through each of those subjects, and do my best to absorb the information you have provided. I have worked a bit with perlin, but in a basic limited capacity, just like UVs, merely setting the sample size and the offset. Just like my answer here on combining 2 samples for random terrain : http://answers.unity3d.com/questions/412624/how-can-i-make-my-algorithm-make-cloudy-heightmaps.html . I wanted to somehow make perlin more flexible, to give a much larger range of outputs like what I reading about in LibNoise with all those parameters. But I realize I have to learn about other things like fractal and browning. I actually just did a conversion of the robot frog hill method, that gives some great results too. Many thanks again for advising me of your blog, all the best.