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

After playing minecraft...

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

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

    Titan8190

    Joined:
    Feb 16, 2013
    Posts:
    29
    About bleeding, here is the most complete answer to this problem in this thread:
    I don't understand the shader part, I am not really novice about them, but how do you choose the mipmap to use in your shader, ("ddx" and "ddy" ?).
    I'm used to sample with tex2D(texture, coordinate), I thought until now that it was the Unity core engine that was sending a lower resolution texture to the GPU.
    If i can choose to clamp mipmap level -to 5 in my case-, then all the problems are gone (so why repeating there is no solution btw ?)


    EDIT:
    Another question which i can't find the answer is trees, my approach would be to run a pseudo random function on every top block after the rest of the terrain generation, and if I have a go for a tree, I replace the empty above blocks by the actual tree (generated by more pseudo random and a sort of L system I guess), but if my tree overlap a non generated chunk it will end up cut in half, since at the other chunk generation time, it would have no idea it's suppose to continue a tree.
    I could try to save an exception to remember this but I'm afraid the code would be quickly messy (if it's not generated until the next session I would even have to serialize that on the HD...). and if I want to build a bigger structure than a tree, that could expend on more than just the nearby chunk it would be even more messy.

    A passage of goldbug's blog made me think that maybe, it is possible to build structures the way we build terrain:
    but if it's possible to guess a forest directly from a 3D noise, I have no clue on how to achieve this sorcery.
     
    Last edited: Jul 7, 2013
  2. Captain Morgan

    Captain Morgan

    Joined:
    May 12, 2013
    Posts:
    144
    * Make the textures bigger, and only use a portion of them. The problem will still be there, but will happen farther away.

    Already) I use 1024х1024, 2048x2048 textures and stretch them at four block
     
  3. Captain Morgan

    Captain Morgan

    Joined:
    May 12, 2013
    Posts:
    144
    will end up cut in half, since at the other chunk generation time, it would have no idea it's suppose to continue a tree.

    i just check that point is valid for trees, and return false if three at the border of chunk. But before that you need to calculate leaves radius. And after just check, that point_x + radius <= Chunk_in_block_width, and point_z also <= Chunk_in_block_width

    For example:

    Chunk size: 32x32 blocks
    2D point (17, 29)
    Radius 4

    Checking

    x + radius < width AND y + radius < width

    17 + 4 < 32 - TRUE
    29 + 4 < 32 - FALSE

    NOT Valide point
     
  4. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    766
    there are several versions of tex2D, some of them accept the dx and dy parameters:
    http://http.developer.nvidia.com/Cg/tex2D.html
    but you require shader model 3.0 for that.
    make sure that dx and dy are clamped to -0.20 to 0.20 or some values like that, depending on how your uvs are done.




    My solution is imperfect, because having overhangs and caves really messes things up. But if you dont' have overhangs and caves, then you can do bit of a hybrid, where you calculate per chunk the locations of trees ahead of time, and then in your terrain generation check if a voxel is within the radius of one of those locations.
     
  5. Titan8190

    Titan8190

    Joined:
    Feb 16, 2013
    Posts:
    29
    thanks, I don't understand this derivative stuff yet but I'll look into it. The shader model is not a problem since I'm working on a DX11 GPU accelerated voxel engine, I already have set aside everything before the model 5.

    and thanks for the trees, i'm a bit disappointed there is no magic solution :(, I'll try to play around this idea, but when I said trees I was also thinking about buildings, town, road, etc (everything that can't be pure noise), so I need to have a strong implementation, but I'm sure I'll do awesome as usual^^.
    I should not have much overhangs and caves if any, I want the player to go upward with a good LOD to see extremely far away
    by the way I loved the idea of a tiny deformation to make the cubes form a sphere that someone presented somewhere on this thread, i'm also going to look into it (I need to figure out how it could work for poles :/, it's sad he didn't came back with updates (bad sign).
     
  6. Captain Morgan

    Captain Morgan

    Joined:
    May 12, 2013
    Posts:
    144
    I have some problem with combine meshes with different materials

    Code (csharp):
    1.         CombineInstance[] combine = new CombineInstance[Constants.MaterialCount];
    2.         for (int i = 0; i < Constants.MaterialCount; ++i)
    3.         {
    4.             combine[i].subMeshIndex = i;
    5.             combine[i].mesh = chunk.Geometry[i].ConvertToUnityMesh();
    6.         }
    And
    Code (csharp):
    1.  
    2. gameobject.GetComponent<MeshRenderer>().materials = Materials;
    Materials count == BlockTypeCount

    But i have an error: Submesh index 6 is invalid for mesh .
    Submesh index 7 is invalid for mesh .
    Submesh index 8 is invalid for mesh .
    Submesh index 9 is invalid for mesh .
    Submesh index 10 is invalid for mesh .
    Submesh index 11 is invalid for mesh .
     
  7. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    766
    Here is one way to do it. For a given voxel (x,y,z) (y is up and down), calculate the height of your terrain:

    Code (csharp):
    1. h = height (x,z)
    then calculate a 2d noise with derivative:

    Code (csharp):
    1. (v, dx, dz) = noise(x,z)
    then return leafs if

    Code (csharp):
    1. (dx * dx + dz * dz  + (y - h - TREE_HEIGHT) * (y - h - TREE_HEIGHT) * k ) <  0.1f  
    adjust the tree_height to make the tree taller or smaller, adjust the threshold to make the tree fatter or thinner.

    This will place trees randomly, but evenly spaced. Make sure the terrain is fairly flat for the height to work ok, otherwise the leafs will be tilted like the terrain. You can compensate for this if you also calculate the derivative in the height function.
     
  8. Captain Morgan

    Captain Morgan

    Joined:
    May 12, 2013
    Posts:
    144
    "My World" There is 2 version: 16x16 chunks and 32x32 chunks. Game still WIP, present a lot of bugs
    I need make some improvements to my game:
    1) Dont store chunk game object (transform) in Chunk class
    2) Use Pool for chunk gameobject
    3) Use optimized mesh collider
    4) Implement vertical chunks
    5) Save only changed chunks

    Enjoy!
     

    Attached Files:

  9. Titan8190

    Titan8190

    Joined:
    Feb 16, 2013
    Posts:
    29
    You din't deeply detailed the derivative of the noise,maybe because it's used often, I suppose it's dx = noise(x,z) - noise(x - 1,z) I'm not sure what the output would look like. I think I need to make a little program to display noises in 2D and 3D to iterate and visualize faster.

    so you are telling me that dx² +dz² + (y - H - treeHeight)² x K < threshold give a tree
    can you explain where this formula come from, and also what are the H and K parameters
     
  10. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    766
    With simplex noise you can get the derivative of any point analytically, here is an implementation:
    http://staffwww.itn.liu.se/~stegu/aqsis/aqsis-newnoise/sdnoise1234.c

    a dx close to 0 means that at that point if you walk on the x axis, the value would stay roughly the same. A dx of 1 means that if you walk to the right the value would become higher. So the dx and dy give you the inclination of the noise at any given point.

    if we do dx² < threshold it would look like a randomized grid. Kind of like the edges of voronoi, but curved and smooth. if we do dx² +dz² < threshold, it would look like just the corners in a voronoi diagram. So it is a way to do placement that I came up with. You could also simply evaluate 2 noise functions and do the same. If this is all you did, in 3d it would look like an infinite circular column of leafs. the last term is to make it into a ball, so it limits the height both up and down and you end up with a sphere placed randomly.
     
  11. GibTreaty

    GibTreaty

    Joined:
    Aug 25, 2010
    Posts:
    792
    InfiChunk Alpha Standalone

    $InfiChunk Alpha.png

    - Faster chunk generation
    - Glass/Transparent block support

    I think the next thing I want to try to add would be entities/instances. First I'll have to determine how to store them. Maybe a look-up dictionary?

    I don't know if and when I'll try to add block deformation back in. The code will need to be redone a lot in order to support it.
     
    Last edited: Jul 10, 2013
  12. Captain Morgan

    Captain Morgan

    Joined:
    May 12, 2013
    Posts:
    144
    You mean something like vertex displacement or marching cubes?
     
  13. GibTreaty

    GibTreaty

    Joined:
    Aug 25, 2010
    Posts:
    792
    Well in my previous version of InfiChunk I was using the standard block mesh generation that's not optimized at all. That allowed me to check, for each vertex, whether it was able to be moved/deformed inward. So to answer you, Vertex Displacement. I haven't looked into doing marching cubes yet but I have heard of it.
     
  14. Captain Morgan

    Captain Morgan

    Joined:
    May 12, 2013
    Posts:
    144
    I tried to implement vertex displacement version, posted by Alezzz, but nothing happened :( :( :(
     
  15. Titan8190

    Titan8190

    Joined:
    Feb 16, 2013
    Posts:
    29
    I've implemented a prototype of marching cubes in few hours, the things is: it's not fun. You can't really build anything pretty, here is a house I built for example:

    let alone lightning calculation, fluid simulation, mesh optimization, custom physics, that become incredibly complicated.
    The main problem is that a cell geometry depend on 4 voxels, so the player can never really edit the way he want.

    The solution can be, like starforge, to have marching cube for terrain and regular cube for building but it kind of duplicate the engine and it's not consistent in my opinion.
    The solution I chose is to have deformation like alexz and different shape like blockscape

    ---------------------------------------
    I wanted to ask: how many bytes do you guys use to store a voxel ? I was thinking about:

    1 bytes shape type (box / triangle / cylinders / half box / ...)
    1 bytes texture type
    1 bytes fluid type (air/water/lava/acid/poison cloud / ... I could have 16 fluid type and 2 by cell
    1 bytes fluid separation value (256 value, bottom fluid is x, top fluid is 255 - x)
    4 bytes lightening (r/g/b/sun)

    The padding is nice but 64 bits by voxels sound huge to me.
    I thing I could drop 2 byte on lightning for 16 value intensity precision, and somehow merge shape and the texture in on side and merge the fluid type and the fluid separation in another, making the fluid level also a 16 value intensity precision and assuming that the second fluid is always air. It sound like an huge drawback but i divide by 2 the storage needed.

    Did I forgot something ? what would you do ?
     
    Last edited: Jul 11, 2013
  16. Vanamerax

    Vanamerax

    Joined:
    Jan 12, 2012
    Posts:
    937
    why not define the shape and texture type by the block type? just store a dictionary or whatever with the blocktypes as a Key value, and store whatever you need to know about the voxel and is dependend on it's type. Textures, shape, hardness, opaque/transparant etc. Very memory-friendly and pretty much the same performance as far as I know.

    Also, couldn't you just merge the fluid type and block type? that would save you a byte and you can use the other byte (fluid seperation) for example for the strength of the block that is in a structure (collapsing mines yeah!)

    If you, for lighting, just store the lighting index (say you have 16 levels of lighting like in minecraft, you only need 4 bytes for that. So you can cut your lighting storage bytes down to 2 by merging them). With the indices, you can just calculate the correct lighting value when building your mesh (make a lookup table or something)

    Doing all of this will result in the following:
    1 byte - block type (or fluid)
    1 byte - strength/fluid seperation
    2 byte lighting

    which comes down to a nice 4 bytes, which is again memory-friendly because it is a power of 2 (somehow that gives you better performance people told me) and is basicly just 1 int



    Now some questions from me to you, how did you implement the marching cubes? I've seen a lot of code samples about it but I've still got no clue on how to actually implement it with a voxel grid?
     
  17. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    766
    Looks pretty to me, but yes, you give up a lot.

    Your voxels are huge. MIne are:

    1 byte block type (air, water, dirt, gold, sand, chest, etc...)
    1 byte data (meaning depends on the type, for spawners it is monster id, for sand and glass it is color, etc)
    2 bytes light (r/g/b/sun, 4 bits each)

    so it is 4 bytes per voxel for me.
     
  18. Titan8190

    Titan8190

    Joined:
    Feb 16, 2013
    Posts:
    29
    Because i'm thinking about having a lot of shape types in one side for example i would have 12 "straight triangles" and 12 "inner corner triangle" and 12 "outer corner triangle" and also some combination of 8 subdivided cube...
    and in an other side the block type since i could have grass triangles on hills, sand triangles on dunes and rock triangles on caves etc.

    and I also wanted to keep fluid values on all voxels because some shape could hold water, for example 4 straight triangle + 4 corner in circle could make a pool (it's easy the fluid sim would just need to check in a lookup table with the shape ID to see if the liquid can spread along each direction for both cell), and it could also allow to not disappear a fluid when someone put and remove a block.

    but I guess it's too much I'll make it fit in 4 bytes, with some kicks, like a luggage, I'm sure it can enter
     
  19. Captain Morgan

    Captain Morgan

    Joined:
    May 12, 2013
    Posts:
    144
    I tried to implement vertex displacement again, but without results. After i tried to add a const value to ALL vertices

    Code (csharp):
    1.             for (int i = 0; i < geometry._vertices.Count; ++i)
    2.             {
    3.                 geometry._vertices[i] += new Vector3(-0.5f, 1.5f, -3.0f);
    4.             }
    And again nothing
     
  20. Titan8190

    Titan8190

    Joined:
    Feb 16, 2013
    Posts:
    29
    sorry I missed the question,
    here is my code, it's just a fast test: http://pastebin.com/Qrv2nTYq
    I commented it, I just replaced my "appendCube" function called for each voxel by this "appendMarchingCube" function.
    It's inspired from voxelForm and some other implementation, here is also the look up tables that you can find everywhere: http://pastebin.com/QW9FeFE0

    you can test it on my blog: http://florian-noirbent.com/blog/en/english-voxel-terrain-engine/, it's really slow but it's not the point.

    @Morgan
    what do you expect us to tell you... just debug your code.
     
    Last edited: Jul 10, 2013
  21. Vanamerax

    Vanamerax

    Joined:
    Jan 12, 2012
    Posts:
    937
    Thanks man, this makes a lot clear to me. I'm trying to get it to work with my system, but I still have a few questions though. I keep getting meshes with 0 number of vertices, triangles and everything

    - I suppose the uv, tangent, atlascoord, vertex and triangle are references to the mesh's uv, tangent, color, vertex and triangle arrays (or in this case, lists which get converted to arrays later)?

    - As far as I understand, I need to do some bound checking in the getVoxelData() method, the coordinates are local to the chunk right?

    - When assigning the VoxelData, how does the algorithm respond to the "state" variable? what is 0 and what is 255? Also, are these variables stored in the voxels in your system, as representing it's "fullness" or is it somehow calculated?

    - Where does "tmpVertex" come from? it is assigned after the cubeIndex but never declared in your code snippet. Is it just an empty array of Vector3's?


    I'm assuming that the reason why I get zero vertex attributes assigned is because the
    Code (csharp):
    1.  
    2. if (edgeTable[cubeIndex] == 0) return;
    3.  
    ends the method. Why does it do this and how can I fix it?

    Thanks anyway, I'm again asking too much :p
     
  22. Titan8190

    Titan8190

    Joined:
    Feb 16, 2013
    Posts:
    29
    Code (csharp):
    1. if (edgeTable[cubeIndex] == 0) return;
    this is an early out if there is no triangle to build in this cube (mean the 4 voxel composing the cube are all in the same side of the isolevel)

    tmpVertex is a Vector3[12] declared as static member and only used there, if you thread declare it as member or as local variable.

    the state tell you the density of your voxel, if the rest of your engine is only meant for cube, you likely don't have this value, put 255 if it's a block and 0 if it's air in getData, but you'll get a terrain looking like my saturated version (a fast google example http://i.stack.imgur.com/4pI9u.jpg).

    the x y z parameters of my function are in the chunk coordinate, to make it work properly you need the 3 bounding check (+X, +Y, +Z, no -), and if x == chunkSize, find in your data structure of Chunks the correct Chunk at this position and find the correct value inside it, or if you have a circular buffer like alexz don't touch anything.

    the output lists are just the same as the one you probably use for your cube version, it has been dashed off, the tangent is not exact, UV should be replaced by a triplanar shader and I even used calculateNormal for the normal, I also store my atlasCoordinate in the color channel of the vertex, the real posiiton is set in the vertex shader, il allow to wrap with an atlas (for the face merging I never did ><)
     
    Last edited: Jul 11, 2013
  23. DaneC020

    DaneC020

    Joined:
    Mar 19, 2010
    Posts:
    191
    I am not sure about the code since I haven't looked at it but that section is correct. I believe (from memory) the cubeIndex is determined by the 8 local values around a given point, then it looks up the edges from the edge table. So if you are == 0, you want an early out since there is nothing to compute. If you are interested in a complete download of marching cubes, Alexzzz was kind enough to post a meatball example that used marching cubes a few pages back. It even has a scene for generating just the spherical mesh data.

    -Dane
     
  24. Vanamerax

    Vanamerax

    Joined:
    Jan 12, 2012
    Posts:
    937
    Okay thanks for explaining all of this! The thing I was missing was the 0 if air and 255 if solid (I was just passing in a random const value for all the voxels, so there was never a mesh to generate since everything was either "inside" or "outside" I guess. I've already added a method to my chunks to get it's neighbour in a simple way. Didn't know you don't need the negative bounds checking, so I will remove that.


    Thanks, I've indeed looked into the metaball example, but since the structure of it's data storage (grid) wasn't clear to me, It didn't really help me out (if I recall correctly, it builds a mesh from only a few points or nodes with each a big value, instead of a whole grid of "small" vallues, or I've misinterpreted that)


    I've got it working now.. well.. kind of. It's still giving me some weird results here and there, but the overall shape is clearly visible. There are some ugly stretched surfaces scattered around the map, chunkborders are clearly visible and some random one-way-walls are sometimes in the centreline of chunks. See some screenshots below. Any idea what I could be doing wrong?

    $marching cubes 1.png $marching cubes 2.png $marching cubes 3.png
     
  25. Captain Morgan

    Captain Morgan

    Joined:
    May 12, 2013
    Posts:
    144
    Does any body tries to use MeshBaker to combine meshes with different material into one mesh?
     
  26. Titan8190

    Titan8190

    Joined:
    Feb 16, 2013
    Posts:
    29
    x y z stored in the voxelData struct has to be the input paramater, maybe you set it in the other chunk coordinate
     
  27. mimminito

    mimminito

    Joined:
    Feb 10, 2010
    Posts:
    780
    Ive been reading through this thread quite a lot recently, amazing what you are all coming up with!

    I wanted to know if anyone had seen this library on GitHub. I am not the developer/owner, just found this the other day.
    https://github.com/federicodangelo/CubeWorld

    Looks pretty good, and works quite well. the only feature it does not have is infinite terrain generation, its limited to a specific size right now.
    Also, a really neat feature is the ability to configure it all via XML:

    Just thought I would share this incase its of any interest to others. Going to try and dedicate some time to read through more of this thread soon :)
     
  28. jordantotty

    jordantotty

    Joined:
    Dec 15, 2011
    Posts:
    77
    Has anyone had any luck getting the world to generate on mobile, I've been trying to fix this for months so I can work on my project.
    Whenever i run the project on my iPhone it doesn't load the world, and the player just falls forever.

    Any ideas?
     
  29. DavidWilliams

    DavidWilliams

    Joined:
    Apr 28, 2013
    Posts:
    522
    Here's a new video of our Cubiquity plugin for Unity3D. The industrial factory complex map is taken from the game 'Build Shoot' and is 512x512x64 voxels. I think there's a really cool amount of destruction taking place here :)

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

    As a reminder:
    Do let us know what you think or if you have any questions :)
     
  30. mimminito

    mimminito

    Joined:
    Feb 10, 2010
    Posts:
    780
    Any idea as to when you will release this plugin? And for what price?
     
  31. DavidWilliams

    DavidWilliams

    Joined:
    Apr 28, 2013
    Posts:
    522
    We're currently expecting to offer a range of prices starting from free and going up to hundreds of USD. The differentiating factor will be the maximum size of the volume, and this will let you test out the system on small scenarios (or probably even release complete games for free) before commiting to buying a license.

    It will be a while (months?) before it is on the asset store, but we are strongly considering making the integration layer open source (though it would depend on our closed source .dll). This would allow people to test early versions and give feedback, and could hapen in the next couple of months.

    Edit: Oh, and there is already a very early test build in this blog post: http://www.volumesoffun.com/cubiquity-unity3d-physics/
     
  32. Vanamerax

    Vanamerax

    Joined:
    Jan 12, 2012
    Posts:
    937
    Okay Ive fixed the issues with marching cubes I was having. Now I have to change my terrain generation algorithms. Previously, it was generating a heightmap based on 2D simplex noise, filled everything with stone that was underneath the heightmap and made the top layer grass. This works fine for cubic mesh generation, but marching cubes want a density per voxel if you want to get smooth meshes out of it.

    Now I have been experimenting with 3D noise and got decent result when playing with the isolevel value, but I can't find out how to combine the 3D density noise with a heightmap. I'd like to achieve a mesh smoothness similar to this:
    http://www.youtube.com/watch?v=7xTUvElNTj4
    or this
    http://www.youtube.com/watch?v=-hJkrr5Slv8
    just to give you some examples

    How do I get that to work? When I use the generation algorithm that I used for the cubic world, marching cubes just gives me a mesh that looks like Titan's example (reminder:http://i.stack.imgur.com/4pI9u.jpg)



    EDIT: nervermind, got it working already :D
    (with the help of this article: http://http.developer.nvidia.com/GPUGems3/gpugems3_ch01.html)

    $unity marching cubes terrain.png
     
    Last edited: Jul 16, 2013
  33. DaneC020

    DaneC020

    Joined:
    Mar 19, 2010
    Posts:
    191
    Looking really awesome! Do you mind me asking how you got the UV's looking so good? Mine has some triangles that have really stretched or squashed textures. I haven't had too much time to play around with it to see if I could fix it but any tips or advice would definitely speed up the process. :)

    EDIT:
    Hmm.. Just took a look at the source Titan posted, is that how you processed the UV's? Or did you come up with another method? I was calculating them based off some other information, this method looks a lot easier.

    -Dane
     
    Last edited: Jul 16, 2013
  34. mimminito

    mimminito

    Joined:
    Feb 10, 2010
    Posts:
    780
    Thanks for the update :)

    Im interested in a system such as yours, so it would be good to test something when possible! And when pricing structures are thought about, id love to know. I currently have not found a system worth purchasing this side of €2000!
     
  35. Vanamerax

    Vanamerax

    Joined:
    Jan 12, 2012
    Posts:
    937
    Thanks! :D I have switched over from using UV's to a triplanar texture (which I grabbed the source from some place I happened to find: http://www.blog.radiator.debacle.us/2013/02/a-smoother-triplanar-shader-for-unity.html, thanks to the author!)
    I had the same problem before using the triplanar shading, but those are all gone now. With this shader you can even define the tiling size and it blends smoothly between top,side,bottom textures.

    Now I only need to find a way to get the right blocktypes into place (at the moment, I just create a density value for each voxel and assign grass to filled voxels, and air to empty) But I already have something in mind to do so.

    After that, I have to seperate all the different "blocktype triangles" in different submeshes, so each submesh can use it's own shader and textures. I thought someone has achieved this a while back, so if this person (have to look up who it was again) could give some explanation on how this exactly works, then that would be awesome :D

    EDIT: after looking back, I think it was GibTreaty. Could you explain your system a bit? Are you using a cache List of triangles etc for every block type while assigning triangles or are you assigning them directly to the submesh?
     
    Last edited: Jul 16, 2013
  36. DavidWilliams

    DavidWilliams

    Joined:
    Apr 28, 2013
    Posts:
    522
    A few years ago I wrote a chapter for the book Game Engine Gems in which I described voxel-based terrain and how to handle multiple materials.

    $Thermite2.jpg

    As luck would have it, the chapter was chosen to go on Google Books so you can read it for free here:
    In Section 3.5 I talk a bit about splitting the mesh into multiple sections and how to handle the blending between the different materials. It's independent of Unity but some of the ideas should still apply.

    As I said, it's a few years old and the approach has some limitations, but maybe you find it interesting. I'm working on an improved approach for when Cubiquity supports smooth terrain in the future.
     
    Last edited: Jul 17, 2013
  37. Vanamerax

    Vanamerax

    Joined:
    Jan 12, 2012
    Posts:
    937
    @DavidWilliams

    Well thanks for the tip! Unfortunately I will be on holidays for the next two weeks (presumably without internet connection) so it will have to wait. Is there a way to download/buy a digital copy of the book? I don't live in the U.S. so I don't think I can buy it from there
     
  38. DavidWilliams

    DavidWilliams

    Joined:
    Apr 28, 2013
    Posts:
    522
  39. Vanamerax

    Vanamerax

    Joined:
    Jan 12, 2012
    Posts:
    937
    Yeah i know, but i meant so that i can view it offline, as i probably wont have an internet connection soon
     
  40. DavidWilliams

    DavidWilliams

    Joined:
    Apr 28, 2013
    Posts:
    522
    Right, I understand! I've sent you a PM with a link to the PDF file on my Google Drive. You can then download through the Google Drive menu.
     
  41. Captain Morgan

    Captain Morgan

    Joined:
    May 12, 2013
    Posts:
    144
    Hello guys. How many draw calls do you have?
    I have 4.4k drawcalls for 1089 meshes, saved by batching: 810
     
  42. Titan8190

    Titan8190

    Joined:
    Feb 16, 2013
    Posts:
    29
    I'm around 150 draw calls for a 4 chunk view range (so 9 x 9 x 9 = 729 meshes maximum) and potentially 2 submesh by chunk now that I have transparency,
    note that half my chunk are actually empty since they are air, I don't have any occlusion culling (I don't think it's possible).
    4.4k sound insanely huge: that mean you have more than 4 draw call peer chunk and that you are actually seeing every single one.

    ----------------------------------

    I'm thinking about a data structure for chunks, alexZ solution is nice, but I'm afraid it's going to make LOD impossible (a huge flat circular array shared by all the chunks for those not following),
    I thought about an octree but since the map is infinite it would be a mess to keep it balanced, and would almost ask to be rebuilt every time we create a chunk.
    this topic hasn't been discussed a lot yet on this thread (or I missed it).

    I found a solution that sound acceptable: have a list of list of list of chunks (Chunks[x][y][z]), and keep them sorted by adding new chunk to the end if it's on positive axis and to the beginning if negative, then to lookup for a chunk with it's coordinate, just start in the middle, check if more or less, then again split in two, etc. So the complexity would be O(n) = 3 x log(n) for lookup and between O(n) = 1 to O(n) = n x 2log(n), depending of the case, for a new chunk, where n is the number of chunk on an axis. each chunk would also keep a reference to all the neighboring chunks so the lookup would basically be done only at instanciation. same for any object, it would save its chunk position at instanciation and then update it through the graph.

    what do you think of that and how are you doing it ?
     
    Last edited: Jul 18, 2013
  43. Captain Morgan

    Captain Morgan

    Joined:
    May 12, 2013
    Posts:
    144
    33*33 chunks, 6 block type, 1 mesh\per block type. Each chunk has 16*16*128 blocks

    I use own chunk collector

    Code (csharp):
    1.     public class ChunkCollector : SortedList<long, Chunk>
    2.     {
    3.         private Chunk _lastAccessedChunk = null;
    4.  
    5.         public Chunk this[IntVect vect]
    6.         {
    7.             get { return this[vect.X, vect.Y]; }
    8.             set { this[vect.X, vect.Y] = value; }
    9.         }
    10.  
    11.         public Chunk this[int x, int y]
    12.         {
    13.             get
    14.             {
    15.                 if (_lastAccessedChunk != null)
    16.                 {
    17.                     if (_lastAccessedChunk.X == x  _lastAccessedChunk.Y == y)
    18.                         return _lastAccessedChunk;
    19.                 }
    20.                 Chunk value;
    21.                 TryGetValue((((long)x) << 32) + y, out value);
    22.                 _lastAccessedChunk = value;
    23.                 return value;
    24.             }
    25.             set
    26.             {
    27.                 long index = (((long)x) << 32) + y;
    28.                 if (value == null)
    29.                 {
    30.                     this[index].Dispose();
    31.                 }
    32.                 this[index] = value;
    33.             }
    34.         }
    35.  
    36.         internal void InternalCheck(int x, int y)
    37.         {
    38.             if (x < -0x200000 || x > 0x200000)
    39.                 throw new IndexOutOfRangeException("x");
    40.  
    41.             if (y < -0x200000 || y > 0x200000)
    42.                 throw new IndexOutOfRangeException("y");
    43.         }
    44.     }
    Version based on SortedList a bit faster than on a one dimension array, or even List
     
  44. Captain Morgan

    Captain Morgan

    Joined:
    May 12, 2013
    Posts:
    144
    i figured out, that my game with 6 block types (1 submesh \per block type) uses 470 mb of RAM. If I add a seventh type (eg wood) will be used by more than 120 MB of RAM (590mb). Even if the wood blocks will be only 100 pieces of 16 * 16 * 128. It's very strange.

    add:

    470mb for 33*33 chunks. Meshes without normales and tangents. With tangents and normals my game uses 660mb. The difference is huge.
     
    Last edited: Jul 17, 2013
  45. Captain Morgan

    Captain Morgan

    Joined:
    May 12, 2013
    Posts:
    144
    I have very strange stats from unity profiler. For example: my world - 33*33 chunks, each chunk represent by gameobject with mesh filter, mesh renderer and mesh collider. In the scene only player with camera and empty gameobject named world with custom scripts.
    Unity profiler told me, that i have 1089 gameobjects (chunks). Total object in scene 7.7k, Total object count: 8.5k. wtf ?
     
  46. GibTreaty

    GibTreaty

    Joined:
    Aug 25, 2010
    Posts:
    792
    Simply put, I'm using Dictionary<Material, List<int>>. Material stores the material and List<int> stores the indices. Afterwards I do a loop sort of like this..

    Code (csharp):
    1.  
    2. MeshCollider meshCollider = chunkObject.GetComponent<MeshCollider>();
    3.  
    4. mesh.subMeshCount = dictionary.Count;
    5.  
    6. int subMeshIndex = 0;
    7. foreach(KeyValuePair<Material, List<int>> a in dictionary){
    8.      mesh.SetIndices(a.Value.ToArray(), MeshTopology.Quads, subMeshIndex);
    9.  
    10.      if(meshCollider)
    11.           mesh.SetTriangles(mesh.GetTriangles(subMeshIndex), subMeshIndex);
    12.  
    13.      subMeshIndex++;
    14. }
    15.  
    16. chunkObject.renderer.sharedMaterials = dictionary.Keys.ToArray();
    17.  
     
    Last edited: Jul 18, 2013
  47. Vanamerax

    Vanamerax

    Joined:
    Jan 12, 2012
    Posts:
    937
     
  48. GibTreaty

    GibTreaty

    Joined:
    Aug 25, 2010
    Posts:
    792
    Pretty much yea. I slap them all into a list and assign them after. Here's what part of the mesh generation looks like in the thread...

    Code (csharp):
    1.  
    2.         List<Vector3> vertices = new List<Vector3>();
    3.         List<Vector3> normals = new List<Vector3>();
    4.         List<Vector2> uv = new List<Vector2>();
    5.         List<VoxelBounds> allBounds = new List<VoxelBounds>();
    6.         Dictionary<Material, List<int>> meshDictionary = new Dictionary<Material, List<int>>();
    7.  
    8.         int i = 0;
    9.         foreach(VoxelBounds voxelBounds in allBounds)
    10.             foreach(MeshBounds a in voxelBounds.bounds) {
    11.                 List<int> indices = null;
    12.                 bool foundMaterial = false;
    13.  
    14.                 foreach(KeyValuePair<Material, List<int>> materialList in meshDictionary)
    15.                     if(a.material.GetHashCode() == materialList.Key.GetHashCode()) {
    16.                         foundMaterial = true;
    17.                         indices = materialList.Value;
    18.                         break;
    19.                     }
    20.  
    21.                 if(!foundMaterial) {
    22.                     indices = new List<int>();
    23.                     meshDictionary.Add(a.material, indices);
    24.                 }
    25.  
    26.                 switch(voxelBounds.direction) {
    27.                     case 0: //Left
    28.                         vertices.Add(new Vector3(a.bounds.min.x, a.bounds.min.y, a.bounds.max.z));
    29.                         vertices.Add(new Vector3(a.bounds.min.x, a.bounds.max.y, a.bounds.max.z));
    30.                         vertices.Add(new Vector3(a.bounds.min.x, a.bounds.max.y, a.bounds.min.z));
    31.                         vertices.Add(a.bounds.min);
    32.  
    33.                         uv.Add(new Vector2(a.bounds.max.z, a.bounds.min.y));
    34.                         uv.Add(new Vector2(a.bounds.max.z, a.bounds.max.y));
    35.                         uv.Add(new Vector2(a.bounds.min.z, a.bounds.max.y));
    36.                         uv.Add(new Vector2(a.bounds.min.z, a.bounds.min.y));
    37.  
    38.                         indices.AddRange(new int[] { i, i + 1, i + 2, i + 3 });
    39.  
    40.                         normals.AddRange(new Vector3[]{
    41.                                 Vector3.left,
    42.                                 Vector3.left,
    43.                                 Vector3.left,
    44.                                 Vector3.left
    45.                             });
    46.  
    47.                         i += 4;
    48.  
    49.                         break;
    50. ....
    51.  
     
    Last edited: Jul 18, 2013
  49. Captain Morgan

    Captain Morgan

    Joined:
    May 12, 2013
    Posts:
    144
    My game vertex displacement.

    TODO:
    Chunk neighborhood events for lighting and meshing
    $vertex_displacement.JPG
     
  50. GibTreaty

    GibTreaty

    Joined:
    Aug 25, 2010
    Posts:
    792
    Pretty cool. Looks like alexzzzz's.

    I've got block rotation somewhat working in InfiChunk... then I had this realization that maybe the textures on the block, or the uvs, should rotate accordingly. So that'll add a ton more work for me...
     
Thread Status:
Not open for further replies.