Search Unity

Perlin Noise, Repeated Values?

Discussion in 'Scripting' started by McFadge, May 26, 2014.

  1. McFadge

    McFadge

    Joined:
    Jun 19, 2011
    Posts:
    18
    Hi all,

    I've been experimenting with Perlin Noise, using it to manipulate a tentacle, and I came across what seems to me a strange occurrence. Every once in a while, the noise function starts returning the same values for a period of time. I've added a video of what I'm seeing below:



    You can see the tentacle pause numerous times in the video, for example 0:17, 0:33, 0:51, 1:01, and more

    I've also included my code:

    Code (csharp):
    1. public GameObject[] Segments;
    2. float noiseSeed = 0f;
    3. public float noiseIncrement = 0.5f;
    4. public float noiseSeparation = 0.1f;
    5. public float rotationScale = 150;
    6.  
    7. void Update () {
    8.     for (int i = 0; i < Segments.Length; i++){
    9.         float rotation = (Mathf.PerlinNoise(noiseSeed - (noiseSeparation * i), 0) * rotationScale) - rotationScale * 0.5f;
    10.         Segments[i].transform.localRotation = Quaternion.Euler(new Vector3(0, 0, rotation));
    11.     }
    12.     noiseSeed += noiseIncrement * Time.deltaTime;
    13.     print ("Input: (" + noiseSeed + ", 0)");
    14.     print ("Output: " + Mathf.PerlinNoise(noiseSeed, 0));
    15. }
    Each tentacle has a child tentacle which has a child tentacle etc, etc. and these are all in the Segments array.

    I've also included some console output I get from my print statements when this 'bug' occurs. The repeated values start at line 220:

    http://pastebin.com/5UsvK0Lk

    Is what I'm seeing strange, or just something that regularly occurs with Perlin noise? It seems a bit odd to me for so many consistent values to come about for an extended period of time.
     
  2. McFadge

    McFadge

    Joined:
    Jun 19, 2011
    Posts:
    18
    Sorry to bump, but does anybody have any ideas? There's workarounds I could incorporate, like including a number of noise values and averaging them, but I'm more curious if I'm lacking some kind of understanding here.
     
  3. 3agle

    3agle

    Joined:
    Jul 9, 2012
    Posts:
    508
    This is quite odd, from first look I couldn't see what would be causing this.

    Looking into the issue I am speculating (I don't know much about Perlin), that the results you are getting are correct, but not the intended effect. If you observe a Perlin noise sample (such as on the wiki page), there are many adjacent areas that are of the same value, it could be that you are sampling such an area.

    It's worth noting that you don't 'seed' Perlin in the same way you would an RNG, the intent of Perlin isn't to generate random results, but natural ones. I would suggest implementing a 'seed' in a similar way as the documentation (http://docs.unity3d.com/ScriptReference/Mathf.PerlinNoise.html) as a test to see if your issue is sampling points that are too close. Using Time.time will give a more spread out sample than your increment which is by smaller amounts. Alternatively multiplying your seed to give a more spread out value.

    Imagine you are taking samples of 'distance from sea level' every 10 meters you walk, and you eventually get to a large lake(assuming the lake is at sea level). If you look at the raw data, it's going to look like something is wrong, but in actual fact you are sampling a large area that has the same data. Take the samples every 100 meters and you'd get better results.

    I don't have an in-depth knowledge of Perlin, or noise in general, so take what I say as you will. It is generally just my initial thoughts on what might be happening, as such, I could be completely wrong.
     
  4. _met44

    _met44

    Joined:
    Jun 1, 2013
    Posts:
    633
    3agle is right, try to change both your noiseIncrement and noiseSeparation parameters you should see a wide range of result depending on how you configure your script.

    You have a small step at the moment, and the deltaTime is reducing it ever further. It seems normal that your values stay on "cliffs" for a while.
     
  5. McFadge

    McFadge

    Joined:
    Jun 19, 2011
    Posts:
    18
    Thanks for the replies.

    I too don't know much about Perlin noise, but came to a similar conclusion as you both. At the time I found it strange to be running into these cases so frequently and for reasonable periods of time, but on reflection it definitely seems like the cause. I imagine part of this is when I think of Perlin noise I think of the image below, so I found it strange to run into so many consistent values, but looking at the image from the documentation it's much more obvious.



    One way, as suggested, to overcome this is to increase the steps between my samples. However, I believe this will produce more sporadic motion as the values will be less 'related', which I don't think I want.

    Ah well, thank you both for the input. At least I can feel satisfied with this answer, and now I just need to find my solution :)
     
  6. _met44

    _met44

    Joined:
    Jun 1, 2013
    Posts:
    633
    You should definetely try to fine tune your script to see how it goes, but if falls there, there are many alternatives to perlin.

    Give a try at the Turbulence Library on the asset store, maybe you'll find what suits your needs best.

    And also a great blog about noises here : http://briansharpe.wordpress.com/ (found on the Turbulence post if I recall correctly)
     
  7. Pawl

    Pawl

    Joined:
    Jun 23, 2013
    Posts:
    113
    Alright, I ran into this exact issue, and like @McFadge said, increasing the sample steps will produce more sporadic motion, which is probably not what you want.

    By simply replacing all your calls with SimplexNoise, the problem should go away.

    Code (CSharp):
    1. float f = Mathf.PerlinNoise(x, y)  // Before
    2. float f = SimplexNoise.Noise(x, y) // After
    3. f = (f + 1.0f) / 2.0f; // Convert [-1,1] to [0,1]
    SimplexNoise can be downloaded from the Unity wiki (one of the few times I can recommend something from there... usually those scripts are convoluted and riddled with bugs).

    http://wiki.unity3d.com/index.php/Tileable_Noise
     
    erebel55 likes this.