• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by udk_lethal_d0se · Oct 15, 2015 at 02:18 PM · terrainterraindataperlin noisetilingseed

How can I correctly offset seeded perlin noise over multiple terrains?

Hello,

I have been creating a randomly seeded world using a single terrain and perlin noise lately, which works as intended. However, I'm attempting to create a new terrain next to the original with an offset applied to the original seeded noise, which in theory should create a seamless tile next to the original but I'm having no luck.

I have a test project where I'd found the number 9.98 to be a working offset by trial and error however it's not working for my current terrain(s).

Here's a screenshot of the result I'm getting, the darker patches indicate areas below water.

Problematic terrain.

As you can see, it's not right. The far-left terrain is the initial and is created with no offset and the seed, the right is created using the seed plus and offset of 9.98. Each terrain has a script attached to it, ready to set neighbours; the script also contains the offset information used upon world generation. See below.

Neighbour script.

Finally, each terrain is a child of a single object controlling world generation, the section relating to manipulating terrain data can be seen below.

IEnumerator CreateLandscape() { for (int i = 0; i < transform.childCount; i++) { TerrainData tData = transform.GetChild(i).GetComponent ().terrainData; Neighbour tNeighbour = transform.GetChild(i).GetComponent (); Vector2 tOffset = new Vector2(tNeighbour.OffsetX, tNeighbour.OffsetY);

         loadingMessage = string.Format("Terrain_{0}: {1}", i, "Creating terrain heights, using random seed.");
         yield return StartCoroutine(CreateTerrain(tData, tOffset));
         yield return new WaitForSeconds(0.5f);
         
         if (i == 0)
         {
             for (int w = 0; w < tData.heightmapWidth; w++)
             {
                 for (int h = 0; h < tData.heightmapHeight; h++)
                 {
                     float cHeight = tData.GetHeight(w, h);                
                     
                     if (cHeight < terrainLowestElevation)
                     {
                         terrainLowestElevation = cHeight;
                     }
                 }
             }
             
             terrainWaterLevel = terrainLowestElevation + defaultWaterOffset;
         }
         
         loadingMessage = string.Format("Terrain_{0}: {1}", i, "Painting terrain based on global water level.");
         yield return StartCoroutine(PaintTerrain(tData));
         yield return new WaitForSeconds(0.5f);
         
         //yield return StartCoroutine(CreateFoliage(tData, transform.GetChild(i), i));
         //yield return new WaitForSeconds(0.5f);
         
         yield return new WaitForSeconds(0.5f);
     }
     
     loadingMessage = string.Format("Environment: {0}", "Setting terrain neighbours, and removing seams.");
     yield return StartCoroutine(SetTerrainNeighbours());
     
     loadingMessage = string.Format("Environment: {0}", "Positioning global water source.");
     TerrainData wData = GameObject.Find("Terrain_M").GetComponent<Terrain>().terrainData;
     yield return StartCoroutine(PositionWater(wData));
     
     yield return StartCoroutine(SetTerrainNeighbours());
     
     loadingMessage = string.Format("Environment: {0}", "Positioning the player.");
     yield return StartCoroutine(PositionPlayer());        
     yield return new WaitForSeconds(0.5f);
     
     hasLoaded = true;
     
     yield return null;
 }
 
 IEnumerator CreateTerrain(TerrainData tData, Vector2 tOffset)
 {
     int Digit_1 = int.Parse(Seed.ToString()[0].ToString());
     int Digit_2 = int.Parse(Seed.ToString()[1].ToString());
     int Digit_3 = int.Parse(Seed.ToString()[2].ToString());
     int Digit_4 = int.Parse(Seed.ToString()[3].ToString());
     int Digit_5 = int.Parse(Seed.ToString()[4].ToString());
     
     float TileHeight = (Digit_1 < 5) ? defaultTerrainHeight + (Digit_1 * 2) : defaultTerrainHeight + Digit_1;
     float TileSize = (Digit_2 > 5) ? (float)Digit_2 : 5f;
     
     Vector3 TerrainSize = tData.size;
     TerrainSize.y = TileHeight;
     tData.size = TerrainSize;
     
     // Create a new empty array which will hold the generated terrain data.
     float[,] tHeights = new float[tData.heightmapWidth, tData.heightmapHeight];        
     
     for (int w = 0; w < tData.heightmapWidth; w++)
     {
         for (int h = 0; h < tData.heightmapHeight; h++)
         {
             tHeights[w, h] = Mathf.PerlinNoise((Seed + tOffset.y) + ((float)w / (float)tData.heightmapWidth) * TileSize, (Seed + tOffset.x) + ((float)h / (float)tData.heightmapHeight) * TileSize);
         }
     }
     
     // Apply the generated data to the terrainData.
     tData.SetHeights(0, 0, tHeights);
     
     // Terrain heights have been generated, return from this function.
     yield return null;
 }

I have no issues with setting the neighbours or stitching terrains together as that is the final part of generating the world; before I can do so though, the noise needs to align properly.

So, to reiterate my question; Am I doing something wrong, is the offset of 9.98 just a coincidence in my text project? What would be the correct way to find the next offset to created a tiled perlin terrain?

Hopefully I've provided enough information, let me know if you need any more. Thanks, LD.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by udk_lethal_d0se · Oct 15, 2015 at 02:39 PM

I have found the solution to this problem simply by trial and error; the new offset is simply 5.

However, I would like to know if there's a better solution by calculating the offset if for instance the size of the terrain or resolution changes.

EDIT: The solution is that the offset is the TileSize used in the perlin function.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

30 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Terrain and PerlinNoise Glitch 0 Answers

Why is perlin noise generating flat terrain? 1 Answer

Tiling problem with Perlin generated terrain chunks 1 Answer

I need help with textures. 2 Answers

2D Efficient Realtime Terrain Generation 0 Answers

  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges