Search Unity

Am a bit stuck - Voxel Terrain Generation.

Discussion in 'Scripting' started by Zero_Xue, Sep 27, 2017.

  1. Zero_Xue

    Zero_Xue

    Joined:
    Apr 18, 2012
    Posts:
    126
    Hey am a tad bit stuck atm and have been smashing my head against the desk for serveral hours now until finally ive reached the point were its time to ask for help - Ive started looking at Random Terrain Generation and decided to use a Voxel based system and it all works nicely accept for 1 issue, when it came around to adding Biomes and such, for example a change from Flatlands to a Mountain like biomes this is were am incountering my issue -

    any here the code am using to generate my chunks,

    Code (CSharp):
    1.     public void CreateChunk()
    2.     {
    3.         int ChunksCreated = 0;
    4.         for (int cx = 0; cx < ChunksToSpawn / 2; cx++)
    5.         {
    6.             for (int cz = 0; cz < ChunksToSpawn / 2; cz++)
    7.             {
    8.                 ChunksCreated++;
    9.                 GameObject Chunk = new GameObject();
    10.                 Chunk.transform.name = "Chunk " + ChunksCreated;
    11.                 Chunk.transform.position = new Vector3(0 + (ChunkSize * cx), 0, 0 + (ChunkSize * cz));
    12.                 Chunk NewChunk = new Chunk(Chunk.transform.position, ChunkSize);
    13.                 for (int x = 0; x < ChunkSize; x++)
    14.                 {
    15.                     for (int z = 0; z < ChunkSize; z++)
    16.                     {
    17.                         float xCoord = ((float)Chunk.transform.position.x + (float)x) / (float)ChunkSize + (float)Seed;
    18.                         float yCoord = ((float)Chunk.transform.position.z + (float)z) / (float)ChunkSize + (float)Seed;
    19.                         SimplexNoiseGenerator simplexNoise = new SimplexNoiseGenerator(Seed.ToString());
    20.  
    21.                         int BiomeFrequency = 100;
    22.                         int BiomeNoise = 2;
    23.                         float BiomeMap = simplexNoise.coherentNoise(xCoord, 0, yCoord, 2, BiomeFrequency, 0.5f, BiomeNoise, 1.0f);
    24.                         //Debug.Log(BiomeMap);
    25.                         int Height;
    26.                         Vector3 VoxelPos = Vector3.negativeInfinity;
    27.  
    28.                         if (BiomeMap < 0)
    29.                         {
    30.                             BiomeMap = BiomeMap * -1;
    31.                         }
    32.  
    33.  
    34.                         if (BiomeMap < 0.04f) // High Mountains
    35.                         {
    36.                             int Frequency = 200;
    37.                             int Noise = 5;
    38.                             int MinHeight = 1;
    39.                             int MaxHeight = 20;
    40.                             Height = Mathf.RoundToInt(simplexNoise.coherentNoise(xCoord, 0, yCoord, 4, Frequency, MinHeight, Noise, MaxHeight) / 128);
    41.                         }
    42.                         else // Rolling Planes
    43.                         {
    44.                             int Frequency = 200;
    45.                             int Noise = 4;
    46.                             int MinHeight = 1;
    47.                             int MaxHeight = 10;
    48.                             Height =  Mathf.RoundToInt(simplexNoise.coherentNoise(xCoord, 0, yCoord, 4, Frequency, MinHeight, Noise, MaxHeight) / 128);
    49.                         }
    50.  
    51.                         if (Height < 0)
    52.                         {
    53.                             Height = Height * -1;
    54.                         }
    55.  
    56.                         VoxelPos = new Vector3(x, Height, z);
    57.                         NewChunk.Blocks[(int)VoxelPos.x, (int)VoxelPos.y, (int)VoxelPos.z] = 1;
    58.  
    59.                         //Generate Sub Surface
    60.                         for (int i = 0; i < Height; i++)
    61.                         {
    62.                             Vector3 SubVoxelPos = new Vector3(x, i, z);
    63.                             NewChunk.Blocks[(int)SubVoxelPos.x, (int)SubVoxelPos.y, (int)SubVoxelPos.z] = 1;
    64.                         }
    65.  
    66.                         //Worm System
    67.  
    68.                     }
    69.                 }
    70.  
    71.                 Chunk.AddComponent<MeshFilter>().mesh = CreateChunkMesh(NewChunk);
    72.                 Chunk.AddComponent<MeshRenderer>().material.mainTexture = DebugMat;
    73.                 Chunk.transform.parent = this.transform;
    74.                 GetComponent<ChunkManager>().AddNewChunk(NewChunk);
    75.             }
    76.         }
    As you can see am using Simplex Noise to generate a Biome Map and then another Simplex noise to generate a height map for that biome.







    Am calling it Hard Walling since thats what it looks like and its the hard wall i keep running into XD

    if you have any ideas on how to solve this issue i would gladly accept any help XD

    [EDIT] i know about the shadow issues, but there easily solved =)
     
  2. makeshiftwings

    makeshiftwings

    Joined:
    May 28, 2011
    Posts:
    3,350
    You need to create a border region between the two biomes where you blend the height maps together. Instead of having a hard cutoff at 0.04 on the biome map to choose between mountains or plains, you could do a hard cutoff at 0.03 and below for mountains, 0.05 and up for plains, but then 0.03 - 0.05 will be a blend. To blend, you need to convert that range of 0.03-0.05 into a percentage that tells you how mountainous it is (and then 100% minus that value would be how plainsy it is). Then you use the height noise maps for BOTH mountains and plains, multiply the mountain output by the mountain percentage, and multiply the plains output by the plains percentage, and add those two values together. That will give you a smooth blend between the two. Something like:

    Code (csharp):
    1. if (BiomeMap > 0.03f && BiomeMap < 0.05f) {
    2.    float percentagePlains = (BiomeMap - 0.03f) / 0.02f;
    3.    float percentageMountains = 1f - percentagePlains;
    4.  
    5.    //do both noise functions here....
    6.    float heightPlains = plainsSimplexNoise.whatever...;
    7.    float heightMountains = mountainsSimplexNoise.whatever...;
    8.    float totalHeight = (percentagePlains * heightPlains) + (percentageMountains * heightMountains);
    9. }
     
    Last edited: Sep 27, 2017
  3. Zero_Xue

    Zero_Xue

    Joined:
    Apr 18, 2012
    Posts:
    126
    thanking you, works spot on =)
     
    makeshiftwings likes this.