Search Unity

How would I layer Perlin Noise?

Discussion in 'Scripting' started by keenanwoodall, Jul 26, 2014.

  1. keenanwoodall

    keenanwoodall

    Joined:
    May 30, 2014
    Posts:
    598
    I've made a script that uses Perlin Noise to move and color a plane of cubes but sometimes it's looks clearly like its scrolling texture. I'd like to layer different Perlin Noises that scroll in different directions to break up the original texture. How would I do this? Here's my current code:
    Code (js):
    1.  
    2. var cubeAmountX : int = 50;
    3. var cubeAmountZ : int = 50;
    4. var seed : int = 0.0;
    5. var cube : GameObject;
    6. var colorSetsScale : boolean;
    7. var heightSetsScale : boolean;
    8. var animateColor : boolean;
    9. var roundHeightToInt : boolean;
    10. var noiseScale : float = 6.5;
    11. var cubeHeight : int = 3;
    12. var animateSpeed : float = 1.0;
    13.  
    14. function Start ()
    15. {
    16.     for (var spawnPositionX = 0; spawnPositionX < cubeAmountX; spawnPositionX++)
    17.     {
    18.         for (var spawnPositionZ = 0; spawnPositionZ < cubeAmountZ; spawnPositionZ++)
    19.         {  
    20.             var makeCube = Instantiate(cube, Vector3(spawnPositionX,0,spawnPositionZ), Quaternion.identity);
    21.             makeCube.transform.parent = this.transform;
    22.         }
    23.     }
    24.     for (var child : Transform in this.transform)
    25.     {
    26.         var height = Mathf.PerlinNoise(child.transform.position.x/noiseScale + (seed * 10), child.transform.position.z/noiseScale + (seed *  10));
    27.         child.renderer.material.color = Color(height,height,height,height);
    28.         if (colorSetsScale)
    29.         {
    30.             child.transform.localScale = Vector3 (height,height,height);
    31.         }
    32.     }
    33.     if (noiseScale <= 0.001)
    34.     {
    35.         noiseScale = 0.0011;
    36.     }
    37. }
    38.  
    39. function Update ()
    40. {
    41.     for (var child : Transform in this.transform)
    42.     {
    43.         var height = Mathf.PerlinNoise(child.transform.position.x/noiseScale, child.transform.position.z/noiseScale);
    44.         if (animateColor)
    45.         {
    46.             child.renderer.material.color = Color(height,height,height,height);
    47.         }
    48.     }
    49.     for (var child : Transform in this.transform)
    50.     {
    51.         height = Mathf.PerlinNoise(Time.time * animateSpeed + (child.transform.position.x/noiseScale) + (seed * 10), Time.time * animateSpeed + (child.transform.position.z/noiseScale) + (seed * 10));
    52.         if (!roundHeightToInt)
    53.         {
    54.             child.transform.position.y = height * cubeHeight + transform.position.y;
    55.         }
    56.         else if (roundHeightToInt)
    57.         {
    58.             child.transform.position.y = Mathf.RoundToInt(height * cubeHeight + transform.position.y);
    59.         }
    60.         if (animateColor)
    61.         {
    62.             child.renderer.material.color = Color(height,height,height,height);
    63.         }
    64.         if (colorSetsScale)
    65.         {
    66.             child.transform.localScale = Vector3 (height,height,height);
    67.             heightSetsScale = false;
    68.         }
    69.         if (heightSetsScale)
    70.         {
    71.             var cubeHeight : float = child.transform.localPosition.y;
    72.             child.transform.localScale = Vector3 (cubeHeight, cubeHeight, cubeHeight);
    73.             colorSetsScale = false;
    74.         }
    75.     }
    76. }
     
  2. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194
    Maybe a screenshot or video would help us understand what you are doing better.

    You could just duplicate this effector and make a version of the script that works on a different axis (change the y to x or z).

    Or you could use the Random.OnUnitSphere to move the cubes in a completely random direction.
     
  3. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    Add a second perlin value, using a different scale, and different Z parameter
    Between lines 26&27 add something like
    height += Mathf.PerlinNoise(child.transform.position.x/(noiseScale*2) + (seed * 10), child.transform.position.z/(noiseScale*2) + (seed * 10), seed);
    Code (CSharp):
    1. height += Mathf.PerlinNoise(child.transform.position.x/(noiseScale*2) + (seed * 10), child.transform.position.z/(noiseScale*2) + (seed *  10), seed);
     
  4. keenanwoodall

    keenanwoodall

    Joined:
    May 30, 2014
    Posts:
    598
    Thanks, I'll try it out
     
  5. keenanwoodall

    keenanwoodall

    Joined:
    May 30, 2014
    Posts:
    598
    Here's a video of what I had before the post. Do you get what I was trying to explain?
     
  6. keenanwoodall

    keenanwoodall

    Joined:
    May 30, 2014
    Posts:
    598
    Here's the project with a second noise channel
     
  7. keenanwoodall

    keenanwoodall

    Joined:
    May 30, 2014
    Posts:
    598
    And here's the code:
    Code (js):
    1.  
    2. var cubeAmountX : int = 50;
    3. var cubeAmountZ : int = 50;
    4. var seed : int = 0.0;
    5. var seed2 : int = 0.0;
    6. var cube : GameObject;
    7. var colorSetsScale : boolean;
    8. var heightSetsScale : boolean;
    9. var sizeDivider : float = 2.0;
    10. var animateColor : boolean;
    11. var roundHeightToInt : boolean;
    12. var noiseScale : float = 6.5;
    13. var noiseScale2 : float = 6.5;
    14. var cubeHeight : float = 3;
    15. var cubeHeight2 : float = 3;
    16. var animateSpeed : float = 0.5;
    17. var animateSpeed2 : float = 1.0;
    18. private var finalHeight : float;
    19.  
    20. function Start ()
    21. {
    22.     for (var spawnPositionX = 0; spawnPositionX < cubeAmountX; spawnPositionX++)
    23.     {
    24.         for (var spawnPositionZ = 0; spawnPositionZ < cubeAmountZ; spawnPositionZ++)
    25.         {  
    26.             var makeCube = Instantiate(cube, Vector3(spawnPositionX,0,spawnPositionZ), Quaternion.identity);
    27.             makeCube.transform.parent = this.transform;
    28.         }
    29.     }
    30.     for (var child : Transform in this.transform)
    31.     {
    32.         if (noiseScale <= 0.001)
    33.         {
    34.             noiseScale = 0.0011;
    35.         }
    36.         var height = Mathf.PerlinNoise(child.transform.position.x/noiseScale + (seed * 10), child.transform.position.z/noiseScale + (seed *  10));
    37.         var height2 = Mathf.PerlinNoise(child.transform.position.x/noiseScale2 + (seed2 * -10), child.transform.position.z/noiseScale2 + (seed2 *  -10));
    38.         height *= cubeHeight;
    39.         height2 *= cubeHeight2;
    40.         finalHeight = height + height2;
    41.         if (animateColor)
    42.         {
    43.             child.renderer.material.color = Color(finalHeight,finalHeight,finalHeight,finalHeight);
    44.         }
    45.         if (colorSetsScale)
    46.         {
    47.             if (sizeDivider <= 0.0)
    48.             {
    49.                 sizeDivider = 0.001;
    50.             }
    51.             child.transform.localScale = Vector3 (finalHeight,finalHeight,finalHeight);
    52.         }
    53.     }
    54. }
    55.  
    56. function Update ()
    57. {
    58.     for (var child : Transform in this.transform)
    59.     {
    60.         var height = Mathf.PerlinNoise(child.transform.position.x/noiseScale, child.transform.position.z/noiseScale);
    61.         var height2 = Mathf.PerlinNoise(child.transform.position.x/noiseScale2 + (seed2 * -10), child.transform.position.z/noiseScale2 + (seed2 *  -10));
    62.         height *= cubeHeight;
    63.         height2 *= cubeHeight2;
    64.         var finalHeight = height + height2;
    65.         if (animateColor)
    66.         {
    67.             child.renderer.material.color = Color(finalHeight,finalHeight,finalHeight,finalHeight);
    68.         }
    69.     }
    70.     for (var child : Transform in this.transform)
    71.     {
    72.         height = Mathf.PerlinNoise(Time.time * animateSpeed + (child.transform.position.x/noiseScale) + (seed * 10), Time.time * animateSpeed + (child.transform.position.z/noiseScale) + (seed * 10));
    73.         height2 = Mathf.PerlinNoise(Time.time * animateSpeed2 + child.transform.position.x/noiseScale2 + (seed2 * -10),Time.time * animateSpeed2 + child.transform.position.z/noiseScale2 + (seed2 *  -10));
    74.         height *= cubeHeight;
    75.         height2 *= cubeHeight2;
    76.         finalHeight = height + height2;
    77.         if (!roundHeightToInt)
    78.         {
    79.             child.transform.position.y = finalHeight + transform.position.y;
    80.         }
    81.         else if (roundHeightToInt)
    82.         {
    83.             child.transform.position.y = Mathf.RoundToInt(finalHeight * cubeHeight + transform.position.y);
    84.         }
    85.         if (animateColor)
    86.         {
    87.             child.renderer.material.color = Color(finalHeight,finalHeight,finalHeight,finalHeight);
    88.         }
    89.         if (colorSetsScale)
    90.         {
    91.             if (sizeDivider <= 0.0)
    92.             {
    93.                 sizeDivider = 1;
    94.             }
    95.             child.transform.localScale = Vector3 (finalHeight,finalHeight,finalHeight);
    96.             heightSetsScale = false;
    97.         }
    98.         if (heightSetsScale)
    99.         {
    100.             if (sizeDivider <= 0.0)
    101.             {
    102.                 sizeDivider = 1;
    103.             }
    104.             var cubeHeight : float = child.transform.localPosition.y;
    105.             child.transform.localScale = Vector3 (cubeHeight/sizeDivider, cubeHeight/sizeDivider, cubeHeight/sizeDivider);
    106.             colorSetsScale = false;
    107.         }
    108.         if (!heightSetsScale && !colorSetsScale)
    109.         {
    110.             child.transform.localScale = Vector3 (1,1,1);
    111.         }
    112.     }
    113. }
     
  8. keenanwoodall

    keenanwoodall

    Joined:
    May 30, 2014
    Posts:
    598
    Does anyone know how I could apply this to a plane. The vertices of the plane would act as the cubes in this example
     
  9. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194
  10. keenanwoodall

    keenanwoodall

    Joined:
    May 30, 2014
    Posts:
    598
  11. keenanwoodall

    keenanwoodall

    Joined:
    May 30, 2014
    Posts:
    598
  12. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    HI again, I misunderstood your initial post and what you wanted.
    Going back to your first posted code, on line 51, instead of using Time.time to modify the X and Y parameters of the perlin noise, use it in the Z only, to stop it looking like it's scrolling
    Code (CSharp):
    1. //Old
    2.         height = Mathf.PerlinNoise(Time.time * animateSpeed + (child.transform.position.x/noiseScale) + (seed * 10), Time.time * animateSpeed + (child.transform.position.z/noiseScale) + (seed * 10));
    3. //New
    4.         height = Mathf.PerlinNoise((child.transform.position.x/noiseScale) + (seed * 10), (child.transform.position.z/noiseScale) + (seed * 10), Time.time * animateSpeed);
     
  13. keenanwoodall

    keenanwoodall

    Joined:
    May 30, 2014
    Posts:
    598
    that would only move the cubes forward and backward though. Right? Right now I have layered noises and that breaks it up nicely
     
  14. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    Nah, just providing a third value (z) to mathf.perlin just makes it output something different, which you then provide only to "height", wont actually move the cubes in the z axis
     
  15. keenanwoodall

    keenanwoodall

    Joined:
    May 30, 2014
    Posts:
    598
    Oh, I see. I though Mathf.PerlinNoise on took two arguments though. Where does it get a z value from?
     
  16. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    Whatever you want.
    Giving it 3 values just makes it sample for 3d perlin instead of 2d
     
  17. keenanwoodall

    keenanwoodall

    Joined:
    May 30, 2014
    Posts:
    598
    how does it figure out 3d perlin? that sounds awesome!
     
  18. keenanwoodall

    keenanwoodall

    Joined:
    May 30, 2014
    Posts:
    598
    I gave it 3 values and I got an error, because it only takes 2 arguments
     
  19. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    Huh, Guess i was thinking about my own implementation then. Oops