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. Dismiss Notice

After playing minecraft...

Discussion in 'General Discussion' started by jc_lvngstn, Oct 8, 2010.

Thread Status:
Not open for further replies.
  1. justin35f

    justin35f

    Joined:
    Jan 19, 2013
    Posts:
    37
    Congratulations!!

    Edit:
    Removed stupid comment because I can't read.
     
  2. RSH1

    RSH1

    Joined:
    Jul 9, 2012
    Posts:
    250
    Congrats, nice work!

    I know what the problem is with the chunk errors. Each chunk checks neighbouring blocks, to see if faces should be drawn/lighting etc. The problem is, when the chunks at the edge of the map check their neighbours, the circular array loops round and they see entries at the other side, so when you move the new chunks already think they've been generated and display the wrong values.

    Anyone encountered/know how to prevent this problem?
     
    Last edited: Jan 25, 2014
  3. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    765

    I normally draw chunks twice. First pass is as fast as possible, as soon as they load. This leaves a little shadow between chunks, and water surface that should not be there. After all neighbors have been loaded, I redraw them so that light and water render properly. When the game starts, you can see shadow lines in a grid; they go away after a few seconds. I would rather do this instead of waiting for all chunks so that terrain displays as soon as possible. Also, my rendering algorithm is very fast, so it is ok for me to render multiple times.
     
  4. RSH1

    RSH1

    Joined:
    Jul 9, 2012
    Posts:
    250
    Hmm, I'm not sure if this would work well for me as drawing the mesh is currently the largest bottleneck for me. I'm doing a fair amount of vertex displacement/tapering too which adds complications. I don't think the "greedy" method linked earlier would work with this kind of terrain.



    Is there a better way of drawing the mesh than three loops X, Y, Z and checking each block?

    EDIT: Tried this method and it's actually not too bad, chunks in the distance still have the 'borders' however which isn't ideal.

     
    Last edited: Jan 25, 2014
  5. jorritTyb

    jorritTyb

    Joined:
    Jan 17, 2014
    Posts:
    13
    My chunk manager doesn't use the circular array to see if a chunk is active or not. It does that independently from the circular array. So old data left over from previous chunks can never be reused since the chunk manager knows it is a new chunk and waits displaying that chunk until it is generated again.

    Greetings,
     
  6. justin35f

    justin35f

    Joined:
    Jan 19, 2013
    Posts:
    37
    How are you handling slopes? I'm currently implementing them, and I'm just finding that there are so many use cases. I currently check the neighboring blocks (Top, Bottom, Left, Right, Front, Back) and then I do a 'corner' check. For the corner check, I only check on the same Y plane as the block I'm concerned with. This neighbor check leaves 64 possible use cases, which is easily handled, and the corner check leaves makes each of the 64 have 16 sub-cases. That's as minimal as I could figure out, and still cover all scenarios (hopefully).

    $Terravox_005.png

    I'm not done yet, I just took that screenshot from a good angle. I'm just if there are simpler ways to do this. Thanks!
     
  7. RSH1

    RSH1

    Joined:
    Jul 9, 2012
    Posts:
    250
    Yep, there are a lot of use cases, hence the added complications with rendering :p

    Here's how I taper a vertex

    Loads of if statements basically with trial and error. If you see a gap, work out on a piece of paper what's not matching up and work from there.

    Yogventures has some nice slopes, I'd like to see their algorithm :)

     
    Last edited: Jan 25, 2014
  8. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    765
    Yes, there is. Consider that the vast majority of a chunk is either air, or is covered by other blocks. Examining these blocks one at a time is a waste. Try to find a way to skip these in large steps. Think of ways to do "this whole line is air, so skip it and move on to the next line".

    If you look from the top, on average, on a chunk there will be roughly X * Z blocks that you will need to render. So if you manage to skip the air and covered blocks, you only need to examine X*Z blocks, which is O(n[SUP]2[/SUP]) and that is a lot better than the x,y,z loop which is O(n[SUP]3[/SUP])
     
    Last edited: Jan 26, 2014
  9. RSH1

    RSH1

    Joined:
    Jul 9, 2012
    Posts:
    250
    Wouldn't this require using some sort of jagged array? I'm currently using a flat array for the blocks and accessing them with [indexX + blocksWidth * (indexY + blocksHeight * indexZ)]. I'm not sure how it would be possible to get a row of a 1D array. Not without looping, anyway.
     
  10. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    765
    Yes, you need to play with the data structures, a flat array or a 3 dimensional array is not enough if you want to do this optimization.
     
    Last edited: Jan 26, 2014
  11. Foam

    Foam

    Joined:
    Jun 13, 2012
    Posts:
    322
    When you loop you already have structure inherent in the loop, so your data structure doesn't matter. Unless I'm misunderstanding something...

    You just need to keep track of your row status in some other variable. I have an array of Row structs, which just keeps track of various things for that row (e.g., does it have air? does it have water?). I do not access my blocks directly but do it through an overridden function for the chunk itself, which in turn does a quick addition/subtraction on the row every time a block is changed (i.e. 0 means there are no air blocks, 1 means there is 1 air block, etc.). This way it is always accurate.

    It would seem this would be inefficient, but, when you're already doing a few multiplications (to calculate x + chunk_width * (y + chunk_height * z)), a few extra additions is nothing.
     
  12. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194
    Has anyone tried run length encoding for this, it's a simple scanline based compression technique that sounds like it could be ideal for dealing with rows of blocks in a chunk?

    For example you only store the index position of the first block followed by it's length (how many blocks of the same type follow it). Would this work as you could have meshes pre-built to a specific length of blocks up to the maximum chunk row length and then draw them in position and texture them?
     
  13. Foam

    Foam

    Joined:
    Jun 13, 2012
    Posts:
    322
    RLE is used quite often, but usually only when passing data over the network. You encode the chunk, send it, and decode it on the client. You don't want to have your native data structure use RLE because you can't access the blocks randomly. That is, you need to look at the position of every block previous to the one you want, and likewise for every neighbor, to get the value of block x, y, z.

    As far as pre-built meshes goes, I'm not sure where you are going with that. I don't think you'd see much benefit as you still have to "stitch" the rows together. So if you had a chunk size of 32, a row can have... I dunno, 32^8 possible meshes (keep in mind all neighbors, even those not in the row, have to be accounted for, and all permutations)?

    /edit oops, it's (2^6)^32 or something like that. Still quite a large number of combinations!
     
    Last edited: Jan 26, 2014
  14. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    765
    Yes. I use RLE for rendering.
     
  15. Foam

    Foam

    Joined:
    Jun 13, 2012
    Posts:
    322
    I use RLE for rendering but that's just a greedy mesh algorithm that generates the RLE as a byproduct. Do you store your RLE encoding data alongside the "pure" chunk/block data? Or something more advanced?
     
  16. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    765
    Yes, I store the RLE data alongside the pure data, and use the RLE data to skip large sections when rendering.
     
  17. RSH1

    RSH1

    Joined:
    Jul 9, 2012
    Posts:
    250
    So I've ported the Bukkit biome code into my project



    The only problem I see is, generating the list of nearby biomes (Dictionary<Biomes,double> biomes = biomeGenerator.getBiomes(localX,localZ)) for every block is absolutely killing performance on chunk creation. I'm dropping down to ~8fps on load now. Has anyone else found this?
     
  18. jorritTyb

    jorritTyb

    Joined:
    Jan 17, 2014
    Posts:
    13
    Biomes are generated using 3 perlin noise maps (one for temperature, one for moistness and one for height level (ocean, hill, ...). I interpolate these over every x,z block in a chunk and that's really very fast for me. I have no trouble with biome generation this way. Not sure how others do it though.

    Greetings,
     
  19. jordantotty

    jordantotty

    Joined:
    Dec 15, 2011
    Posts:
    77
    Exact thing has happened to me! I have great biomes and terrain but the lag is unbearable :( I've been trying to fix this for like a week hah. Good luck and share your findings :)
     
  20. RSH1

    RSH1

    Joined:
    Jul 9, 2012
    Posts:
    250
    I also tried using Voronoi Noise, instead of Perlin, to try and make the biomes occur more naturally rather than in "bands" like Perlin generates.

    https://forums.bukkit.org/threads/wgen-voronoi-noise.161319/

    However this really was way too slow. Which is a shame because I really dislike the way Perlin generates biomes and according to this image of Minecraft biomes:



    It seems Notch used Voronoi for Minecraft biome generation. Maybe the Bukkit implementation of Voronoi isn't optimized.
     
  21. jorritTyb

    jorritTyb

    Joined:
    Jan 17, 2014
    Posts:
    13
    Why would Perlin create bands? Of course if you use a single perlin map for biome generation then it would do that but I'm using three perlin maps (temperature, moistness and height level) and then a table mapping the different settings to the biome. This works really well and doesn't create bands at all. For example:

    DRY, HOT, PLAINS is mapped to desert

    So you get a lot of combinations with that. I use bilinearly interpolated perlin which speeds up the process a lot (biome generation is less then 0.0001% of my total calculation time).

    The end result is nicely random shaped biomes with the tendency to have same-temperature and same-moistness biomes adjacent to eachother but with still enough variety.
     
  22. RSH1

    RSH1

    Joined:
    Jul 9, 2012
    Posts:
    250
    From the Bukkit example this is what's went by "bands" of Perlin biomes



    Their suggestion is to use Voronoi which generates them like this:



    Which just looks a bit more random and organic.
     
  23. jorritTyb

    jorritTyb

    Joined:
    Jan 17, 2014
    Posts:
    13
    Hmm, those urls are giving me an error (you must be logged in). I don't have a bukkit account.
     
  24. RSH1

    RSH1

    Joined:
    Jul 9, 2012
    Posts:
    250
  25. jorritTyb

    jorritTyb

    Joined:
    Jan 17, 2014
    Posts:
    13
    No, they are not working there either. I guess you have to be logged in to see bukkit images.
     
  26. RSH1

    RSH1

    Joined:
    Jul 9, 2012
    Posts:
    250
    Some mirrors

    Perlin:



    Voronoi:



    Also, how are people doing sea biomes? Do you just set a water level and anything below that is water?
     
  27. BigRoy

    BigRoy

    Joined:
    Jan 2, 2014
    Posts:
    12
    So I've been reading through most of this thread, awesome stuff here! :)
    I still have some questions that I hope some of you might be able to answer.

    I'm trying to build an infinite world data structure for a Voxel world in Unity in C#.
    I'm using a 2D voxel space so I'll use that as the example space for the code here.

    Going to the infinite world stage...

    Examples might contain errors, I typed the code especially for this post to show the idea I have in my mind.

    Currently I have a finite world predefined in a nested array, like so:

    Code (csharp):
    1. Chunk[,,] = new Chunk[chunkAmountX, chunkAmountY]
    That contains the data for all my chunks in the world.

    Yet I'm currently thinking about implementing a circular flat array for the currently active data in memory.
    As far as I know for it to be a circular array it should have a predefined finite size, which I can make it (it's my currently memory active data).

    So let's say at any time there's 32 chunks and 32 chunks x, y in memory based on where the player is.

    Code (csharp):
    1. Chunk[] = new Chunk[32*32]
    Then the chunk where the player currently is would be the chunk:

    Code (csharp):
    1. index = Mathf.FloorToInt(player.x) % 32
    I'm not moving the geometry instead of the player (or any other extreme measure to avoid floating point issues). But I was thinking about storing an integer offset that would describe the chunk the player is at. Then if the player loads the game later I'm placing him at 0,0,0 position with the stored offset and the world will be generated (actually just accessed) with the offset.

    Code (csharp):
    1. index =  Mathf.FloorToInt(player.x + offset.x) % 32
    Then as I move around in the game (for example to the right) I know which blocks are 'far away' enough (out of the memory reach) to be forgotten about. I can then replace that index in the array with the the new chunks that are now close enough.

    Let's say I wanted to store the new right-most chunk, by doing this:

    Code (csharp):
    1. index =  (Mathf.FloorToInt(player.x + offset.x) + 16) % 32
    // The right most chunk is 16 chunk away from the player.

    By assigning a new chunk at that index the reference to the old chunk at that index can be destroyed (or saved out to disk to keep track of a much larger world size that doesn't reside in memory). Yet I know that the index I'll override was originally the left most chunk (if I moved by one chunk).

    This is just pseudocode and the idea I have in my head, yet I've no clue if this makes any sense. I've read in this topic people use hashes (mainly dictionaries?) to store the chunks in so they have relatively quick access in general. Yet for an infinite world how could you easily know which Chunks that reside in the dictionary would need to be removed. Do you iterate over all the keys, values in the dictionary to see which one can be discarded/saved out. Or do you just kill that 'chunkMinimum - 1' index and hope that you ever only move 1 chunk per frame at most?

    Storing your chunks/blocks data...

    I originally started with this series of tutorials: http://studentgamedev.blogspot.nl/2013/08/unity-voxel-tutorial-part-1-generating.html

    Yet it uses a single 'data' array on the World class that contains all the voxel information. The Chunk classes themselves don't have any of the voxel/block data, they are actually accessing this again from the big array on the World class. Instead the Chunk class only contains the functionality to create the Chunk mesh based on the World data. Is this the normal way of doing this? Or do you store the voxel data PER CHUNK instead?

    As I'm not that experienced with low-level black magic going on in the computer hardware but I'm able to guess the single big data center on World could have benefits. Since it's a single long array (actually nested in the tutorial) it's all contiguously allocated in memory which might result in faster access. For me it just feels so strange to do it like that. :) Any pointers/tips?

    Hope someone can answer my questions, and sorry for the long post.

    -Roy

    EDIT:

    These two posts did help with some of my questions, yet if someone still wants to elaborate some more I'd be glad to read it. :)
    http://forum.unity3d.com/threads/63149-After-playing-minecraft/page113?p=1493753&viewfull=1#post1493753

    http://forum.unity3d.com/threads/63149-After-playing-minecraft/page113?p=1494095&viewfull=1#post1494095
     
    Last edited: Jan 30, 2014
  28. RSH1

    RSH1

    Joined:
    Jul 9, 2012
    Posts:
    250
    Anyone managed to get a triplanar shader working with the vertex lighting system most of us are using? All of the triplanar shaders I've found so far are purely surface shaders which are ignoring the custom lighting.
     
  29. justin35f

    justin35f

    Joined:
    Jan 19, 2013
    Posts:
    37

    I'm at work so I can't dig into my code to give specific examples. In terms of the dictionary approach (what I am currently using), the key is a Vector3, which is the X,Y,Z of that chunk. That way it is very easy to access any chunk, because I always know (or can easily determine) the location of a chunk I want to interact with in some way. Currently, I have my voxel data in each chunk, I haven't had the need to put everything into a circular array, however each chunks voxel array is a flattened array.

    One more thing, any operation you perform on a per voxel basis needs to be micro-optimized. The thing about voxel engines that you don't see in most other kinds of programming is heavy iteration. Everything you do to a voxel is potentially done tens, if not hundreds of thousands of times. So a simple thing like a modulo, should be further optimized by using bitwise operators. NEVER divide when dealing with individual voxels. There are far too many optimizations that can be easily done, and are not that confusing.

    Normally the micro-optimizations are frowned upon, but in this specific case (voxel engine) it really is the way to go.
     
  30. RSH1

    RSH1

    Joined:
    Jul 9, 2012
    Posts:
    250
    Anyone else get these strange anomalies sometimes using Bukkit terrain blending?

     
  31. JohanHoltby

    JohanHoltby

    Joined:
    Feb 10, 2013
    Posts:
    89
    I have not used Bukkit. But it looks like you are dividing by a number aproching zero which aproces infinit fast.
     
  32. RSH1

    RSH1

    Joined:
    Jul 9, 2012
    Posts:
    250
  33. jordantotty

    jordantotty

    Joined:
    Dec 15, 2011
    Posts:
    77
    Mine doesn't do this? hmm, probably a small error in your code
     
  34. midorina

    midorina

    Joined:
    Jun 1, 2012
    Posts:
    131
    Just came across this thread and I have to say, it's really useful! I haven't quite read all of the thread -yet- but there are leaps of information in here.

    I can't wait to dive into this and start working on my own little project.

    I'm curious, are you guys doing this for education purposes, unity store asset or are you going to be designing your own game around all this?
     
  35. GibTreaty

    GibTreaty

    Joined:
    Aug 25, 2010
    Posts:
    792
    I did it as a challenge to see how far I could develop my own voxel generator. I've learned a lot from it. I'd like to use mine in a game but it still needs tons of work to make it easier to use.
     
  36. Spiderbean

    Spiderbean

    Joined:
    Nov 12, 2012
    Posts:
    6
  37. justin35f

    justin35f

    Joined:
    Jan 19, 2013
    Posts:
    37
    I'm doing this for my own game. It did however start out as a challenge to myself. I had started a tutorial series on YouTube and got in over my head, so I took a break from that, and I figured I would create a complete game with a voxel engine first, then once it was complete, and actually playable, then I would make a tutorial series for people to follow along and be able to create their own voxel engine.
     
  38. DavidWilliams

    DavidWilliams

    Joined:
    Apr 28, 2013
    Posts:
    522
    We've just made a new progress video for Cubiquity if anyone is interested:

    [video=youtube_share;NLQozqoPMho]http://youtu.be/NLQozqoPMho​

    This shows off a couple of features which I think are fairly unique. Each volume now has its own transform, which means we can set up this system of voxel planets which rotate and orbit each other. It took a bit of effort to get the raycasting working across the different transform spaces, and to make the triplanar texturing properly stick to moving surfaces but it came together nicely in the end. The second feature is the texturing of the planets which is done by pulling the texture from a cubemap based on the surface normal.

    You can find more details and download the Unity Package on our blog post: http://www.volumesoffun.com/cubiquity-volume-transformations/

    Feel free to ask if you have any questions about the implementation :)
     
    Last edited: Feb 12, 2014
  39. ciprianbiris

    ciprianbiris

    Joined:
    Oct 11, 2013
    Posts:
    32
    Hi guys. I implemented my own engine with 4 block types and infinite world.
    Currently you can only destroy blocks.
    Can you run an give me the Chunk Gen time from top left corner?
    ps. I do mesh optimization even with different blocks

    https://www.dropbox.com/s/chyz8yafyx8obss/ciprian_0.0.11.zip

    image
     
    Last edited: Feb 17, 2014
  40. Deleted User

    Deleted User

    Guest

    I was wondering. It seems that there are mostly two options for collisions: AABB and optimised meshes.
    I plan to have a significant number (let's say 50+) of agents that will require pathfinding (in which I have not looked into), does that affect my choice of collision approach?

    On other note, I can see that standard storage + RLE seems to be a good approach, but has anyone considered using octrees instead of RLE? (not as a replacement for storage, but just for optimization purposes).

    Edit: One more thing - if not building optimized collision meshes, is there a point of having chunks?
     
  41. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    765
     
  42. mathias234

    mathias234

    Joined:
    Sep 9, 2012
    Posts:
    239

    $Uten navn.png
     
  43. mathias234

    mathias234

    Joined:
    Sep 9, 2012
    Posts:
    239


    here is my stats
     
  44. ciprianbiris

    ciprianbiris

    Joined:
    Oct 11, 2013
    Posts:
    32
  45. asperw

    asperw

    Joined:
    Oct 19, 2012
    Posts:
    3
    Hello,

    I am very new here but I have been reading through this thread for the past several days now, and I have been playing with an open source framework for voxel engine myself. One of the things I found interesting and unique was alexzzzz's vertex displacement model. I have tried it myself with interesting results.

    It obviously seems that I am changing the vertex position for all of the voxels in my scene.

    $scenedisp.png

    My question is: can anybody explain how I would go about defining the vertexes that would have the displacement applied to them? I'm thinking it has something to do with the number of visible faces attached to the vertex (a lone corner has 3 faces compared to a solid wall's 4) Am I wrong?
     
    Last edited: Feb 28, 2014
  46. RSH1

    RSH1

    Joined:
    Jul 9, 2012
    Posts:
    250
    The easiest way is to check if the vertex is touching air, and if so displace.
     
  47. Deleted User

    Deleted User

    Guest

    You are sort-of right, you need to update the nearby blocks to adjust for displacement.
     
  48. asperw

    asperw

    Joined:
    Oct 19, 2012
    Posts:
    3
    I was thinking something along those lines. Maybe if the vertex is rendered (then we could assume it is touching air). But wouldn't this problem occur?
    $displacetrouble.png

    So maybe check in a 3x3 space around the voxel in question, but I have no idea how to implement the checking space and make the generator decide which vertices have displacement on them.

    I am using the source provided by this sir (thanks) I have since changed how the character works. I found where the vertex location data is stored in a script CubeBuilder.cs.

    https://www.youtube.com/watch?v=cgWM75QTr2o
     
  49. Enka2012

    Enka2012

    Joined:
    May 2, 2013
    Posts:
    8
    Hy guys, following some tutorials I found a way to generate a chunk creating all of its faces.
    What I'd like to do is just to optimize the mesh collider, searching for squares and rectangles, but I have no idea of how I could do.
    Any suggestions?

    Here is my code:
     
  50. RSH1

    RSH1

    Joined:
    Jul 9, 2012
    Posts:
    250
    I would advise against using a mesh collider and write your own simple AABB collision detection system.

    Yes, you need to do this, too. It takes a lot of IF statements to check if neighbouring vertices are displaced. There is another way you can do it, on the shader level (just look at how a water shader 'ripples' the vertices) but that will apply the displacement to every vertex.
     
    Last edited: Mar 15, 2014
Thread Status:
Not open for further replies.