Search Unity

Question Problems with adding elevation to perlin noise

Discussion in 'Scripting' started by FederalRazer89, Jul 1, 2020.

  1. FederalRazer89

    FederalRazer89

    Joined:
    Nov 24, 2019
    Posts:
    83
    I have a script that generat terrain based on perlin noise, but i get some circular edges on the added elevations that i intend to have look like a continent or island, would like to have a smoother transition.
    upload_2020-7-1_4-41-14.png

    The circular edges comes from the way i create elevations which i do by measure the distance from the center of each landmass center position and try to gradually increase elevation. These islands can consist of several tiles, which is created on multiple threads so that kind of makes it a bit harder to fix. I think i have a solution but that will create a additional pass to smooth it out, but that will add more cpu time and might also conflict with some additional features that i intend to add.


    I would be grateful for any suggestions

    Script:
    Code (CSharp):
    1.  
    2. public class TerrainBasicGeology
    3. {
    4.  
    5.  
    6.     public static float CreatingY(int xPos, int zPos, int perlinNoiseScale, int perlinNoiseheigh, TileData tileData)
    7.     {
    8.  
    9.         float vertexHeight = 1;
    10.         float vertexAccumulate = 1;
    11.         float vertexStreach = 0.01f;
    12.         float vertexNoise = Mathf.PerlinNoise((xPos * vertexStreach * perlinNoiseScale), (zPos * vertexStreach * perlinNoiseScale));
    13.         float modifierAmount = 0;
    14.         int clampHeight = 150;
    15.  
    16.  
    17.         for (int i = 0; i < tileData.continentCenter.Length; i++)
    18.         {
    19.  
    20.             float distanceLandMassCenter = Vector3.Distance(tileData.continentCenter[i], new Vector3(xPos, 0, zPos));
    21.             if (distanceLandMassCenter < 200)
    22.             {
    23.  
    24.                 if (distanceLandMassCenter < clampHeight) { distanceLandMassCenter = clampHeight; };
    25.                 float tempScale = 201 / distanceLandMassCenter;
    26.                 vertexAccumulate = vertexAccumulate * tempScale;
    27.                 modifierAmount++;
    28.             }
    29.             for (int j = 0; j < tileData.continentFiller.Length; j++)
    30.             {
    31.  
    32.                 float distanceLandMassModifier = Vector3.Distance(tileData.continentFiller[j], new Vector3(xPos, 0, zPos));
    33.                 if (distanceLandMassModifier < 200)
    34.                 {
    35.  
    36.                     if (distanceLandMassModifier < clampHeight) { distanceLandMassModifier = clampHeight; };
    37.                     float tempScale = 201 / distanceLandMassModifier;
    38.                     vertexAccumulate = vertexAccumulate * tempScale;
    39.                     modifierAmount++;
    40.                 }
    41.  
    42.             }
    43.  
    44.         }
    45.         // vertexHeight = vertexHeight * ( 1 * tempScale * (distanceLandMassModifier / 201));
    46.  
    47.         float vertexMacroDetail = 2f * (Mathf.PerlinNoise((xPos * vertexStreach), (zPos * vertexStreach))) * vertexNoise;
    48.         float vertexMacroDetail2 = 5f * (Mathf.PerlinNoise((xPos * 0.001f), (zPos * 0.001f))) * vertexNoise;
    49.  
    50.  
    51.         if (modifierAmount == 0)
    52.         {
    53.             vertexHeight = vertexHeight * vertexNoise * (vertexMacroDetail) * perlinNoiseheigh;
    54.         }
    55.         else
    56.         {
    57.             vertexHeight = 5f * ((vertexHeight) * vertexNoise * (vertexMacroDetail2) * perlinNoiseheigh * vertexAccumulate);
    58.  
    59.         }
    60.  
    61.  
    62.         return vertexHeight;
    63.  
    64.     }
    65. }
    Calling CreatingY:
    Code (CSharp):
    1.      
    2. for (int i = 0, z = 0; z <= tileMeshSize; z++)
    3.         {
    4.             for (int x = 0; x <= tileMeshSize; x++)
    5.             {
    6.                 float y = TerrainBasicGeology.CreatingY(x + tileData.xStartPos, z + tileData.zStartPos, perlinNoiseScale, perlinNoiseheigh, tileData);
    7.                 tileData.vertices[i] = new Vector3((x * tileSizeScaleModifier), (y * tileSizeScaleModifier), (z * tileSizeScaleModifier));
    8.                 i++;
    9.             }
    10.         }


    Edit: Tried to add a function that try to smooth the terrain, but it fails to do anything. Troubleshooting but here is the code if someone is interested.
    Code (CSharp):
    1.    
    2. public static Vector3[] SmoothingTile(TileData tileData, int tileMeshSize, int tileSizeScaleModifier, int perlinNoiseScale, int perlinNoiseheigh)
    3.     {
    4.         Vector3[] tempVectors = new Vector3[(tileMeshSize + 1) * (tileMeshSize + 1)];
    5.  
    6.  
    7.         for (int i = 0, z = 0; z <= tileMeshSize; z++)
    8.         {
    9.             for (int x = 0; x <= tileMeshSize; x++)
    10.             {
    11.                 Vector3[] tempCheckRadius = new Vector3[tileMeshSize];
    12.                
    13.                
    14.                 for (int j = 0, k = 0, zCheck = 0; zCheck <= tileMeshSize; zCheck++)
    15.                 {
    16.                     for (int xCheck = 0; xCheck <= tileMeshSize; xCheck++)
    17.                     {
    18.                         float checkSmoothDistance = Vector3.Distance(tileData.vertices[i], tileData.vertices[j]);
    19.                         if (checkSmoothDistance < 10)
    20.                         {
    21.                             //?
    22.                             tempCheckRadius[k] = tileData.vertices[j];
    23.                             k++;
    24.                         }
    25.                        
    26.                         j++;
    27.                     }
    28.                 }
    29.  
    30.                 float averageVector = 0;
    31.                 for (int c = 0; c < tempCheckRadius.Length; c++)
    32.                 {
    33.                     averageVector = averageVector + tempCheckRadius[c].y;
    34.                 }
    35.                 Vector3 newVectorY = new Vector3(tileData.vertices[i].x, averageVector, tileData.vertices[i].z);
    36.  
    37.  
    38.                 if ((x != 0) || (x != tileMeshSize) || (z != 0) || (z != tileMeshSize))
    39.                 {
    40.                     tempVectors[i] = newVectorY;
    41.                 }
    42.                 else
    43.                 {
    44.                     tempVectors[i] = tileData.vertices[i];
    45.                 }
    46.                 i++;
    47.             }
    48.         }
    49.         return tempVectors;
    50.     }
    51.  
     
    Last edited: Jul 3, 2020