Search Unity

Need Help Learning to make a Voxel Engine

Discussion in 'Scripting' started by JasonBricco, Sep 20, 2014.

  1. JasonBricco

    JasonBricco

    Joined:
    Jul 15, 2013
    Posts:
    956
    First of all, I apologize if this is the wrong section to post this topic in. What I'm looking for is not help in the sense of getting programmers to help out, but rather in the sense of being introduced to some resources that could help me.

    Here's my situation. I'm [fairly] new at programming and at using Unity. I've programmed for a small amount of time prior to getting into Unity, but never made anything serious. And then I found Unity, and was very interested in starting a career out of making games. In that regard, I'm now very serious about this work.

    I started off pretty simple, making a simple space shooter game and a point and click game. Unfortunately, I never completed either of them, though I made some considerable progress.

    The truth is, I really didn't want to make games like that and I instead wanted to make a voxel game. Being one who loved games like Minecraft and Eden - World Builder, I wanted to make my own unique twist on a voxel engine. And I have quite the plan for that!

    So I followed a tutorial on the forums to get me started with voxel engines and I have made progress. I have chunk loading (sort of infinite, if you don't count floating point precision errors), breaking terrain, adding to it, a movable player with controls, different block types, a rather bad terrain generator but it can do some things...

    But I realize that there are a lot of areas in this realm that I simply am clueless about. I have no idea how to make a lighting system. I have no idea how to use shaders to modify individual blocks. I have no idea how to do disk compression. I have no idea how to make water, how to make animated blocks (like for water/lava, etc), I don't really know how to make my terrain generator much better. I don't know how to make a decent physics system without using Unity's mesh colliders. I don't know how to do pathfinding in a voxel engine, I don't know how to make a pathfinding system from the asset store work on one. Nor do I know how to do voxel raycasting, how to optimize the noise libraries, and how to use greedy mesh algorithms to make meshes more efficient.

    In fact, my expertise in the 3D graphics programming field is quite nonexistent.

    As you can see, I've got a lot of work to do. These are things I maybe shouldn't be trying to get into given my current experience with programming. And yet, I feel like I'm capable of it. I've made considerable progress already. I just have a lot of learning to do...

    And, with all of that out of the way, that's where I'm a bit stuck. I looked at Safari Books Online and there are so many books I don't know where to begin. And in general, that's my issue.

    So my question is: what kinds of books or courses or (you name it) would you recommend for me to learn how to do some of these things, or for simply making a good, robust voxel engine?

    Any pointers would be greatly appreciated.

    PS: I have read much of the 'after playing Minecraft...' topic, but found it to be more about people showing off their work than about giving helpful information. And I didn't find a whole lot of helpful information, mostly things that went over my head due to improper explanation.
     
    Last edited: Sep 21, 2014
  2. Vanamerax

    Vanamerax

    Joined:
    Jan 12, 2012
    Posts:
    938
    The things that you mention are very complicated topics indeed, like water simulation. Therefore, very few people have accomplished to get this working at an interactive speed.

    As far as physics is concerned, The only methods used within Unity that I know of, are either:
    - custom AABB collisions, works only good if you are using cubes to represent your voxels (aka minecraft)
    - Mesh colliders, easiest way, 'works' for every scenario, but may have performance penalties (I am using them myself but haven't really suffered from performance so far)
    - Using box colliders around the player at voxel positions. Whenever the player moves, you shift the box colliders with it. This will need a radius of colliders for every dynamic object in the scene, which, if you have many, gets messy real quick.

    Water simulation is a complicated topic, you should take a look at cellular automata, specifically this
    Note that you can make this how complicated you want, but that every little change might have significant performance penalties. Minecraft for example, doesn't use a full simulation of this kind probably for that reason.

    I don't have any experience in pathfinding myself, but A* seems to be quite a popular choice. It also appears to play well with grid-based solutions, so would fit perfect with a voxel engine.

    As for disk compression, a good solution for voxel engines is 'Run length encoding' (RLE). Basicly, assuming a = air, b = dirt, c = stone, instead of writing a series of voxels to the disk as aaaabbdddd, you write 4a2b4d. Only in this simple example, you are writing 6 bytes to the disk instead of 10. In voxel engines you can greatly reduce the memory/disk usage with this method. There are also 2d and 3d variants (such as octrees), but personally I think they are more complicated, performance heavy and don't add that much benefit.

    Hope this will help you out a bit :)
     
    Last edited: Sep 20, 2014
    JasonBricco likes this.
  3. JasonBricco

    JasonBricco

    Joined:
    Jul 15, 2013
    Posts:
    956
    Thanks for the advice!

    I have this issue with pathfinding that I feel like will come up. I have chunks loaded around the player, but what do I do about chunks outside of the view range? Those chunks aren't loaded and essentially don't exist until the player gets close enough, with my system. I had the A* pathfinding project plugin for Unity, and it requires that you make grids on terrain. That's a challenge for me, as it can't make grids on chunks that don't exist. Furthermore, I tried to optimize mesh colliders by only generating those colliders on the chunks directly surrounding the player's chunk (and the player's chunk as well). Those change as the player moves. So I feel like I'd have to be constantly updating grids each time I update positions of mesh colliders, and that could be slow.

    Also, it would probably have to apply to enemy characters as well (who would likely need a similar set of colliders as the player, hurting performance even more). And then more grid updates.

    I really don't know how I'll be handling this one!

    As a note, I'm using a cube-based voxel world rather than a marching cubes, smoothed out type situation. This is intentional - I feel I won't be able to accomplish everything I want to accomplish in this game using the smoothed terrain, and the point of my game isn't necessarily to be realistic.
     
  4. Vanamerax

    Vanamerax

    Joined:
    Jan 12, 2012
    Posts:
    938
    Well, in my experience updating the mesh colliders takes more CPU power than having them enabled. In my case, updating mesh colliders for a marching cubes chunk with 32^3 in dimension takes about 6ms. That's half a frame time gone for a single chunk already on the mainthread. Therefore, I just keep all the mesh colliders within the view range (loaded chunks) enabled and update them only when the chunk updates.

    Apart from the updates, I haven't experienced any performance problems yet. But then again, my game is far from finished and not really populated with other objects yet. If you run into that problem though, you can make a seperate layer for your terrain, and disable as many collisions with other layers in the collision matrix (project settings). If that doesnt help, maybe try the .enabled property on the mesh collider. I don't know if this takes the same time as to assign a new mesh to the collider?
     
  5. JasonBricco

    JasonBricco

    Joined:
    Jul 15, 2013
    Posts:
    956
    My system creates them once if they're not already created, but then as long as they stay in the view range, disables them (if they're not within 1 chunk range of the player), and enables when the player goes close enough. This seems to be a lot faster, since the collider mesh data is built already and is simply being ignored by the physics engine. That's what I gather, anyway...

    Performance isn't really an issue I'm having right now but I still have fluid to add, lighting, pathfinding... you know, the stuff I mentioned up there. I feel like I'll be running into issues at some point. That is, if I ever figure this stuff out!
     
  6. Vanamerax

    Vanamerax

    Joined:
    Jan 12, 2012
    Posts:
    938
    For fluids I don't see collision detection that much as a problem. You probably want to let the player be able to walk into the fluid anyways. The fluid must therefore be handled seperately for the collision. If you want to decrease the player's speed inside the fluid or add a force to the player in the flow direction, you can always add a less-accurate trigger area (maybe even use primitive colliders as the trigger)
     
    JasonBricco likes this.