Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Dividing Terrain Into Biomes

Discussion in 'Scripting' started by JasonBricco, Mar 24, 2015.

  1. JasonBricco

    JasonBricco

    Joined:
    Jul 15, 2013
    Posts:
    956
    I'm having a great deal of trouble dividing my voxel terrain into biomes, and I'm looking for advice for methods I could use.

    I have tried two methods so far - Simplex noise and Voronoi diagrams. But I can't seem to get them to work in such a way to where my goals are met.

    Goals:

    1. The terrain should be divided up into regions, each region being a biome.
    2. The regions should not be based on height. Rather, the biomes should act on the terrain to create the proper height.
    3. Biomes should transition smoothly between each other.

    Simplex:

    I can generate a simplex heightmap and map biomes to it. On the positive side, I can easily transition smoothly between biomes because I can use the simplex value to see how close I am to the biome edge. If I map a value of 2 to 4 to be a forest biome, then I know if the value is near 2 or 4, it's close to an edge. The problem is, simplex violates goal #2. I do not want my biomes being based on height. With simplex, biomes will be based on height in some way. And often, my biomes look like circular strips instead of filled in areas.

    Voronoi:

    Voronoi is great at dividing my terrain into the types of regions I want. The regions are not based on height, and they're not circular strips. The problem with voronoi is it violates goal #3. I cannot figure out how to transition smoothly between biomes. Because biomes control the height, I often get flat walls between the biomes. I use a simplex heightmap within the voronoi regions, but the voronoi regions can modify it to control the terrain.

    To solve the problem with voronoi, I have to be able to get the distance from the seed to the edge and see how far my current block is between it. I have no idea how to get the distance from the seed to the edge, though.

    Are there any other methods I could try that would meet my three goals? Not necessarily looking for any code, by the way. I'm looking for more high level basic explanations about how I could approach this.

    And if there aren't, is there a way I could make one of these two methods work better?

    I've spent many days trying to figure this out to no avail so far, so I'd appreciate any help!
     
  2. Brominion

    Brominion

    Joined:
    Sep 30, 2012
    Posts:
    48
    to generate the heightmap use a weighted average of your two [Edit: can more than two offcourse] biome output functions, with the weight beeing the distance to the "center". You could naturally impose some limit as to how far away the zones influence eachother.
     
  3. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    I'm building something similar. I essentially use multiple layers of Perlin noise. The first layer determines height, and ensures the terrain has a smooth height map.

    The second layer determines some other biome factor, say water availability.

    The actual biome is determined from a 2D data structure. This 2D approach means biomes are height related. But it breaks the hard edges you see with a 1D approach.

    For higher realism you can add dimensions tied to lattitude as well. One real climate model I saw used 12 dimensions to model pest populations in a national park. In the final analysis it dropped back to about five, as the other dimensions were not considered statistically significant.

    My code base for this is pretty hacky at the moment. But once it's fit for public consumption I'll throw it up on the asset store if you are interested.
     
  4. JasonBricco

    JasonBricco

    Joined:
    Jul 15, 2013
    Posts:
    956
    I'm trying to wrap my mind around this. When I tried a (rather awful) height-based approach with only a single simplex function, I ended up with the biomes being in a circular strip around the base of hills, because I was essentially just taking a certain range of the height and saying whatever falls in that range is going to be this specific biome.

    Your suggestion is to use multiple simplex (or perlin) functions, and take an average or something of the like. It's still height based, but what advantage does it give? How does doing it this way make the biomes better and remove this strip problem I have?

    One thing I'm not necessarily trying to do is make my terrain realistic, like on Earth. Also, I'm trying to code a biome system that can be dynamically modified by the player. That means, the player can optionally turn specific biomes on or off. This requirement is making my life much more difficult.
     
  5. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    My suggestion was not an average. I may have explained it wrong.

    Something like this
    • If height > .8 and moisture > .5 then ice and snow
    • If height > .7 and moisture < .5 the rocky
    And so on till you fill the solution space. It's still height related, as biomes are in real life, but not so directly as to appear obvious.
     
  6. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Just reread your post. A dynamic biome system controlled by the player at runtime would look very different. Let me think on it.

    You probably will want something like @Brominion suggested, where each biomes influence bleeds into the others.
     
  7. JasonBricco

    JasonBricco

    Joined:
    Jul 15, 2013
    Posts:
    956
    The problem I have is that I don't know the distance to the center, with the methods I've tried. If I knew distance to the edge with voronoi, it would be easy. I could just have a base heightmap, then let the biomes modify their heights while factoring in the distance to the edge. I could turn it into a percentage - if you are at the edge, then the percentage would be 0% meaning apply 0% of the biome's terrain modification to this spot (so it would use the base height). As you go inward in the biome, the percentage goes up and the biome has more influence.

    That sounds fine to me, but I don't know how to get that percentage. I can get the distance from any spot to the region's generator site, but I don't know how close that is to the edge.

    I may have to play around with simplex some more, since I'm starting to think voronoi just won't cut it.
     
  8. RockoDyne

    RockoDyne

    Joined:
    Apr 10, 2014
    Posts:
    2,234
    I think there might be a way to do this with angles. This is all unverified math, so hold on to your butt.

    If you have a triangle and you take one of the edges, any point inside of the original triangle should make an angle that is greater than the third point in the original triangle. Make sense? Because I sure as hell don't think so. I think it's right, just don't come to me wanting proofs.
     
  9. Brominion

    Brominion

    Joined:
    Sep 30, 2012
    Posts:
    48
    Sorry was in too much of a hurry with my original post ;)

    I would think Voronoi type datastructure is exactly what you would want, given that: "a Voronoi diagram is a partitioning of a plane into regions based on distance to points" (from wikipedia) The points mentioned are the "centers of the biomes"

    For each of these points you can figure out what biome is best suited (this can be done like suggested elsewhere by other random heightmaps representing not height but perhaps moisture levels, temperature, general elevation etc. You could assign them completely at random as well. You can also give it some score as to make it more influential, generating a bigger voronoi cell).

    For each such biome you probably want at different parameters to your terrain/voxel generating function or a different generator function completely. (think mountains vs desert vs ocean and so on).
    Now at any one point in the world the influence will be a combination of the (edit)current voronoi cell and (/edit: for clarity) adjacent voronoi cells' generation functions weighted by 1/distance or perhaps or perhaps 1/distance squared for quicker dropoff.

    This would fullfill your three objectives from OP i think.
     
    Last edited: Mar 25, 2015
    JasonBricco and Kiwasi like this.
  10. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    The key issue I see with the Voronoi and drop off approach is there will be area that are far enough distant from any point to be influenced by any biome.

    I would deal with this by normalising the output from your drop off. Take the closet three or so biomes. Apply drop off. Add the results together. Then scale the individual biome factors so the sum is always equal to one.
     
    JasonBricco likes this.
  11. Brominion

    Brominion

    Joined:
    Sep 30, 2012
    Posts:
    48
  12. Orr10c

    Orr10c

    Joined:
    Sep 11, 2016
    Posts:
    45
    I'v been dealing with these problems lately and was wondering how can I put all adjusent boims center points (when using the voronoi method) to a 1D array? I was trying to find a solution for this for some time but haven't found one, any help appreciated! :)
     
  13. Judas_Bricot

    Judas_Bricot

    Joined:
    Apr 13, 2019
    Posts:
    1
    Hey, I am also creating a procedural World, and I've got the same problem than you. I saw that Voronoi diagram was just random center point, and all the points that are closest from a center point are in the center points cell. So maybe you can create your proper Voronoi by creating these random center points, and then it is very easy to store all those points on a 1d array.
    I think it could be also easier to do a transition between two biomes based on the distance between a point, its cell center point and the second closest center point.
    To get a smoother transition you can probably use curve, that are implemented in unity.

    I hope this could help, I don't know if that is what you want. Also sorry for the explanations I don't know if it is clear :), and for my French High-schooler English.
     
  14. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    1,556
    It is kind that you want to help, but you should look at the timestamp from the last post you are replying to. Your answer comes more than two years after the last response (and five ears after the initial question). Still appreciated, I'm sure, but probably no longer urgently awaited :)