Announcement

Collapse
No announcement yet.

Create procedural terrain from tiles

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Create procedural terrain from tiles

    Basically an extension from my original post in Content Creation about creating a large 3D map of tiles procedurally. As it has gone into specific programming issues, it would be more appropriate to ask here.

    I am attempting to procedurally generate a fairly large map out of 3D tiles, in a similar fashion to Dungeon Keeper and Evil Genius, with some inspiration from RimWorld and Prison Architect. So far, I have implemented LibNoise to generate procedural noise, and I have been able to get a procedural mesh in place to visualize the noise. All this works perfectly fine. However, I am now attempting to translate this into simple square tiles.

    The map in question will be no larger than 250x250 tiles. Each tile is 100 units wide (approx. 1 meter).

    Now, the easiest way to do this is to create a base actor class which represents a single tile. This contains a reference to a tile mesh (a quad for the ground, a cliff face for mountain edges, etc.) It also contains all the data that a tile would need, such as its type. Another class (let's call it TerrainManager) creates an array of instances of these actors and positions them in a grid. Using the aforementioned procedural noise, I can spawn specific tiles at specific coordinates. Of course, the major problem with this is that having thousands of actors can grind the game to a halt, even if they are quite simple. By searching around, I came to the conclusion that I need to separate the rendering and the data.

    The data can easily be stored in a struct, and each unique tile can be created as Data Asset in the editor. An array is created with instances of these Data Assets based upon the procedural noise. I believe I can access a specific tile from the world by using a formula to convert the world coordinates into an array index number. This part hasn't been worked out fully yet, though, as the rendering part is more important at this point.

    As for rendering the tiles, my initial attempt was to use Hierarchical Instanced Static Mesh Components. While it certainly worked with 250x250 tiles, HISMC's are severely limited, for a reason. Each instance is exactly the same, except for the transform. This means that for each unique tile, I need a unique component. This in itself is perhaps not so bad. I'm not going to have several dozen unique types of grass or rock, although I do intend to include variations of cliff meshes to avoid repetition. However, I would also like to have different tiles adjacent to each other to blend their textures, which can't happen if every instance uses the same material.

    I am currently trying to use the Runtime Mesh Component plugin. I have successfully created a mesh that has ground at 0 Z and solid rock at 300 Z. Unfortunately, this creates a sharp transition as all vertices are welded (see attachment). What I wanted to try was to convert a static mesh (with vertex colors on the edges which could be used for blending) into the procedural mesh, and then copy this tile across the surface of the map, or create individual mesh sections for each tile. However, I can't seem to access a specific mesh section directly to grab the render data.

    So that is basically my story so far. What I need help with is deciding how I can render a 250x250 size map, preferably with soft transitions between ground tiles. Whether HISMC's can still be used for this, or if a Procedural Mesh is better, and if so, how it could be implemented. Ground and solid rock tiles are flat. Transitioning between flat ground and solid rock is going be done using separate cliff meshes, or wall meshes when the player builds them.
    Attached Files
    Portfolio: https://www.artstation.com/final-frontier
    Stargate & DHD: https://forums.unrealengine.com/comm...5-stargate-dhd

    #2
    I am using something similar, so yes, getting a tile based on world coordinates is definitely possible.
    Hint: Morepork functions library has a function which lets you check if coordinates are within certain bounding box (all just by maths) so it should be easy to convert to c++.

    Comment


      #3
      Not sure how relevant this is, but I've written a tile-based procedural terrain generator if you want to have a look at the code :

      https://github.com/midgen/cashgenUE

      Note you can't use LibNoise if you plan on releasing the game, the GPL license is a nono. I've written a UE4 wrapper around an MIT-licensed noise generator that's free to use (and faster) https://github.com/midgen/UnrealFastNoise

      Comment


        #4
        Originally posted by mid_gen View Post
        Not sure how relevant this is, but I've written a tile-based procedural terrain generator if you want to have a look at the code :

        https://github.com/midgen/cashgenUE

        Note you can't use LibNoise if you plan on releasing the game, the GPL license is a nono. I've written a UE4 wrapper around an MIT-licensed noise generator that's free to use (and faster) https://github.com/midgen/UnrealFastNoise
        Thank you for notifying me about the license of LibNoise, I hadn't bothered to look if I could use it, and none of the other topics I found about using the library mentioned it. I looked into FastNoise, and it looks to be a good alternative. I haven't looked at your terrain generator yet, but I will and thanks for the suggestion.
        Portfolio: https://www.artstation.com/final-frontier
        Stargate & DHD: https://forums.unrealengine.com/comm...5-stargate-dhd

        Comment


          #5
          Did anything come of this? I am attempting to much the same, and i've also come to the conclusion that thousands of actors is a bad idea. My tiles are 9 vertex, 8 triangle meshes that when I make 100x100, it simply takes out my machine if I'm not using max drawing distance. I have also combined it all into one mesh, but then i cant hide part of it if i want to, and i haven't figured out how to identify specific sections of the mesh during runtime in order to edit a desired area.

          Comment

          Working...
          X