Search Unity

Procedural Terrain System and Shader

Discussion in 'Shaders' started by Deneb, Jul 16, 2014.

  1. Deneb

    Deneb

    Joined:
    Dec 4, 2013
    Posts:
    22
    Hi everyone!

    I'm building a procedural terrain system and have an issue regarding texturing.

    That terrain system has nothing to do with the unity built-in terrain system.
    the terrain mesh's are generated by C#.
    Iterations are made to fill vertices, triangles, normals and uv's arrays to create the mesh's.
    I use perlin noise as heightmap.

    the system works with 9 tiles ( 3 by 3 )
    the user / aircraft is always in the center tile. When the aircraft is moving to another tile, that tile becomes the tile
    in the center and other tiles are moving to re-form the 3 by 3 shape ( with the aircraft in the center tile ).
    In the current system, each tile is 24000 x 24000 units.
    using proper fog settings i can hide the new terrain tiles poping at the horizon.

    All of this is working great, my only problem is about the texturing:
    i wrote a very simple Cg shader for the terrain material. Using the multi uv mixing technique, to avoid the tiling texture effect. The shader is using 2 seamless textures, that are "mixed" in many different scales to totaly avoid any visible tiling. The result is convincing.

    But the problem:

    Every of the 9 tiles are using that same Material, and between each tiles, the texture seam is visible.
    I'm looking for a different approch to texture my 9 tiles in a way that we cannot see any texture seams between tiles.


    (image: in the middle of a 24km terrain tile)
    in the middle of a 24km tile.png

    (image: at a tile edges)
    at a tile edges.png
     
  2. dirtybassett

    dirtybassett

    Joined:
    Oct 3, 2012
    Posts:
    59
    Deneb likes this.
  3. jc_lvngstn

    jc_lvngstn

    Joined:
    Jul 19, 2006
    Posts:
    1,508
    Your terrain must be very low resolution to use such large meshes :)
     
  4. Deneb

    Deneb

    Joined:
    Dec 4, 2013
    Posts:
    22
    yes rather low resolution:
    each "tile" mesh is 120 x 120 verts
    and distance between each vertex is: 200 m

    i tried to push it and go 250 x 250 verts ( near the 65k verts limit ) but it take long minutes to compute
    for unity. Each time Play / Stop is pressed, unity gets frozen during computing. (4-5 minutes)
    same to run the binary. (4-5 minutes of black screen before it starts)
    but once loaded, frame rate was ok. ( about 100 fps on a mac mini )

    (those 120x120 verts mesh tiles takes only a second to "load" when i go runtime.)

    i'm dreaming about Mesh LOD ( or CDLOD) , but it's out of my reach...................for now.
     
    Last edited: Jul 17, 2014
  5. Deneb

    Deneb

    Joined:
    Dec 4, 2013
    Posts:
    22
    oh yes! world uv's in the shader.... brilliant!
    i modified my "multi-uv-mixing" shader so it uses the World Position as UV coordinates.
    (instead of the 2D Texture uv's)
    It works fine! thank you!
    :) :) :)



    yes it's nine large meshes. 24 square kilometers each.
    each tile/mesh is a gameObject with a MeshFilter, MeshRenderer, MeshCollier and a script that build its mesh.

    the MeshFilter and MeshCollider component are empty before runtime.
    these 2 components gets their data ( the mesh ) from the C# script at runtime.

    so instead of selecting a mesh in the MeshFilter component and browse the mesh list from the project asset,
    the mesh is created on-the-fly ( at runtime ) by the script and then assigned to the MeshFilter component.

    if you'd like more details, just tell me and i'll explain.
     
    Last edited: Jul 17, 2014
  6. FuzzyQuills

    FuzzyQuills

    Joined:
    Jun 8, 2013
    Posts:
    2,871
    @Deneb: You doing this for what reason? I am curious! :)
     
  7. drudiverse

    drudiverse

    Joined:
    May 16, 2013
    Posts:
    218
    I have written a terrain system and i ironed out all the bugs. for seams, the floating point accuracy means single pixels sometiems visible in seams, solution was use hexagon tile plane generator on unify3d and to enlarge the terrain tiles by 0.001 or so so they overlap one pixel. still leaves the problem of normals at edges, which are based on normals from the uv's around them, so at edges they dont have uv's around the same, and you have to add the 2 edge ones togetehr and devide them.

    i have a terrain code complete, i have to sell it lol. it has hexagons and correct shadows etc.
     
  8. drudiverse

    drudiverse

    Joined:
    May 16, 2013
    Posts:
    218
    https://www.youtube.com/edit?o=U&video_id=Xis10EA3NQE

    it's a tiling version, i worked for a long time on it but i included some shader code and a noise library in the asset version for convenience and i didnt get an answer from the asset store so i ran out of energy on it. i have to arrange a version with simpler noise code ... there is a sales page on the youtube im not sure where the most recent version is i have to see. thanks the mesh uses any mesh size and number that you want, it depends on how much the pc can handle, when you rewrite terrain mesh on the fly, it has to also be passed to the graphics card, so it limits the mesh size, 32x32 meshes for example can cause slow frames, so have to find a balance to stream the new mesh to the graphics, which i did and i multicored the code, i dont know even if unity allows us to include WhyDoIDoIt's mutlicore code in an asset even though he sais its ok. the code is tidy and it's like 2-3 months of work. technical list is on the frogsbo.com webpage.
     
  9. drudiverse

    drudiverse

    Joined:
    May 16, 2013
    Posts:
    218
    here's another video... You know... one of the things that didnt look nice about about the terrain, is that the vertices are all spaced equally apart in a kind of pattern, and the mountains are trying to be variable and random appearence... so what i did, was i randomized all the tiles at start time, to change the vertices by say 20 percent... which made all the triangles all different sizes, it's kindof nicer.

    here's another video of the terrain code i wrote, it has alot of options you can have as many tiles as you want etc. if you want to make a game using it, you can have a copy of the code.

     
  10. FuzzyQuills

    FuzzyQuills

    Joined:
    Jun 8, 2013
    Posts:
    2,871
    Nice! Pretty impressive for something dynamically generated... ;)
     
  11. Deneb

    Deneb

    Joined:
    Dec 4, 2013
    Posts:
    22
    very nice!
    the correct URL to your video is: www.youtube.com/watch?v=Xis10EA3NQE

    where is your asset in the store?
     
    Last edited: Jul 20, 2014
  12. Deneb

    Deneb

    Joined:
    Dec 4, 2013
    Posts:
    22
    oh yes, the space between each vertices, in my system they are all spaced equally, i never tried to touch that. I only do heights by 2 scales of perlin noise.
    i'll try what you suggest!

    yes i'd love to take a glimpse at your code.

    do you generate / apply also colliders on the terrains meshes?
    because at first i went into trouble when applying the mesh on the MeshCollider component during runtime,
    ugly lags. I had to split each tile (24'000 by 24'000) mesh into 12 parts, and apply the colliders gently, parts by parts on the tile using coroutines to preserve a constant frame rate.
     
  13. drudiverse

    drudiverse

    Joined:
    May 16, 2013
    Posts:
    218
    The code isnt in the asset store because i was naive and included multithreading code and noise library in the my demonstration files, and i can't do that for unity, it has to be all my code. so i have to do asset store version without demonstrations files.

    Yes you will find that colliders take about 10-20 times more processor time to generate than mesh renderers. so i could generate about 5 tiles of colliders around the central player for realtime play, i made it adjustable by radius, you can decide what radius of tiles near player to make colliders, also the mesh tiles are generated in a kind of radius around player.

    Unity mesh collider is completely un-adapted for a procedural terrain, if you want to fly very fast in the terrain and have distant crashes , i would definitely recommend using an array to keep all points of terrain in the game, and read from the array to see if something has gone under the terrain. for slow flying and walking games, it's very possible to queue the unity mesh colliders in idle time.

    I'll see where my code is, PM me your email. it would be helpful to have a version control to check for bugs:)
     
  14. drudiverse

    drudiverse

    Joined:
    May 16, 2013
    Posts:
    218
    sorry i meant quality control :)